diff options
36 files changed, 8417 insertions, 3552 deletions
@@ -1,4 +1,3 @@ -settings_local.py *.pyc *.swp nbproject @@ -0,0 +1,6 @@ +this is based on May23 beta2 version on google code + +changes: +* added internationalization (i18n) messages to templates and .py files +* added i18n support for javascript + English and Chinese messages +* site runs as English version diff --git a/cnprog.wsgi b/cnprog.wsgi new file mode 100644 index 00000000..a1bd8039 --- /dev/null +++ b/cnprog.wsgi @@ -0,0 +1,8 @@ +import os +import sys + +sys.path.append('/var/www/vhosts') +os.environ['DJANGO_SETTINGS_MODULE'] = 'cnprog.settings' + +import django.core.handlers.wsgi +application = django.core.handlers.wsgi.WSGIHandler() diff --git a/forum/views.py b/forum/views.py index 08a0e958..6ac172df 100644 --- a/forum/views.py +++ b/forum/views.py @@ -1,1958 +1,1958 @@ -# encoding:utf-8
-import os.path
-import time, datetime, calendar, random
-import logging
-from urllib import quote, unquote
-from django.conf import settings
-from django.core.files.storage import default_storage
-from django.shortcuts import render_to_response, get_object_or_404
-from django.contrib.auth.decorators import login_required
-from django.http import HttpResponseRedirect, HttpResponse,Http404
-from django.core.paginator import Paginator, EmptyPage, InvalidPage
-from django.template import RequestContext
-from django.utils.html import *
-from django.utils import simplejson
-from django.core import serializers
-from django.db import transaction
-from django.contrib.contenttypes.models import ContentType
-from django.utils.translation import ugettext as _
-
-from utils.html import sanitize_html
-from markdown2 import Markdown
-#from lxml.html.diff import htmldiff
-from forum.diff import textDiff as htmldiff
-from forum.forms import *
-from forum.models import *
-from forum.auth import *
-from forum.const import *
-from forum.user import *
-from forum import auth
-
-# used in index page
-INDEX_PAGE_SIZE = 20
-INDEX_AWARD_SIZE = 15
-INDEX_TAGS_SIZE = 100
-# used in tags list
-DEFAULT_PAGE_SIZE = 60
-# used in questions
-QUESTIONS_PAGE_SIZE = 10
-# used in users
-USERS_PAGE_SIZE = 35
-# used in answers
-ANSWERS_PAGE_SIZE = 10
-markdowner = Markdown(html4tags=True)
-question_type = ContentType.objects.get_for_model(Question)
-answer_type = ContentType.objects.get_for_model(Answer)
-comment_type = ContentType.objects.get_for_model(Comment)
-question_revision_type = ContentType.objects.get_for_model(QuestionRevision)
-answer_revision_type = ContentType.objects.get_for_model(AnswerRevision)
-repute_type =ContentType.objects.get_for_model(Repute)
-question_type_id = question_type.id
-answer_type_id = answer_type.id
-comment_type_id = comment_type.id
-question_revision_type_id = question_revision_type.id
-answer_revision_type_id = answer_revision_type.id
-repute_type_id = repute_type.id
-def _get_tags_cache_json():
- tags = Tag.objects.filter(deleted=False).all()
- tags_list = []
- for tag in tags:
- dic = {'n': tag.name, 'c': tag.used_count }
- tags_list.append(dic)
- tags = simplejson.dumps(tags_list)
- return tags
-
-def index(request):
- view_id = request.GET.get('sort', None)
- view_dic = {
- "latest":"-last_activity_at",
- "hottest":"-answer_count",
- "mostvoted":"-score",
- "trans": "-last_activity_at"
- }
- try:
- orderby = view_dic[view_id]
- except KeyError:
- view_id = "latest"
- orderby = "-last_activity_at"
- # group questions by author_id of 28,29
- if view_id == 'trans':
- questions = Question.objects.get_translation_questions(orderby, INDEX_PAGE_SIZE)
- else:
- questions = Question.objects.get_questions_by_pagesize(orderby, INDEX_PAGE_SIZE)
- # RISK - inner join queries
- questions = questions.select_related()
- tags = Tag.objects.get_valid_tags(INDEX_TAGS_SIZE)
-
- awards = Award.objects.get_recent_awards()
-
- return render_to_response('index.html', {
- "questions" : questions,
- "tab_id" : view_id,
- "tags" : tags,
- "awards" : awards[:INDEX_AWARD_SIZE],
- }, context_instance=RequestContext(request))
-
-def about(request):
- return render_to_response('about.html', context_instance=RequestContext(request))
-
-def faq(request):
- return render_to_response('faq.html', context_instance=RequestContext(request))
-
-def privacy(request):
- return render_to_response('privacy.html', context_instance=RequestContext(request))
-
-def unanswered(request):
- return questions(request, unanswered=True)
-
-def questions(request, tagname=None, unanswered=False):
- """
- List of Questions, Tagged questions, and Unanswered questions.
- """
- # template file
- # "questions.html" or "unanswered.html"
- template_file = "questions.html"
- # 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
- pagesize = request.session.get("pagesize")
- try:
- page = int(request.GET.get('page', '1'))
- except ValueError:
- page = 1
-
- view_id = request.GET.get('sort', None)
- view_dic = {"latest":"-added_at", "active":"-last_activity_at", "hottest":"-answer_count", "mostvoted":"-score" }
- try:
- orderby = view_dic[view_id]
- except KeyError:
- view_id = "latest"
- orderby = "-added_at"
-
- # check if request is from tagged questions
- if tagname is not None:
- 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.get_unanswered_questions(orderby)
- else:
- objects = Question.objects.get_questions(orderby)
-
- # RISK - inner join queries
- objects = objects.select_related(depth=1);
- objects_list = Paginator(objects, pagesize)
- questions = objects_list.page(page)
-
- # Get related tags from this page objects
- 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,
- "questions_count" : objects_list.count,
- "tags" : related_tags,
- "searchtag" : tagname,
- "is_unanswered" : unanswered,
- "context" : {
- 'is_paginated' : True,
- 'pages': objects_list.num_pages,
- 'page': page,
- 'has_previous': questions.has_previous(),
- 'has_next': questions.has_next(),
- 'previous': questions.previous_page_number(),
- 'next': questions.next_page_number(),
- 'base_url' : request.path + '?sort=%s&' % view_id,
- 'pagesize' : pagesize
- }}, context_instance=RequestContext(request))
-
-#TODO: allow anynomus user to ask question by providing email and username.
-@login_required
-def ask(request):
- if request.method == "POST":
- form = AskForm(request.POST)
- if form.is_valid():
- added_at = datetime.datetime.now()
- html = sanitize_html(markdowner.convert(form.cleaned_data['text']))
- question = Question(
- title = strip_tags(form.cleaned_data['title']),
- author = request.user,
- added_at = added_at,
- last_activity_at = added_at,
- last_activity_by = request.user,
- wiki = form.cleaned_data['wiki'],
- tagnames = form.cleaned_data['tags'].strip(),
- html = html,
- summary = strip_tags(html)[:120]
- )
- if question.wiki:
- question.last_edited_by = question.author
- question.last_edited_at = added_at
- question.wikified_at = added_at
-
- question.save()
-
- # create the first revision
- QuestionRevision.objects.create(
- question = question,
- revision = 1,
- title = question.title,
- author = request.user,
- revised_at = added_at,
- tagnames = question.tagnames,
- summary = CONST['default_version'],
- text = form.cleaned_data['text']
- )
-
- return HttpResponseRedirect(question.get_absolute_url())
-
- else:
- form = AskForm()
-
- tags = _get_tags_cache_json()
- return render_to_response('ask.html', {
- 'form' : form,
- 'tags' : tags,
- }, context_instance=RequestContext(request))
-
-def question(request, id):
- try:
- page = int(request.GET.get('page', '1'))
- except ValueError:
- page = 1
- view_id = request.GET.get('sort', 'votes')
- view_dic = {"latest":"-added_at", "oldest":"added_at", "votes":"-score" }
- try:
- orderby = view_dic[view_id]
- except KeyError:
- view_id = "votes"
- orderby = "-score"
-
- question = get_object_or_404(Question, id=id)
- if question.deleted and not can_view_deleted_post(request.user, question):
- raise Http404
- answer_form = AnswerForm(question)
- answers = Answer.objects.get_answers_from_question(question, request.user)
- answers = answers.select_related(depth=1)
-
- favorited = question.has_favorite_by_user(request.user)
- question_vote = question.votes.select_related().filter(user=request.user)
- if question_vote is not None and question_vote.count() > 0:
- question_vote = question_vote[0]
-
- user_answer_votes = {}
- for answer in answers:
- vote = answer.get_user_vote(request.user)
- if vote is not None and not user_answer_votes.has_key(answer.id):
- vote_value = -1
- if vote.is_upvote():
- vote_value = 1
- user_answer_votes[answer.id] = vote_value
-
-
- if answers is not None:
- answers = answers.order_by("-accepted", orderby)
- objects_list = Paginator(answers, ANSWERS_PAGE_SIZE)
- page_objects = objects_list.page(page)
- # update view count
- Question.objects.update_view_count(question)
- return render_to_response('question.html', {
- "question" : question,
- "question_vote" : question_vote,
- "question_comment_count":question.comments.count(),
- "answer" : answer_form,
- "answers" : page_objects.object_list,
- "user_answer_votes": user_answer_votes,
- "tags" : question.tags.all(),
- "tab_id" : view_id,
- "favorited" : favorited,
- "similar_questions" : Question.objects.get_similar_questions(question),
- "context" : {
- 'is_paginated' : True,
- 'pages': objects_list.num_pages,
- 'page': page,
- 'has_previous': page_objects.has_previous(),
- 'has_next': page_objects.has_next(),
- 'previous': page_objects.previous_page_number(),
- 'next': page_objects.next_page_number(),
- 'base_url' : request.path + '?sort=%s&' % view_id,
- 'extend_url' : "#sort-top"
- }
- }, context_instance=RequestContext(request))
-
-@login_required
-def close(request, id):
- question = get_object_or_404(Question, id=id)
- if not can_close_question(request.user, question):
- return HttpResponse('Permission denied.')
- if request.method == 'POST':
- form = CloseForm(request.POST)
- if form.is_valid():
- reason = form.cleaned_data['reason']
- question.closed = True
- question.closed_by = request.user
- question.closed_at = datetime.datetime.now()
- question.close_reason = reason
- question.save()
- return HttpResponseRedirect(question.get_absolute_url())
- else:
- form = CloseForm()
- return render_to_response('close.html', {
- 'form' : form,
- 'question' : question,
- }, context_instance=RequestContext(request))
-
-@login_required
-def reopen(request, id):
- question = get_object_or_404(Question, id=id)
- # open question
- if not can_reopen_question(request.user, question):
- return HttpResponse('Permission denied.')
- if request.method == 'POST' :
- Question.objects.filter(id=question.id).update(closed=False,
- closed_by=None, closed_at=None, close_reason=None)
- return HttpResponseRedirect(question.get_absolute_url())
- else:
- return render_to_response('reopen.html', {
- 'question' : question,
- }, context_instance=RequestContext(request))
-
-@login_required
-def edit_question(request, id):
- question = get_object_or_404(Question, id=id)
- if question.deleted and not can_view_deleted_post(request.user, question):
- raise Http404
- if can_edit_post(request.user, question):
- return _edit_question(request, question)
- elif can_retag_questions(request.user):
- return _retag_question(request, question)
- else:
- raise Http404
-
-def _retag_question(request, question):
- if request.method == 'POST':
- form = RetagQuestionForm(question, request.POST)
- if form.is_valid():
- if form.has_changed():
- latest_revision = question.get_latest_revision()
- retagged_at = datetime.datetime.now()
- # Update the Question itself
- Question.objects.filter(id=question.id).update(
- tagnames = form.cleaned_data['tags'],
- last_edited_at = retagged_at,
- last_edited_by = request.user,
- last_activity_at = retagged_at,
- last_activity_by = request.user
- )
- # Update the Question's tag associations
- tags_updated = Question.objects.update_tags(question,
- form.cleaned_data['tags'], request.user)
- # Create a new revision
- QuestionRevision.objects.create(
- question = question,
- title = latest_revision.title,
- author = request.user,
- revised_at = retagged_at,
- tagnames = form.cleaned_data['tags'],
- summary = CONST['retagged'],
- text = latest_revision.text
- )
- # send tags updated singal
- tags_updated.send(sender=question.__class__, question=question)
-
- return HttpResponseRedirect(question.get_absolute_url())
- else:
- form = RetagQuestionForm(question)
- return render_to_response('question_retag.html', {
- 'question': question,
- 'form' : form,
- 'tags' : _get_tags_cache_json(),
- }, context_instance=RequestContext(request))
-
-
-def _edit_question(request, question):
- latest_revision = question.get_latest_revision()
- revision_form = None
- if request.method == 'POST':
- if 'select_revision' in request.POST:
- # user has changed revistion number
- revision_form = RevisionForm(question, latest_revision, request.POST)
- if revision_form.is_valid():
- # Replace with those from the selected revision
- form = EditQuestionForm(question,
- QuestionRevision.objects.get(question=question,
- revision=revision_form.cleaned_data['revision']))
- else:
- form = EditQuestionForm(question, latest_revision, request.POST)
- else:
- # Always check modifications against the latest revision
- form = EditQuestionForm(question, latest_revision, request.POST)
- if form.is_valid():
- html = sanitize_html(markdowner.convert(form.cleaned_data['text']))
- if form.has_changed():
- edited_at = datetime.datetime.now()
- tags_changed = (latest_revision.tagnames !=
- form.cleaned_data['tags'])
- tags_updated = False
- # Update the Question itself
- updated_fields = {
- 'title': form.cleaned_data['title'],
- 'last_edited_at': edited_at,
- 'last_edited_by': request.user,
- 'last_activity_at': edited_at,
- 'last_activity_by': request.user,
- 'tagnames': form.cleaned_data['tags'],
- 'summary': strip_tags(html)[:120],
- 'html': html,
- }
-
- # only save when it's checked
- # because wiki doesn't allow to be edited if last version has been enabled already
- # and we make sure this in forms.
- if ('wiki' in form.cleaned_data and
- form.cleaned_data['wiki']):
- updated_fields['wiki'] = True
- updated_fields['wikified_at'] = edited_at
-
- Question.objects.filter(
- id=question.id).update(**updated_fields)
- # Update the Question's tag associations
- if tags_changed:
- tags_updated = Question.objects.update_tags(
- question, form.cleaned_data['tags'], request.user)
- # Create a new revision
- revision = QuestionRevision(
- question = question,
- title = form.cleaned_data['title'],
- author = request.user,
- revised_at = edited_at,
- tagnames = form.cleaned_data['tags'],
- text = form.cleaned_data['text'],
- )
- if form.cleaned_data['summary']:
- revision.summary = form.cleaned_data['summary']
- else:
- revision.summary = 'No.%s Revision' % latest_revision.revision
- revision.save()
-
- return HttpResponseRedirect(question.get_absolute_url())
- else:
-
- revision_form = RevisionForm(question, latest_revision)
- form = EditQuestionForm(question, latest_revision)
- return render_to_response('question_edit.html', {
- 'question': question,
- 'revision_form': revision_form,
- 'form' : form,
- 'tags' : _get_tags_cache_json()
- }, context_instance=RequestContext(request))
-
-
-@login_required
-def edit_answer(request, id):
- answer = get_object_or_404(Answer, id=id)
- if answer.deleted and not can_view_deleted_post(request.user, answer):
- raise Http404
- elif not can_edit_post(request.user, answer):
- raise Http404
- else:
- latest_revision = answer.get_latest_revision()
- if request.method == "POST":
- if 'select_revision' in request.POST:
- # user has changed revistion number
- revision_form = RevisionForm(answer, latest_revision, request.POST)
- if revision_form.is_valid():
- # Replace with those from the selected revision
- form = EditAnswerForm(answer,
- AnswerRevision.objects.get(answer=answer,
- revision=revision_form.cleaned_data['revision']))
- else:
- form = EditAnswerForm(answer, latest_revision, request.POST)
- else:
- form = EditAnswerForm(answer, latest_revision, request.POST)
- if form.is_valid():
- html = sanitize_html(markdowner.convert(form.cleaned_data['text']))
- if form.has_changed():
- edited_at = datetime.datetime.now()
- updated_fields = {
- 'last_edited_at': edited_at,
- 'last_edited_by': request.user,
- 'html': html,
- }
- Answer.objects.filter(id=answer.id).update(**updated_fields)
-
- revision = AnswerRevision(
- answer = answer,
- author = request.user,
- revised_at = edited_at,
- text = form.cleaned_data['text']
- )
-
- if form.cleaned_data['summary']:
- revision.summary = form.cleaned_data['summary']
- else:
- revision.summary = 'No.%s Revision' % latest_revision.revision
- revision.save()
-
- answer.question.last_activity_at = edited_at
- answer.question.last_activity_by = request.user
- answer.question.save()
-
- return HttpResponseRedirect(answer.get_absolute_url())
- else:
- revision_form = RevisionForm(answer, latest_revision)
- form = EditAnswerForm(answer, latest_revision)
- return render_to_response('answer_edit.html', {
- 'answer': answer,
- 'revision_form': revision_form,
- 'form' : form,
- }, context_instance=RequestContext(request))
-
-QUESTION_REVISION_TEMPLATE = ('<h1>%(title)s</h1>\n'
- '<div class="text">%(html)s</div>\n'
- '<div class="tags">%(tags)s</div>')
-def question_revisions(request, id):
- post = get_object_or_404(Question, id=id)
- revisions = list(post.revisions.all())
- for i, revision in enumerate(revisions):
- revision.html = QUESTION_REVISION_TEMPLATE % {
- 'title': revision.title,
- 'html': sanitize_html(markdowner.convert(revision.text)),
- 'tags': ' '.join(['<a class="post-tag">%s</a>' % tag
- for tag in revision.tagnames.split(' ')]),
- }
- if i > 0:
- revisions[i - 1].diff = htmldiff(revision.html,
- revisions[i - 1].html)
- else:
- revisions[i - 1].diff = QUESTION_REVISION_TEMPLATE % {
- 'title': revisions[0].title,
- 'html': sanitize_html(markdowner.convert(revisions[0].text)),
- 'tags': ' '.join(['<a class="post-tag">%s</a>' % tag
- for tag in revisions[0].tagnames.split(' ')]),
- }
- revisions[i - 1].summary = None
- return render_to_response('revisions_question.html', {
- 'post': post,
- 'revisions': revisions,
- }, context_instance=RequestContext(request))
-
-ANSWER_REVISION_TEMPLATE = ('<div class="text">%(html)s</div>')
-def answer_revisions(request, id):
- post = get_object_or_404(Answer, id=id)
- revisions = list(post.revisions.all())
- for i, revision in enumerate(revisions):
- revision.html = ANSWER_REVISION_TEMPLATE % {
- 'html': sanitize_html(markdowner.convert(revision.text))
- }
- if i > 0:
- revisions[i - 1].diff = htmldiff(revision.html,
- revisions[i - 1].html)
- else:
- revisions[i - 1].diff = revisions[i-1].text
- revisions[i - 1].summary = None
- return render_to_response('revisions_answer.html', {
- 'post': post,
- 'revisions': revisions,
- }, context_instance=RequestContext(request))
-
-#TODO: allow anynomus
-@login_required
-def answer(request, id):
- question = get_object_or_404(Question, id=id)
- if request.method == "POST":
- form = AnswerForm(question, request.POST)
- if form.is_valid():
- update_time = datetime.datetime.now()
- answer = Answer(
- question = question,
- author = request.user,
- added_at = update_time,
- wiki = form.cleaned_data['wiki'],
- html = sanitize_html(markdowner.convert(form.cleaned_data['text'])),
- )
- if answer.wiki:
- answer.last_edited_by = answer.author
- answer.last_edited_at = update_time
- answer.wikified_at = update_time
-
- answer.save()
- Question.objects.update_answer_count(question)
-
- question = get_object_or_404(Question, id=id)
- question.last_activity_at = update_time
- question.last_activity_by = request.user
- question.save()
-
- AnswerRevision.objects.create(
- answer = answer,
- revision = 1,
- author = request.user,
- revised_at = update_time,
- summary = CONST['default_version'],
- text = form.cleaned_data['text']
- )
-
- return HttpResponseRedirect(question.get_absolute_url())
-
-def tags(request):
- stag = ""
- is_paginated = True
- sortby = request.GET.get('sort', 'used')
- try:
- page = int(request.GET.get('page', '1'))
- except ValueError:
- page = 1
-
- if request.method == "GET":
- stag = request.GET.get("q", "").strip()
- if stag is not None:
- objects_list = Paginator(Tag.objects.filter(deleted=False).exclude(used_count=0).extra(where=['name like %s'], params=['%' + stag + '%']), DEFAULT_PAGE_SIZE)
- else:
- if sortby == "name":
- objects_list = Paginator(Tag.objects.all().filter(deleted=False).exclude(used_count=0).order_by("name"), DEFAULT_PAGE_SIZE)
- else:
- objects_list = Paginator(Tag.objects.all().filter(deleted=False).exclude(used_count=0).order_by("-used_count"), DEFAULT_PAGE_SIZE)
-
- try:
- tags = objects_list.page(page)
- except (EmptyPage, InvalidPage):
- tags = objects_list.page(objects_list.num_pages)
-
- return render_to_response('tags.html', {
- "tags" : tags,
- "stag" : stag,
- "tab_id" : sortby,
- "keywords" : stag,
- "context" : {
- 'is_paginated' : is_paginated,
- 'pages': objects_list.num_pages,
- 'page': page,
- 'has_previous': tags.has_previous(),
- 'has_next': tags.has_next(),
- 'previous': tags.previous_page_number(),
- 'next': tags.next_page_number(),
- 'base_url' : '/tags/?sort=%s&' % sortby
- }
-
- }, context_instance=RequestContext(request))
-
-def tag(request, tag):
- return questions(request, tagname=tag)
-
-def vote(request, id):
- """
- vote_type:
- acceptAnswer : 0,
- questionUpVote : 1,
- questionDownVote : 2,
- favorite : 4,
- answerUpVote: 5,
- answerDownVote:6,
- offensiveQuestion : 7,
- offensiveAnswer:8,
- removeQuestion: 9,
- removeAnswer:10
-
- accept answer code:
- response_data['allowed'] = -1, Accept his own answer 0, no allowed - Anonymous 1, Allowed - by default
- response_data['success'] = 0, failed 1, Success - by default
- response_data['status'] = 0, By default 1, Answer has been accepted already(Cancel)
-
- vote code:
- allowed = -3, Don't have enough votes left
- -2, Don't have enough reputation score
- -1, Vote his own post
- 0, no allowed - Anonymous
- 1, Allowed - by default
- status = 0, By default
- 1, Cancel
- 2, Vote is too old to be canceled
-
- offensive code:
- allowed = -3, Don't have enough flags left
- -2, Don't have enough reputation score to do this
- 0, not allowed
- 1, allowed
- status = 0, by default
- 1, can't do it again
- """
- response_data = {
- "allowed": 1,
- "success": 1,
- "status" : 0,
- "count" : 0,
- "message" : ''
- }
-
- def can_vote(vote_score, user):
- if vote_score == 1:
- return can_vote_up(request.user)
- else:
- return can_vote_down(request.user)
-
- try:
- if not request.user.is_authenticated():
- response_data['allowed'] = 0
- response_data['success'] = 0
-
- elif request.is_ajax():
- question = get_object_or_404(Question, id=id)
- vote_type = request.POST.get('type')
-
- #accept answer
- if vote_type == '0':
- answer_id = request.POST.get('postId')
- answer = get_object_or_404(Answer, id=answer_id)
- # make sure question author is current user
- if question.author == request.user:
- # answer user who is also question author is not allow to accept answer
- if answer.author == question.author:
- response_data['success'] = 0
- response_data['allowed'] = -1
- # check if answer has been accepted already
- elif answer.accepted:
- onAnswerAcceptCanceled(answer, request.user)
- response_data['status'] = 1
- else:
- # set other answers in this question not accepted first
- for answer_of_question in Answer.objects.get_answers_from_question(question, request.user):
- if answer_of_question != answer and answer_of_question.accepted:
- onAnswerAcceptCanceled(answer_of_question, request.user)
-
- #make sure retrieve data again after above author changes, they may have related data
- answer = get_object_or_404(Answer, id=answer_id)
- onAnswerAccept(answer, request.user)
- else:
- response_data['allowed'] = 0
- response_data['success'] = 0
- # favorite
- elif vote_type == '4':
- has_favorited = False
- fav_questions = FavoriteQuestion.objects.filter(question=question)
- # if the same question has been favorited before, then delete it
- if fav_questions is not None:
- for item in fav_questions:
- if item.user == request.user:
- item.delete()
- response_data['status'] = 1
- response_data['count'] = len(fav_questions) - 1
- if response_data['count'] < 0:
- response_data['count'] = 0
- has_favorited = True
- # if above deletion has not been executed, just insert a new favorite question
- if not has_favorited:
- new_item = FavoriteQuestion(question=question, user=request.user)
- new_item.save()
- response_data['count'] = FavoriteQuestion.objects.filter(question=question).count()
- Question.objects.update_favorite_count(question)
-
- elif vote_type in ['1', '2', '5', '6']:
- post_id = id
- post = question
- vote_score = 1
- if vote_type in ['5', '6']:
- answer_id = request.POST.get('postId')
- answer = get_object_or_404(Answer, id=answer_id)
- post_id = answer_id
- post = answer
- if vote_type in ['2', '6']:
- vote_score = -1
-
- if post.author == request.user:
- response_data['allowed'] = -1
- elif not can_vote(vote_score, request.user):
- response_data['allowed'] = -2
- elif post.votes.filter(user=request.user).count() > 0:
- vote = post.votes.filter(user=request.user)[0]
- # unvote should be less than certain time
- if (datetime.datetime.now().day - vote.voted_at.day) >= VOTE_RULES['scope_deny_unvote_days']:
- response_data['status'] = 2
- else:
- voted = vote.vote
- if voted > 0:
- # cancel upvote
- onUpVotedCanceled(vote, post, request.user)
-
- else:
- # cancel downvote
- onDownVotedCanceled(vote, post, request.user)
-
- response_data['status'] = 1
- response_data['count'] = post.score
- elif Vote.objects.get_votes_count_today_from_user(request.user) >= VOTE_RULES['scope_votes_per_user_per_day']:
- response_data['allowed'] = -3
- else:
- vote = Vote(user=request.user, content_object=post, vote=vote_score, voted_at=datetime.datetime.now())
- if vote_score > 0:
- # upvote
- onUpVoted(vote, post, request.user)
- else:
- # downvote
- onDownVoted(vote, post, request.user)
-
- votes_left = VOTE_RULES['scope_votes_per_user_per_day'] - Vote.objects.get_votes_count_today_from_user(request.user)
- if votes_left <= VOTE_RULES['scope_warn_votes_left']:
- response_data['message'] = u'%s votes left' % votes_left
- response_data['count'] = post.score
- elif vote_type in ['7', '8']:
- post = question
- post_id = id
- if vote_type == '8':
- post_id = request.POST.get('postId')
- post = get_object_or_404(Answer, id=post_id)
-
- if FlaggedItem.objects.get_flagged_items_count_today(request.user) >= VOTE_RULES['scope_flags_per_user_per_day']:
- response_data['allowed'] = -3
- elif not can_flag_offensive(request.user):
- response_data['allowed'] = -2
- elif post.flagged_items.filter(user=request.user).count() > 0:
- response_data['status'] = 1
- else:
- item = FlaggedItem(user=request.user, content_object=post, flagged_at=datetime.datetime.now())
- onFlaggedItem(item, post, request.user)
- response_data['count'] = post.offensive_flag_count
- # send signal when question or answer be marked offensive
- mark_offensive.send(sender=post.__class__, instance=post, mark_by=request.user)
- elif vote_type in ['9', '10']:
- post = question
- post_id = id
- if vote_type == '10':
- post_id = request.POST.get('postId')
- post = get_object_or_404(Answer, id=post_id)
-
- if not can_delete_post(request.user, post):
- response_data['allowed'] = -2
- elif post.deleted:
- onDeleteCanceled(post, request.user)
- response_data['status'] = 1
- else:
- onDeleted(post, request.user)
- delete_post_or_answer.send(sender=post.__class__, instance=post, delete_by=request.user)
- else:
- response_data['success'] = 0
- response_data['message'] = u'Request mode is not supported. Please try again.'
-
- data = simplejson.dumps(response_data)
-
- except Exception, e:
- response_data['message'] = str(e)
- data = simplejson.dumps(response_data)
- return HttpResponse(data, mimetype="application/json")
-
-def users(request):
- is_paginated = True
- sortby = request.GET.get('sort', 'reputation')
- suser = request.REQUEST.get('q', "")
- try:
- page = int(request.GET.get('page', '1'))
- except ValueError:
- page = 1
-
- if suser == "":
- if sortby == "newest":
- objects_list = Paginator(User.objects.all().order_by('-date_joined'), USERS_PAGE_SIZE)
- elif sortby == "last":
- objects_list = Paginator(User.objects.all().order_by('date_joined'), USERS_PAGE_SIZE)
- elif sortby == "user":
- objects_list = Paginator(User.objects.all().order_by('username'), USERS_PAGE_SIZE)
- # default
- else:
- objects_list = Paginator(User.objects.all().order_by('-reputation'), USERS_PAGE_SIZE)
- base_url = '/users/?sort=%s&' % sortby
- else:
- sortby = "reputation"
- objects_list = Paginator(User.objects.extra(where=['username like %s'], params=['%' + suser + '%']).order_by('-reputation'), USERS_PAGE_SIZE)
- base_url = '/users/?name=%s&sort=%s&' % (suser, sortby)
-
- try:
- users = objects_list.page(page)
- except (EmptyPage, InvalidPage):
- users = objects_list.page(objects_list.num_pages)
-
- return render_to_response('users.html', {
- "users" : users,
- "suser" : suser,
- "keywords" : suser,
- "tab_id" : sortby,
- "context" : {
- 'is_paginated' : is_paginated,
- 'pages': objects_list.num_pages,
- 'page': page,
- 'has_previous': users.has_previous(),
- 'has_next': users.has_next(),
- 'previous': users.previous_page_number(),
- 'next': users.next_page_number(),
- 'base_url' : base_url
- }
-
- }, context_instance=RequestContext(request))
-
-def user(request, id):
- sort = request.GET.get('sort', 'stats')
- user_view = dict((v.id, v) for v in USER_TEMPLATE_VIEWS).get(sort, USER_TEMPLATE_VIEWS[0])
- from forum import views
- func = getattr(views, user_view.view_name)
- return func(request, id, user_view)
-
-@login_required
-def edit_user(request, id):
- user = get_object_or_404(User, id=id)
- if request.user != user:
- raise Http404
- if request.method == "POST":
- form = EditUserForm(user, request.POST)
- if form.is_valid():
- user.email = sanitize_html(form.cleaned_data['email'])
- user.real_name = sanitize_html(form.cleaned_data['realname'])
- user.website = sanitize_html(form.cleaned_data['website'])
- user.location = sanitize_html(form.cleaned_data['city'])
- user.date_of_birth = sanitize_html(form.cleaned_data['birthday'])
- if len(user.date_of_birth) == 0:
- user.date_of_birth = '1900-01-01'
- user.about = sanitize_html(form.cleaned_data['about'])
-
- user.save()
- # send user updated singal if full fields have been updated
- if user.email and user.real_name and user.website and user.location and \
- user.date_of_birth and user.about:
- user_updated.send(sender=user.__class__, instance=user, updated_by=user)
- return HttpResponseRedirect(user.get_profile_url())
- else:
- form = EditUserForm(user)
- return render_to_response('user_edit.html', {
- 'form' : form,
- }, context_instance=RequestContext(request))
-
-def user_stats(request, user_id, user_view):
- user = get_object_or_404(User, id=user_id)
- questions = Question.objects.extra(
- select={
- 'vote_count' : 'question.score',
- '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',
- 'la_user_silver' : 'auth_user.silver',
- 'la_user_bronze' : 'auth_user.bronze',
- 'la_user_reputation' : 'auth_user.reputation'
- },
- select_params=[user_id],
- tables=['question', 'auth_user'],
- where=['question.deleted = 0 AND question.author_id=%s AND question.last_activity_by_id = auth_user.id'],
- params=[user_id],
- order_by=['-vote_count', '-last_activity_at']
- ).values('vote_count',
- 'favorited_myself',
- 'id',
- 'title',
- 'author_id',
- 'added_at',
- 'answer_accepted',
- 'answer_count',
- 'comment_count',
- 'view_count',
- 'favourite_count',
- 'summary',
- 'tagnames',
- 'vote_up_count',
- 'vote_down_count',
- 'last_activity_at',
- 'la_user_id',
- 'la_username',
- 'la_user_gold',
- 'la_user_silver',
- 'la_user_bronze',
- 'la_user_reputation')[:100]
-
- answered_questions = Question.objects.extra(
- select={
- 'vote_up_count' : 'answer.vote_up_count',
- 'vote_down_count' : 'answer.vote_down_count',
- 'answer_id' : 'answer.id',
- 'accepted' : 'answer.accepted',
- 'vote_count' : 'answer.score',
- 'comment_count' : 'answer.comment_count'
- },
- tables=['question', 'answer'],
- where=['answer.deleted=0 AND answer.author_id=%s AND answer.question_id=question.id'],
- params=[user_id],
- order_by=['-vote_count', '-answer_id'],
- select_params=[user_id]
- ).distinct().values('comment_count',
- 'id',
- 'answer_id',
- 'title',
- 'author_id',
- 'accepted',
- 'vote_count',
- 'answer_count',
- 'vote_up_count',
- 'vote_down_count')[:100]
- up_votes = Vote.objects.get_up_vote_count_from_user(user)
- down_votes = Vote.objects.get_down_vote_count_from_user(user)
- votes_today = Vote.objects.get_votes_count_today_from_user(user)
- votes_total = VOTE_RULES['scope_votes_per_user_per_day']
- tags = user.created_tags.all().order_by('-used_count')[:50]
- awards = Award.objects.extra(
- select={'id': 'badge.id', 'count': 'count(badge_id)', 'name':'badge.name', 'description': 'badge.description', 'type': 'badge.type'},
- tables=['award', 'badge'],
- order_by=['-awarded_at'],
- where=['user_id=%s AND badge_id=badge.id'],
- params=[user.id]
- ).values('id', 'count', 'name', 'description', 'type')
- total_awards = awards.count()
- awards.query.group_by = ['badge_id']
-
- return render_to_response(user_view.template_file,{
- "tab_name" : user_view.id,
- "tab_description" : user_view.tab_description,
- "page_title" : user_view.page_title,
- "view_user" : user,
- "questions" : questions,
- "answered_questions" : answered_questions,
- "up_votes" : up_votes,
- "down_votes" : down_votes,
- "total_votes": up_votes + down_votes,
- "votes_today_left": votes_total-votes_today,
- "votes_total_per_day": votes_total,
- "tags" : tags,
- "awards": awards,
- "total_awards" : total_awards,
- }, context_instance=RequestContext(request))
-
-def user_recent(request, user_id, user_view):
- user = get_object_or_404(User, id=user_id)
- def get_type_name(type_id):
- for item in TYPE_ACTIVITY:
- if type_id in item:
- return item[1]
-
- class Event:
- def __init__(self, time, type, title, summary, answer_id, question_id):
- self.time = time
- self.type = get_type_name(type)
- self.type_id = type
- self.title = title
- self.summary = summary
- self.title_link = u'/questions/%s/%s#%s' %(question_id, title, answer_id)\
- if int(answer_id) > 0 else u'/questions/%s/%s' %(question_id, title)
- class AwardEvent:
- def __init__(self, time, type, id):
- self.time = time
- self.type = get_type_name(type)
- self.type_id = type
- self.badge = get_object_or_404(Badge, id=id)
-
- activities = []
- # ask questions
- questions = Activity.objects.extra(
- select={
- 'title' : 'question.title',
- 'question_id' : 'question.id',
- 'active_at' : 'activity.active_at',
- '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'],
- params=[question_type_id, user_id, TYPE_ACTIVITY_ASK_QUESTION],
- order_by=['-activity.active_at']
- ).values(
- 'title',
- 'question_id',
- 'active_at',
- 'activity_type'
- )
- if len(questions) > 0:
- questions = [(Event(q['active_at'], q['activity_type'], q['title'], '', '0', \
- q['question_id'])) for q in questions]
- activities.extend(questions)
-
- # answers
- answers = Activity.objects.extra(
- select={
- 'title' : 'question.title',
- 'question_id' : 'question.id',
- 'answer_id' : 'answer.id',
- 'active_at' : 'activity.active_at',
- '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'],
- params=[answer_type_id, user_id, TYPE_ACTIVITY_ANSWER],
- order_by=['-activity.active_at']
- ).values(
- 'title',
- 'question_id',
- 'answer_id',
- 'active_at',
- 'activity_type'
- )
- if len(answers) > 0:
- answers = [(Event(q['active_at'], q['activity_type'], q['title'], '', q['answer_id'], \
- q['question_id'])) for q in answers]
- activities.extend(answers)
-
- # question comments
- comments = Activity.objects.extra(
- select={
- 'title' : 'question.title',
- 'question_id' : 'comment.object_id',
- 'added_at' : 'comment.added_at',
- 'activity_type' : 'activity.activity_type'
- },
- 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'],
- params=[comment_type_id, question_type_id, user_id, TYPE_ACTIVITY_COMMENT_QUESTION],
- order_by=['-comment.added_at']
- ).values(
- 'title',
- 'question_id',
- 'added_at',
- 'activity_type'
- )
-
- if len(comments) > 0:
- comments = [(Event(q['added_at'], q['activity_type'], q['title'], '', '0', \
- q['question_id'])) for q in comments]
- activities.extend(comments)
-
- # answer comments
- comments = Activity.objects.extra(
- select={
- 'title' : 'question.title',
- 'question_id' : 'question.id',
- 'answer_id' : 'answer.id',
- 'added_at' : 'comment.added_at',
- 'activity_type' : 'activity.activity_type'
- },
- 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'],
- params=[comment_type_id, answer_type_id, user_id, TYPE_ACTIVITY_COMMENT_ANSWER],
- order_by=['-comment.added_at']
- ).values(
- 'title',
- 'question_id',
- 'answer_id',
- 'added_at',
- 'activity_type'
- )
-
- if len(comments) > 0:
- comments = [(Event(q['added_at'], q['activity_type'], q['title'], '', q['answer_id'], \
- q['question_id'])) for q in comments]
- activities.extend(comments)
-
- # question revisions
- revisions = Activity.objects.extra(
- select={
- 'title' : 'question_revision.title',
- 'question_id' : 'question_revision.question_id',
- 'added_at' : 'activity.active_at',
- 'activity_type' : 'activity.activity_type',
- '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'],
- params=[question_revision_type_id, user_id, TYPE_ACTIVITY_UPDATE_QUESTION],
- order_by=['-activity.active_at']
- ).values(
- 'title',
- 'question_id',
- 'added_at',
- 'activity_type',
- 'summary'
- )
-
- if len(revisions) > 0:
- revisions = [(Event(q['added_at'], q['activity_type'], q['title'], q['summary'], '0', \
- q['question_id'])) for q in revisions]
- activities.extend(revisions)
-
- # answer revisions
- revisions = Activity.objects.extra(
- select={
- 'title' : 'question.title',
- 'question_id' : 'question.id',
- 'answer_id' : 'answer.id',
- 'added_at' : 'activity.active_at',
- 'activity_type' : 'activity.activity_type',
- 'summary' : 'answer_revision.summary'
- },
- 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'],
- params=[answer_revision_type_id, user_id, TYPE_ACTIVITY_UPDATE_ANSWER],
- order_by=['-activity.active_at']
- ).values(
- 'title',
- 'question_id',
- 'added_at',
- 'answer_id',
- 'activity_type',
- 'summary'
- )
-
- if len(revisions) > 0:
- revisions = [(Event(q['added_at'], q['activity_type'], q['title'], q['summary'], \
- q['answer_id'], q['question_id'])) for q in revisions]
- activities.extend(revisions)
-
- # accepted answers
- accept_answers = Activity.objects.extra(
- select={
- 'title' : 'question.title',
- 'question_id' : 'question.id',
- 'added_at' : 'activity.active_at',
- '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'],
- params=[answer_type_id, user_id, TYPE_ACTIVITY_MARK_ANSWER],
- order_by=['-activity.active_at']
- ).values(
- 'title',
- 'question_id',
- 'added_at',
- 'activity_type',
- )
- if len(accept_answers) > 0:
- accept_answers = [(Event(q['added_at'], q['activity_type'], q['title'], '', '0', \
- q['question_id'])) for q in accept_answers]
- activities.extend(accept_answers)
- #award history
- awards = Activity.objects.extra(
- select={
- 'badge_id' : 'badge.id',
- 'awarded_at': 'award.awarded_at',
- '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'],
- params=[user_id, TYPE_ACTIVITY_PRIZE],
- order_by=['-activity.active_at']
- ).values(
- 'badge_id',
- 'awarded_at',
- 'activity_type'
- )
- if len(awards) > 0:
- awards = [(AwardEvent(q['awarded_at'], q['activity_type'], q['badge_id'])) for q in awards]
- activities.extend(awards)
-
- activities.sort(lambda x,y: cmp(y.time, x.time))
-
- return render_to_response(user_view.template_file,{
- "tab_name" : user_view.id,
- "tab_description" : user_view.tab_description,
- "page_title" : user_view.page_title,
- "view_user" : user,
- "activities" : activities[:user_view.data_size]
- }, context_instance=RequestContext(request))
-
-def user_responses(request, user_id, user_view):
- """
- We list answers for question, comments, and answer accepted by others for this user.
- """
- class Response:
- def __init__(self, type, title, question_id, answer_id, time, username, user_id, content):
- self.type = type
- self.title = title
- self.titlelink = u'/questions/%s/%s#%s' % (question_id, title, answer_id)
- self.time = time
- self.userlink = u'/users/%s/%s/' % (user_id, username)
- self.username = username
- self.content = u'%s ...' % strip_tags(content)[:300]
-
- def __unicode__(self):
- return u'%s %s' % (self.type, self.titlelink)
-
- user = get_object_or_404(User, id=user_id)
- responses = []
- answers = Answer.objects.extra(
- select={
- 'title' : 'question.title',
- 'question_id' : 'question.id',
- 'answer_id' : 'answer.id',
- 'added_at' : 'answer.added_at',
- 'html' : 'answer.html',
- 'username' : 'auth_user.username',
- 'user_id' : 'auth_user.id'
- },
- 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'],
- params=[user_id, user_id],
- order_by=['-answer.id']
- ).values(
- 'title',
- 'question_id',
- 'answer_id',
- 'added_at',
- 'html',
- 'username',
- 'user_id'
- )
- if len(answers) > 0:
- answers = [(Response(TYPE_RESPONSE['QUESTION_ANSWERED'], a['title'], a['question_id'],
- a['answer_id'], a['added_at'], a['username'], a['user_id'], a['html'])) for a in answers]
- responses.extend(answers)
-
-
- # question comments
- comments = Comment.objects.extra(
- select={
- 'title' : 'question.title',
- 'question_id' : 'comment.object_id',
- 'added_at' : 'comment.added_at',
- 'comment' : 'comment.comment',
- 'username' : 'auth_user.username',
- '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'],
- params=[user_id, question_type_id, user_id],
- order_by=['-comment.added_at']
- ).values(
- 'title',
- 'question_id',
- 'added_at',
- 'comment',
- 'username',
- 'user_id'
- )
-
- if len(comments) > 0:
- comments = [(Response(TYPE_RESPONSE['QUESTION_COMMENTED'], c['title'], c['question_id'],
- '', c['added_at'], c['username'], c['user_id'], c['comment'])) for c in comments]
- responses.extend(comments)
-
- # answer comments
- comments = Comment.objects.extra(
- select={
- 'title' : 'question.title',
- 'question_id' : 'question.id',
- 'answer_id' : 'answer.id',
- 'added_at' : 'comment.added_at',
- 'comment' : 'comment.comment',
- 'username' : 'auth_user.username',
- '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'],
- params=[user_id, answer_type_id, user_id],
- order_by=['-comment.added_at']
- ).values(
- 'title',
- 'question_id',
- 'answer_id',
- 'added_at',
- 'comment',
- 'username',
- 'user_id'
- )
-
- if len(comments) > 0:
- comments = [(Response(TYPE_RESPONSE['ANSWER_COMMENTED'], c['title'], c['question_id'],
- c['answer_id'], c['added_at'], c['username'], c['user_id'], c['comment'])) for c in comments]
- responses.extend(comments)
-
- # answer has been accepted
- answers = Answer.objects.extra(
- select={
- 'title' : 'question.title',
- 'question_id' : 'question.id',
- 'answer_id' : 'answer.id',
- 'added_at' : 'answer.accepted_at',
- 'html' : 'answer.html',
- 'username' : 'auth_user.username',
- 'user_id' : 'auth_user.id'
- },
- 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'],
- params=[user_id],
- order_by=['-answer.id']
- ).values(
- 'title',
- 'question_id',
- 'answer_id',
- 'added_at',
- 'html',
- 'username',
- 'user_id'
- )
- if len(answers) > 0:
- answers = [(Response(TYPE_RESPONSE['ANSWER_ACCEPTED'], a['title'], a['question_id'],
- a['answer_id'], a['added_at'], a['username'], a['user_id'], a['html'])) for a in answers]
- responses.extend(answers)
-
- # sort posts by time
- responses.sort(lambda x,y: cmp(y.time, x.time))
-
- return render_to_response(user_view.template_file,{
- "tab_name" : user_view.id,
- "tab_description" : user_view.tab_description,
- "page_title" : user_view.page_title,
- "view_user" : user,
- "responses" : responses[:user_view.data_size],
-
- }, context_instance=RequestContext(request))
-
-def user_votes(request, user_id, user_view):
- user = get_object_or_404(User, id=user_id)
- if not can_view_user_votes(request.user, user):
- raise Http404
- votes = []
- question_votes = Vote.objects.extra(
- select={
- 'title' : 'question.title',
- 'question_id' : 'question.id',
- 'answer_id' : 0,
- 'voted_at' : 'vote.voted_at',
- 'vote' : 'vote',
- },
- 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'],
- params=[question_type_id, user_id],
- order_by=['-vote.id']
- ).values(
- 'title',
- 'question_id',
- 'answer_id',
- 'voted_at',
- 'vote',
- )
- if(len(question_votes) > 0):
- votes.extend(question_votes)
-
- answer_votes = Vote.objects.extra(
- select={
- 'title' : 'question.title',
- 'question_id' : 'question.id',
- 'answer_id' : 'answer.id',
- 'voted_at' : 'vote.voted_at',
- 'vote' : 'vote',
- },
- 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'],
- params=[answer_type_id, user_id],
- order_by=['-vote.id']
- ).values(
- 'title',
- 'question_id',
- 'answer_id',
- 'voted_at',
- 'vote',
- )
- if(len(answer_votes) > 0):
- votes.extend(answer_votes)
- votes.sort(lambda x,y: cmp(y['voted_at'], x['voted_at']))
- return render_to_response(user_view.template_file,{
- "tab_name" : user_view.id,
- "tab_description" : user_view.tab_description,
- "page_title" : user_view.page_title,
- "view_user" : user,
- "votes" : votes[:user_view.data_size]
-
- }, context_instance=RequestContext(request))
-
-def user_reputation(request, user_id, user_view):
- user = get_object_or_404(User, id=user_id)
- reputation = Repute.objects.extra(
- select={'positive': 'sum(positive)', 'negative': 'sum(negative)', 'question_id':'question_id',
- 'title': 'question.title'},
- tables=['repute', 'question'],
- order_by=['-reputed_at'],
- where=['user_id=%s AND question_id=question.id'],
- params=[user.id]
- ).values('positive', 'negative', 'question_id', 'title', 'reputed_at', 'reputation')
-
- reputation.query.group_by = ['question_id']
-
-
- rep_list = []
- for rep in Repute.objects.filter(user=user).order_by('reputed_at'):
- dic = '[%s,%s]' % (calendar.timegm(rep.reputed_at.timetuple()) * 1000, rep.reputation)
- rep_list.append(dic)
- reps = ','.join(rep_list)
- reps = '[%s]' % reps
-
- return render_to_response(user_view.template_file,{
- "tab_name" : user_view.id,
- "tab_description" : user_view.tab_description,
- "page_title" : user_view.page_title,
- "view_user" : user,
- "reputation" : reputation,
- "reps" : reps
- }, context_instance=RequestContext(request))
-
-def user_favorites(request, user_id, user_view):
- user = get_object_or_404(User, id=user_id)
- 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',
- 'la_user_id' : 'auth_user.id',
- 'la_username' : 'auth_user.username',
- 'la_user_gold' : 'auth_user.gold',
- 'la_user_silver' : 'auth_user.silver',
- 'la_user_bronze' : 'auth_user.bronze',
- 'la_user_reputation' : 'auth_user.reputation'
- },
- 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'],
- params=[user_id],
- order_by=['-vote_count', '-question.id']
- ).values('vote_count',
- 'favorited_myself',
- 'id',
- 'title',
- 'author_id',
- 'added_at',
- 'answer_accepted',
- 'answer_count',
- 'comment_count',
- 'view_count',
- 'favourite_count',
- 'summary',
- 'tagnames',
- 'vote_up_count',
- 'vote_down_count',
- 'last_activity_at',
- 'la_user_id',
- 'la_username',
- 'la_user_gold',
- 'la_user_silver',
- 'la_user_bronze',
- 'la_user_reputation')
- return render_to_response(user_view.template_file,{
- "tab_name" : user_view.id,
- "tab_description" : user_view.tab_description,
- "page_title" : user_view.page_title,
- "questions" : questions[:user_view.data_size],
- "view_user" : user
- }, context_instance=RequestContext(request))
-
-
-def user_preferences(request, user_id, user_view):
- user = get_object_or_404(User, id=user_id)
- return render_to_response(user_view.template_file,{
- "tab_name" : user_view.id,
- "tab_description" : user_view.tab_description,
- "page_title" : user_view.page_title,
- "view_user" : user,
- }, context_instance=RequestContext(request))
-
-def question_comments(request, id):
- question = get_object_or_404(Question, id=id)
- user = request.user
- return __comments(request, question, 'question', user)
-
-def answer_comments(request, id):
- answer = get_object_or_404(Answer, id=id)
- user = request.user
- return __comments(request, answer, 'answer', user)
-
-def __comments(request, obj, type, user):
- # only support get comments by ajax now
- if request.is_ajax():
- if request.method == "GET":
- return __generate_comments_json(obj, type, user)
- elif request.method == "POST":
- comment_data = request.POST.get('comment')
- comment = Comment(content_object=obj, comment=comment_data, user=request.user)
- comment.save()
- obj.comment_count = obj.comment_count + 1
- obj.save()
- return __generate_comments_json(obj, type, user)
-
-def __generate_comments_json(obj, type, user):
- comments = obj.comments.all().order_by('-id')
- # {"Id":6,"PostId":38589,"CreationDate":"an hour ago","Text":"hello there!","UserDisplayName":"Jarrod Dixon","UserUrl":"/users/3/jarrod-dixon","DeleteUrl":null}
- json_comments = []
- for comment in comments:
- comment_user = comment.user
- delete_url = ""
- if user != None and auth.can_delete_comment(user, comment):
- #/posts/392845/comments/219852/delete
- delete_url = "/" + type + "s/%s/comments/%s/delete/" % (obj.id, comment.id)
- json_comments.append({"id" : comment.id,
- "object_id" : obj.id,
- "add_date" : comment.added_at.strftime('%Y-%m-%d'),
- "text" : comment.comment,
- "user_display_name" : comment_user.username,
- "user_url" : "/users/%s/%s" % (comment_user.id, comment_user.username),
- "delete_url" : delete_url
- })
-
- data = simplejson.dumps(json_comments)
- return HttpResponse(data, mimetype="application/json")
-
-def delete_question_comment(request, question_id, comment_id):
- if request.is_ajax():
- question = get_object_or_404(Question, id=question_id)
- comment = get_object_or_404(Comment, id=comment_id)
-
- question.comments.remove(comment)
- question.comment_count = question.comment_count - 1
- question.save()
- user = request.user
- return __generate_comments_json(question, 'question', user)
-
-def delete_answer_comment(request, answer_id, comment_id):
- if request.is_ajax():
- answer = get_object_or_404(Answer, id=answer_id)
- comment = get_object_or_404(Comment, id=comment_id)
-
- answer.comments.remove(comment)
- answer.comment_count = answer.comment_count - 1
- answer.save()
- user = request.user
- return __generate_comments_json(answer, 'answer', user)
-
-def logout(request):
- url = request.GET.get('next')
- return render_to_response('logout.html', {
- 'next' : url,
- }, context_instance=RequestContext(request))
-
-def badges(request):
- badges = Badge.objects.all().order_by('type')
- my_badges = []
- if request.user.is_authenticated():
- my_badges = Award.objects.filter(user=request.user)
- my_badges.query.group_by = ['badge_id']
-
- return render_to_response('badges.html', {
- 'badges' : badges,
- 'mybadges' : my_badges,
- }, context_instance=RequestContext(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'},
- tables=['award', 'auth_user'],
- where=['badge_id=%s AND user_id=auth_user.id'],
- params=[id]
- ).values('id').distinct()
-
- return render_to_response('badge.html', {
- 'awards' : awards,
- 'badge' : badge,
- }, context_instance=RequestContext(request))
-
-def read_message(request):
- if request.method == "POST":
- if request.POST['formdata'] == 'required':
- request.session['message_silent'] = 1
-
- if request.user.is_authenticated():
- request.user.delete_messages()
- return HttpResponse('')
-
-def upload(request):
- class FileTypeNotAllow(Exception):
- pass
- class FileSizeNotAllow(Exception):
- pass
- class UploadPermissionNotAuthorized(Exception):
- pass
-
- #<result><msg><![CDATA[%s]]></msg><error><![CDATA[%s]]></error><file_url>%s</file_url></result>
- xml_template = "<result><msg><![CDATA[%s]]></msg><error><![CDATA[%s]]></error><file_url>%s</file_url></result>"
-
- try:
- f = request.FILES['file-upload']
- # check upload permission
- if not can_upload_files(request.user):
- raise UploadPermissionNotAuthorized
-
- # check file type
- file_name_suffix = os.path.splitext(f.name)[1].lower()
- if not file_name_suffix in settings.ALLOW_FILE_TYPES:
- raise FileTypeNotAllow
-
- # genetate new file name
- new_file_name = str(time.time()).replace('.', str(random.randint(0,100000))) + file_name_suffix
- # use default storage to store file
- default_storage.save(new_file_name, f)
- # check file size
- # byte
- size = default_storage.size(new_file_name)
- if size > settings.ALLOW_MAX_FILE_SIZE:
- default_storage.delete(new_file_name)
- raise FileSizeNotAllow
-
- result = xml_template % ('Good', '', default_storage.url(new_file_name))
- except UploadPermissionNotAuthorized:
- result = xml_template % ('', _('uploading images is limited to users with >60 reputation points'), '')
- except FileTypeNotAllow:
- result = xml_template % ('', _("allowed file types are 'jpg', 'jpeg', 'gif', 'bmp', 'png', 'tiff'"), '')
- except FileSizeNotAllow:
- result = xml_template % ('', _("maximum upload file size is %sK") % settings.ALLOW_MAX_FILE_SIZE / 1024, '')
- except Exception as e:
- result = xml_template % ('', _('Error uploading file. Please contact the site administrator. Thank you. %s' % e), '')
-
- return HttpResponse(result, mimetype="application/xml")
-
-def books(request):
- return HttpResponseRedirect("/books/mysql-zhaoyang")
-
-def book(request, short_name, unanswered=False):
- """
- 1. questions list
- 2. book info
- 3. author info and blog rss items
- """
- """
- List of Questions, Tagged questions, and Unanswered questions.
- """
- books = Book.objects.extra(where=['short_name = %s'], params=[short_name])
- match_count = len(books)
- if match_count == 0 :
- raise Http404
- else:
- # the book info
- book = books[0]
- # get author info
- author_info = BookAuthorInfo.objects.get(book=book)
- # get author rss info
- author_rss = BookAuthorRss.objects.filter(book=book)
-
- # 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:
- page = int(request.GET.get('page', '1'))
- except ValueError:
- page = 1
-
- view_id = request.GET.get('sort', None)
- view_dic = {"latest":"-added_at", "active":"-last_activity_at", "hottest":"-answer_count", "mostvoted":"-score" }
- try:
- orderby = view_dic[view_id]
- except KeyError:
- view_id = "latest"
- orderby = "-added_at"
-
- # check if request is from tagged questions
- if unanswered:
- # check if request is from unanswered questions
- # Article.objects.filter(publications__id__exact=1)
- objects = Question.objects.filter(book__id__exact=book.id, deleted=False, answer_count=0).order_by(orderby)
- else:
- objects = Question.objects.filter(book__id__exact=book.id, deleted=False).order_by(orderby)
-
- # RISK - inner join queries
- objects = objects.select_related();
- objects_list = Paginator(objects, user_page_size)
- questions = objects_list.page(page)
-
- return render_to_response('book.html', {
- "book" : book,
- "author_info" : author_info,
- "author_rss" : author_rss,
- "questions" : questions,
- "context" : {
- 'is_paginated' : True,
- 'pages': objects_list.num_pages,
- 'page': page,
- 'has_previous': questions.has_previous(),
- 'has_next': questions.has_next(),
- 'previous': questions.previous_page_number(),
- 'next': questions.next_page_number(),
- 'base_url' : request.path + '?sort=%s&' % view_id,
- 'pagesize' : user_page_size
- }
- }, context_instance=RequestContext(request))
-
-@login_required
-def ask_book(request, short_name):
- if request.method == "POST":
- form = AskForm(request.POST)
- if form.is_valid():
- added_at = datetime.datetime.now()
- html = sanitize_html(markdowner.convert(form.cleaned_data['text']))
- question = Question(
- title = strip_tags(form.cleaned_data['title']),
- author = request.user,
- added_at = added_at,
- last_activity_at = added_at,
- last_activity_by = request.user,
- wiki = form.cleaned_data['wiki'],
- tagnames = form.cleaned_data['tags'].strip(),
- html = html,
- summary = strip_tags(html)[:120]
- )
- if question.wiki:
- question.last_edited_by = question.author
- question.last_edited_at = added_at
- question.wikified_at = added_at
-
- question.save()
-
- # create the first revision
- QuestionRevision.objects.create(
- question = question,
- revision = 1,
- title = question.title,
- author = request.user,
- revised_at = added_at,
- tagnames = question.tagnames,
- summary = CONST['default_version'],
- text = form.cleaned_data['text']
- )
-
- books = Book.objects.extra(where=['short_name = %s'], params=[short_name])
- match_count = len(books)
- if match_count == 1:
- # the book info
- book = books[0]
- book.questions.add(question)
-
- return HttpResponseRedirect(question.get_absolute_url())
- else:
- form = AskForm()
-
- tags = _get_tags_cache_json()
- return render_to_response('ask.html', {
- 'form' : form,
- 'tags' : tags,
- }, context_instance=RequestContext(request))
-
-def search(request):
- """
- Search by question, user and tag keywords.
- For questions now we only search keywords in question title.
- """
- if request.method == "GET":
- keywords = request.GET.get("q")
- search_type = request.GET.get("t")
- try:
- page = int(request.GET.get('page', '1'))
- except ValueError:
- page = 1
- if keywords is None:
- return HttpResponseRedirect('/')
- if search_type == 'tag':
- return HttpResponseRedirect('/tags/?q=%s&page=%s' % (keywords.strip(), page))
- elif search_type == "user":
- return HttpResponseRedirect('/users/?q=%s&page=%s' % (keywords.strip(), page))
- elif search_type == "question":
-
- template_file = "questions.html"
- # 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:
- 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" }
- try:
- orderby = view_dic[view_id]
- except KeyError:
- view_id = "latest"
- orderby = "-added_at"
-
- objects = Question.objects.filter(deleted=False).extra(where=['title like %s'], params=['%' + keywords + '%']).order_by(orderby)
-
- # RISK - inner join queries
- objects = objects.select_related();
- 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)
-
- return render_to_response(template_file, {
- "questions" : questions,
- "tab_id" : view_id,
- "questions_count" : objects_list.count,
- "tags" : related_tags,
- "searchtag" : None,
- "searchtitle" : keywords,
- "keywords" : keywords,
- "is_unanswered" : False,
- "context" : {
- 'is_paginated' : True,
- 'pages': objects_list.num_pages,
- 'page': page,
- 'has_previous': questions.has_previous(),
- 'has_next': questions.has_next(),
- 'previous': questions.previous_page_number(),
- 'next': questions.next_page_number(),
- 'base_url' : request.path + '?t=question&q=%s&sort=%s&' % (keywords, view_id),
- 'pagesize' : pagesize
- }}, context_instance=RequestContext(request))
-
- else:
- raise Http404
-
+# encoding:utf-8 +import os.path +import time, datetime, calendar, random +import logging +from urllib import quote, unquote +from django.conf import settings +from django.core.files.storage import default_storage +from django.shortcuts import render_to_response, get_object_or_404 +from django.contrib.auth.decorators import login_required +from django.http import HttpResponseRedirect, HttpResponse,Http404 +from django.core.paginator import Paginator, EmptyPage, InvalidPage +from django.template import RequestContext +from django.utils.html import * +from django.utils import simplejson +from django.core import serializers +from django.db import transaction +from django.contrib.contenttypes.models import ContentType +from django.utils.translation import ugettext as _ + +from utils.html import sanitize_html +from markdown2 import Markdown +#from lxml.html.diff import htmldiff +from forum.diff import textDiff as htmldiff +from forum.forms import * +from forum.models import * +from forum.auth import * +from forum.const import * +from forum.user import * +from forum import auth + +# used in index page +INDEX_PAGE_SIZE = 20 +INDEX_AWARD_SIZE = 15 +INDEX_TAGS_SIZE = 100 +# used in tags list +DEFAULT_PAGE_SIZE = 60 +# used in questions +QUESTIONS_PAGE_SIZE = 10 +# used in users +USERS_PAGE_SIZE = 35 +# used in answers +ANSWERS_PAGE_SIZE = 10 +markdowner = Markdown(html4tags=True) +question_type = ContentType.objects.get_for_model(Question) +answer_type = ContentType.objects.get_for_model(Answer) +comment_type = ContentType.objects.get_for_model(Comment) +question_revision_type = ContentType.objects.get_for_model(QuestionRevision) +answer_revision_type = ContentType.objects.get_for_model(AnswerRevision) +repute_type =ContentType.objects.get_for_model(Repute) +question_type_id = question_type.id +answer_type_id = answer_type.id +comment_type_id = comment_type.id +question_revision_type_id = question_revision_type.id +answer_revision_type_id = answer_revision_type.id +repute_type_id = repute_type.id +def _get_tags_cache_json(): + tags = Tag.objects.filter(deleted=False).all() + tags_list = [] + for tag in tags: + dic = {'n': tag.name, 'c': tag.used_count } + tags_list.append(dic) + tags = simplejson.dumps(tags_list) + return tags + +def index(request): + view_id = request.GET.get('sort', None) + view_dic = { + "latest":"-last_activity_at", + "hottest":"-answer_count", + "mostvoted":"-score", + "trans": "-last_activity_at" + } + try: + orderby = view_dic[view_id] + except KeyError: + view_id = "latest" + orderby = "-last_activity_at" + # group questions by author_id of 28,29 + if view_id == 'trans': + questions = Question.objects.get_translation_questions(orderby, INDEX_PAGE_SIZE) + else: + questions = Question.objects.get_questions_by_pagesize(orderby, INDEX_PAGE_SIZE) + # RISK - inner join queries + questions = questions.select_related() + tags = Tag.objects.get_valid_tags(INDEX_TAGS_SIZE) + + awards = Award.objects.get_recent_awards() + + return render_to_response('index.html', { + "questions" : questions, + "tab_id" : view_id, + "tags" : tags, + "awards" : awards[:INDEX_AWARD_SIZE], + }, context_instance=RequestContext(request)) + +def about(request): + return render_to_response('about.html', context_instance=RequestContext(request)) + +def faq(request): + return render_to_response('faq.html', context_instance=RequestContext(request)) + +def privacy(request): + return render_to_response('privacy.html', context_instance=RequestContext(request)) + +def unanswered(request): + return questions(request, unanswered=True) + +def questions(request, tagname=None, unanswered=False): + """ + List of Questions, Tagged questions, and Unanswered questions. + """ + # template file + # "questions.html" or "unanswered.html" + template_file = "questions.html" + # 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 + pagesize = request.session.get("pagesize") + try: + page = int(request.GET.get('page', '1')) + except ValueError: + page = 1 + + view_id = request.GET.get('sort', None) + view_dic = {"latest":"-added_at", "active":"-last_activity_at", "hottest":"-answer_count", "mostvoted":"-score" } + try: + orderby = view_dic[view_id] + except KeyError: + view_id = "latest" + orderby = "-added_at" + + # check if request is from tagged questions + if tagname is not None: + 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.get_unanswered_questions(orderby) + else: + objects = Question.objects.get_questions(orderby) + + # RISK - inner join queries + objects = objects.select_related(depth=1); + objects_list = Paginator(objects, pagesize) + questions = objects_list.page(page) + + # Get related tags from this page objects + 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, + "questions_count" : objects_list.count, + "tags" : related_tags, + "searchtag" : tagname, + "is_unanswered" : unanswered, + "context" : { + 'is_paginated' : True, + 'pages': objects_list.num_pages, + 'page': page, + 'has_previous': questions.has_previous(), + 'has_next': questions.has_next(), + 'previous': questions.previous_page_number(), + 'next': questions.next_page_number(), + 'base_url' : request.path + '?sort=%s&' % view_id, + 'pagesize' : pagesize + }}, context_instance=RequestContext(request)) + +#TODO: allow anynomus user to ask question by providing email and username. +@login_required +def ask(request): + if request.method == "POST": + form = AskForm(request.POST) + if form.is_valid(): + added_at = datetime.datetime.now() + html = sanitize_html(markdowner.convert(form.cleaned_data['text'])) + question = Question( + title = strip_tags(form.cleaned_data['title']), + author = request.user, + added_at = added_at, + last_activity_at = added_at, + last_activity_by = request.user, + wiki = form.cleaned_data['wiki'], + tagnames = form.cleaned_data['tags'].strip(), + html = html, + summary = strip_tags(html)[:120] + ) + if question.wiki: + question.last_edited_by = question.author + question.last_edited_at = added_at + question.wikified_at = added_at + + question.save() + + # create the first revision + QuestionRevision.objects.create( + question = question, + revision = 1, + title = question.title, + author = request.user, + revised_at = added_at, + tagnames = question.tagnames, + summary = CONST['default_version'], + text = form.cleaned_data['text'] + ) + + return HttpResponseRedirect(question.get_absolute_url()) + + else: + form = AskForm() + + tags = _get_tags_cache_json() + return render_to_response('ask.html', { + 'form' : form, + 'tags' : tags, + }, context_instance=RequestContext(request)) + +def question(request, id): + try: + page = int(request.GET.get('page', '1')) + except ValueError: + page = 1 + view_id = request.GET.get('sort', 'votes') + view_dic = {"latest":"-added_at", "oldest":"added_at", "votes":"-score" } + try: + orderby = view_dic[view_id] + except KeyError: + view_id = "votes" + orderby = "-score" + + question = get_object_or_404(Question, id=id) + if question.deleted and not can_view_deleted_post(request.user, question): + raise Http404 + answer_form = AnswerForm(question) + answers = Answer.objects.get_answers_from_question(question, request.user) + answers = answers.select_related(depth=1) + + favorited = question.has_favorite_by_user(request.user) + question_vote = question.votes.select_related().filter(user=request.user) + if question_vote is not None and question_vote.count() > 0: + question_vote = question_vote[0] + + user_answer_votes = {} + for answer in answers: + vote = answer.get_user_vote(request.user) + if vote is not None and not user_answer_votes.has_key(answer.id): + vote_value = -1 + if vote.is_upvote(): + vote_value = 1 + user_answer_votes[answer.id] = vote_value + + + if answers is not None: + answers = answers.order_by("-accepted", orderby) + objects_list = Paginator(answers, ANSWERS_PAGE_SIZE) + page_objects = objects_list.page(page) + # update view count + Question.objects.update_view_count(question) + return render_to_response('question.html', { + "question" : question, + "question_vote" : question_vote, + "question_comment_count":question.comments.count(), + "answer" : answer_form, + "answers" : page_objects.object_list, + "user_answer_votes": user_answer_votes, + "tags" : question.tags.all(), + "tab_id" : view_id, + "favorited" : favorited, + "similar_questions" : Question.objects.get_similar_questions(question), + "context" : { + 'is_paginated' : True, + 'pages': objects_list.num_pages, + 'page': page, + 'has_previous': page_objects.has_previous(), + 'has_next': page_objects.has_next(), + 'previous': page_objects.previous_page_number(), + 'next': page_objects.next_page_number(), + 'base_url' : request.path + '?sort=%s&' % view_id, + 'extend_url' : "#sort-top" + } + }, context_instance=RequestContext(request)) + +@login_required +def close(request, id): + question = get_object_or_404(Question, id=id) + if not can_close_question(request.user, question): + return HttpResponse('Permission denied.') + if request.method == 'POST': + form = CloseForm(request.POST) + if form.is_valid(): + reason = form.cleaned_data['reason'] + question.closed = True + question.closed_by = request.user + question.closed_at = datetime.datetime.now() + question.close_reason = reason + question.save() + return HttpResponseRedirect(question.get_absolute_url()) + else: + form = CloseForm() + return render_to_response('close.html', { + 'form' : form, + 'question' : question, + }, context_instance=RequestContext(request)) + +@login_required +def reopen(request, id): + question = get_object_or_404(Question, id=id) + # open question + if not can_reopen_question(request.user, question): + return HttpResponse('Permission denied.') + if request.method == 'POST' : + Question.objects.filter(id=question.id).update(closed=False, + closed_by=None, closed_at=None, close_reason=None) + return HttpResponseRedirect(question.get_absolute_url()) + else: + return render_to_response('reopen.html', { + 'question' : question, + }, context_instance=RequestContext(request)) + +@login_required +def edit_question(request, id): + question = get_object_or_404(Question, id=id) + if question.deleted and not can_view_deleted_post(request.user, question): + raise Http404 + if can_edit_post(request.user, question): + return _edit_question(request, question) + elif can_retag_questions(request.user): + return _retag_question(request, question) + else: + raise Http404 + +def _retag_question(request, question): + if request.method == 'POST': + form = RetagQuestionForm(question, request.POST) + if form.is_valid(): + if form.has_changed(): + latest_revision = question.get_latest_revision() + retagged_at = datetime.datetime.now() + # Update the Question itself + Question.objects.filter(id=question.id).update( + tagnames = form.cleaned_data['tags'], + last_edited_at = retagged_at, + last_edited_by = request.user, + last_activity_at = retagged_at, + last_activity_by = request.user + ) + # Update the Question's tag associations + tags_updated = Question.objects.update_tags(question, + form.cleaned_data['tags'], request.user) + # Create a new revision + QuestionRevision.objects.create( + question = question, + title = latest_revision.title, + author = request.user, + revised_at = retagged_at, + tagnames = form.cleaned_data['tags'], + summary = CONST['retagged'], + text = latest_revision.text + ) + # send tags updated singal + tags_updated.send(sender=question.__class__, question=question) + + return HttpResponseRedirect(question.get_absolute_url()) + else: + form = RetagQuestionForm(question) + return render_to_response('question_retag.html', { + 'question': question, + 'form' : form, + 'tags' : _get_tags_cache_json(), + }, context_instance=RequestContext(request)) + + +def _edit_question(request, question): + latest_revision = question.get_latest_revision() + revision_form = None + if request.method == 'POST': + if 'select_revision' in request.POST: + # user has changed revistion number + revision_form = RevisionForm(question, latest_revision, request.POST) + if revision_form.is_valid(): + # Replace with those from the selected revision + form = EditQuestionForm(question, + QuestionRevision.objects.get(question=question, + revision=revision_form.cleaned_data['revision'])) + else: + form = EditQuestionForm(question, latest_revision, request.POST) + else: + # Always check modifications against the latest revision + form = EditQuestionForm(question, latest_revision, request.POST) + if form.is_valid(): + html = sanitize_html(markdowner.convert(form.cleaned_data['text'])) + if form.has_changed(): + edited_at = datetime.datetime.now() + tags_changed = (latest_revision.tagnames != + form.cleaned_data['tags']) + tags_updated = False + # Update the Question itself + updated_fields = { + 'title': form.cleaned_data['title'], + 'last_edited_at': edited_at, + 'last_edited_by': request.user, + 'last_activity_at': edited_at, + 'last_activity_by': request.user, + 'tagnames': form.cleaned_data['tags'], + 'summary': strip_tags(html)[:120], + 'html': html, + } + + # only save when it's checked + # because wiki doesn't allow to be edited if last version has been enabled already + # and we make sure this in forms. + if ('wiki' in form.cleaned_data and + form.cleaned_data['wiki']): + updated_fields['wiki'] = True + updated_fields['wikified_at'] = edited_at + + Question.objects.filter( + id=question.id).update(**updated_fields) + # Update the Question's tag associations + if tags_changed: + tags_updated = Question.objects.update_tags( + question, form.cleaned_data['tags'], request.user) + # Create a new revision + revision = QuestionRevision( + question = question, + title = form.cleaned_data['title'], + author = request.user, + revised_at = edited_at, + tagnames = form.cleaned_data['tags'], + text = form.cleaned_data['text'], + ) + if form.cleaned_data['summary']: + revision.summary = form.cleaned_data['summary'] + else: + revision.summary = 'No.%s Revision' % latest_revision.revision + revision.save() + + return HttpResponseRedirect(question.get_absolute_url()) + else: + + revision_form = RevisionForm(question, latest_revision) + form = EditQuestionForm(question, latest_revision) + return render_to_response('question_edit.html', { + 'question': question, + 'revision_form': revision_form, + 'form' : form, + 'tags' : _get_tags_cache_json() + }, context_instance=RequestContext(request)) + + +@login_required +def edit_answer(request, id): + answer = get_object_or_404(Answer, id=id) + if answer.deleted and not can_view_deleted_post(request.user, answer): + raise Http404 + elif not can_edit_post(request.user, answer): + raise Http404 + else: + latest_revision = answer.get_latest_revision() + if request.method == "POST": + if 'select_revision' in request.POST: + # user has changed revistion number + revision_form = RevisionForm(answer, latest_revision, request.POST) + if revision_form.is_valid(): + # Replace with those from the selected revision + form = EditAnswerForm(answer, + AnswerRevision.objects.get(answer=answer, + revision=revision_form.cleaned_data['revision'])) + else: + form = EditAnswerForm(answer, latest_revision, request.POST) + else: + form = EditAnswerForm(answer, latest_revision, request.POST) + if form.is_valid(): + html = sanitize_html(markdowner.convert(form.cleaned_data['text'])) + if form.has_changed(): + edited_at = datetime.datetime.now() + updated_fields = { + 'last_edited_at': edited_at, + 'last_edited_by': request.user, + 'html': html, + } + Answer.objects.filter(id=answer.id).update(**updated_fields) + + revision = AnswerRevision( + answer = answer, + author = request.user, + revised_at = edited_at, + text = form.cleaned_data['text'] + ) + + if form.cleaned_data['summary']: + revision.summary = form.cleaned_data['summary'] + else: + revision.summary = 'No.%s Revision' % latest_revision.revision + revision.save() + + answer.question.last_activity_at = edited_at + answer.question.last_activity_by = request.user + answer.question.save() + + return HttpResponseRedirect(answer.get_absolute_url()) + else: + revision_form = RevisionForm(answer, latest_revision) + form = EditAnswerForm(answer, latest_revision) + return render_to_response('answer_edit.html', { + 'answer': answer, + 'revision_form': revision_form, + 'form' : form, + }, context_instance=RequestContext(request)) + +QUESTION_REVISION_TEMPLATE = ('<h1>%(title)s</h1>\n' + '<div class="text">%(html)s</div>\n' + '<div class="tags">%(tags)s</div>') +def question_revisions(request, id): + post = get_object_or_404(Question, id=id) + revisions = list(post.revisions.all()) + for i, revision in enumerate(revisions): + revision.html = QUESTION_REVISION_TEMPLATE % { + 'title': revision.title, + 'html': sanitize_html(markdowner.convert(revision.text)), + 'tags': ' '.join(['<a class="post-tag">%s</a>' % tag + for tag in revision.tagnames.split(' ')]), + } + if i > 0: + revisions[i - 1].diff = htmldiff(revision.html, + revisions[i - 1].html) + else: + revisions[i - 1].diff = QUESTION_REVISION_TEMPLATE % { + 'title': revisions[0].title, + 'html': sanitize_html(markdowner.convert(revisions[0].text)), + 'tags': ' '.join(['<a class="post-tag">%s</a>' % tag + for tag in revisions[0].tagnames.split(' ')]), + } + revisions[i - 1].summary = None + return render_to_response('revisions_question.html', { + 'post': post, + 'revisions': revisions, + }, context_instance=RequestContext(request)) + +ANSWER_REVISION_TEMPLATE = ('<div class="text">%(html)s</div>') +def answer_revisions(request, id): + post = get_object_or_404(Answer, id=id) + revisions = list(post.revisions.all()) + for i, revision in enumerate(revisions): + revision.html = ANSWER_REVISION_TEMPLATE % { + 'html': sanitize_html(markdowner.convert(revision.text)) + } + if i > 0: + revisions[i - 1].diff = htmldiff(revision.html, + revisions[i - 1].html) + else: + revisions[i - 1].diff = revisions[i-1].text + revisions[i - 1].summary = None + return render_to_response('revisions_answer.html', { + 'post': post, + 'revisions': revisions, + }, context_instance=RequestContext(request)) + +#TODO: allow anynomus +@login_required +def answer(request, id): + question = get_object_or_404(Question, id=id) + if request.method == "POST": + form = AnswerForm(question, request.POST) + if form.is_valid(): + update_time = datetime.datetime.now() + answer = Answer( + question = question, + author = request.user, + added_at = update_time, + wiki = form.cleaned_data['wiki'], + html = sanitize_html(markdowner.convert(form.cleaned_data['text'])), + ) + if answer.wiki: + answer.last_edited_by = answer.author + answer.last_edited_at = update_time + answer.wikified_at = update_time + + answer.save() + Question.objects.update_answer_count(question) + + question = get_object_or_404(Question, id=id) + question.last_activity_at = update_time + question.last_activity_by = request.user + question.save() + + AnswerRevision.objects.create( + answer = answer, + revision = 1, + author = request.user, + revised_at = update_time, + summary = CONST['default_version'], + text = form.cleaned_data['text'] + ) + + return HttpResponseRedirect(question.get_absolute_url()) + +def tags(request): + stag = "" + is_paginated = True + sortby = request.GET.get('sort', 'used') + try: + page = int(request.GET.get('page', '1')) + except ValueError: + page = 1 + + if request.method == "GET": + stag = request.GET.get("q", "").strip() + if stag is not None: + objects_list = Paginator(Tag.objects.filter(deleted=False).exclude(used_count=0).extra(where=['name like %s'], params=['%' + stag + '%']), DEFAULT_PAGE_SIZE) + else: + if sortby == "name": + objects_list = Paginator(Tag.objects.all().filter(deleted=False).exclude(used_count=0).order_by("name"), DEFAULT_PAGE_SIZE) + else: + objects_list = Paginator(Tag.objects.all().filter(deleted=False).exclude(used_count=0).order_by("-used_count"), DEFAULT_PAGE_SIZE) + + try: + tags = objects_list.page(page) + except (EmptyPage, InvalidPage): + tags = objects_list.page(objects_list.num_pages) + + return render_to_response('tags.html', { + "tags" : tags, + "stag" : stag, + "tab_id" : sortby, + "keywords" : stag, + "context" : { + 'is_paginated' : is_paginated, + 'pages': objects_list.num_pages, + 'page': page, + 'has_previous': tags.has_previous(), + 'has_next': tags.has_next(), + 'previous': tags.previous_page_number(), + 'next': tags.next_page_number(), + 'base_url' : '/tags/?sort=%s&' % sortby + } + + }, context_instance=RequestContext(request)) + +def tag(request, tag): + return questions(request, tagname=tag) + +def vote(request, id): + """ + vote_type: + acceptAnswer : 0, + questionUpVote : 1, + questionDownVote : 2, + favorite : 4, + answerUpVote: 5, + answerDownVote:6, + offensiveQuestion : 7, + offensiveAnswer:8, + removeQuestion: 9, + removeAnswer:10 + + accept answer code: + response_data['allowed'] = -1, Accept his own answer 0, no allowed - Anonymous 1, Allowed - by default + response_data['success'] = 0, failed 1, Success - by default + response_data['status'] = 0, By default 1, Answer has been accepted already(Cancel) + + vote code: + allowed = -3, Don't have enough votes left + -2, Don't have enough reputation score + -1, Vote his own post + 0, no allowed - Anonymous + 1, Allowed - by default + status = 0, By default + 1, Cancel + 2, Vote is too old to be canceled + + offensive code: + allowed = -3, Don't have enough flags left + -2, Don't have enough reputation score to do this + 0, not allowed + 1, allowed + status = 0, by default + 1, can't do it again + """ + response_data = { + "allowed": 1, + "success": 1, + "status" : 0, + "count" : 0, + "message" : '' + } + + def can_vote(vote_score, user): + if vote_score == 1: + return can_vote_up(request.user) + else: + return can_vote_down(request.user) + + try: + if not request.user.is_authenticated(): + response_data['allowed'] = 0 + response_data['success'] = 0 + + elif request.is_ajax(): + question = get_object_or_404(Question, id=id) + vote_type = request.POST.get('type') + + #accept answer + if vote_type == '0': + answer_id = request.POST.get('postId') + answer = get_object_or_404(Answer, id=answer_id) + # make sure question author is current user + if question.author == request.user: + # answer user who is also question author is not allow to accept answer + if answer.author == question.author: + response_data['success'] = 0 + response_data['allowed'] = -1 + # check if answer has been accepted already + elif answer.accepted: + onAnswerAcceptCanceled(answer, request.user) + response_data['status'] = 1 + else: + # set other answers in this question not accepted first + for answer_of_question in Answer.objects.get_answers_from_question(question, request.user): + if answer_of_question != answer and answer_of_question.accepted: + onAnswerAcceptCanceled(answer_of_question, request.user) + + #make sure retrieve data again after above author changes, they may have related data + answer = get_object_or_404(Answer, id=answer_id) + onAnswerAccept(answer, request.user) + else: + response_data['allowed'] = 0 + response_data['success'] = 0 + # favorite + elif vote_type == '4': + has_favorited = False + fav_questions = FavoriteQuestion.objects.filter(question=question) + # if the same question has been favorited before, then delete it + if fav_questions is not None: + for item in fav_questions: + if item.user == request.user: + item.delete() + response_data['status'] = 1 + response_data['count'] = len(fav_questions) - 1 + if response_data['count'] < 0: + response_data['count'] = 0 + has_favorited = True + # if above deletion has not been executed, just insert a new favorite question + if not has_favorited: + new_item = FavoriteQuestion(question=question, user=request.user) + new_item.save() + response_data['count'] = FavoriteQuestion.objects.filter(question=question).count() + Question.objects.update_favorite_count(question) + + elif vote_type in ['1', '2', '5', '6']: + post_id = id + post = question + vote_score = 1 + if vote_type in ['5', '6']: + answer_id = request.POST.get('postId') + answer = get_object_or_404(Answer, id=answer_id) + post_id = answer_id + post = answer + if vote_type in ['2', '6']: + vote_score = -1 + + if post.author == request.user: + response_data['allowed'] = -1 + elif not can_vote(vote_score, request.user): + response_data['allowed'] = -2 + elif post.votes.filter(user=request.user).count() > 0: + vote = post.votes.filter(user=request.user)[0] + # unvote should be less than certain time + if (datetime.datetime.now().day - vote.voted_at.day) >= VOTE_RULES['scope_deny_unvote_days']: + response_data['status'] = 2 + else: + voted = vote.vote + if voted > 0: + # cancel upvote + onUpVotedCanceled(vote, post, request.user) + + else: + # cancel downvote + onDownVotedCanceled(vote, post, request.user) + + response_data['status'] = 1 + response_data['count'] = post.score + elif Vote.objects.get_votes_count_today_from_user(request.user) >= VOTE_RULES['scope_votes_per_user_per_day']: + response_data['allowed'] = -3 + else: + vote = Vote(user=request.user, content_object=post, vote=vote_score, voted_at=datetime.datetime.now()) + if vote_score > 0: + # upvote + onUpVoted(vote, post, request.user) + else: + # downvote + onDownVoted(vote, post, request.user) + + votes_left = VOTE_RULES['scope_votes_per_user_per_day'] - Vote.objects.get_votes_count_today_from_user(request.user) + if votes_left <= VOTE_RULES['scope_warn_votes_left']: + response_data['message'] = u'%s votes left' % votes_left + response_data['count'] = post.score + elif vote_type in ['7', '8']: + post = question + post_id = id + if vote_type == '8': + post_id = request.POST.get('postId') + post = get_object_or_404(Answer, id=post_id) + + if FlaggedItem.objects.get_flagged_items_count_today(request.user) >= VOTE_RULES['scope_flags_per_user_per_day']: + response_data['allowed'] = -3 + elif not can_flag_offensive(request.user): + response_data['allowed'] = -2 + elif post.flagged_items.filter(user=request.user).count() > 0: + response_data['status'] = 1 + else: + item = FlaggedItem(user=request.user, content_object=post, flagged_at=datetime.datetime.now()) + onFlaggedItem(item, post, request.user) + response_data['count'] = post.offensive_flag_count + # send signal when question or answer be marked offensive + mark_offensive.send(sender=post.__class__, instance=post, mark_by=request.user) + elif vote_type in ['9', '10']: + post = question + post_id = id + if vote_type == '10': + post_id = request.POST.get('postId') + post = get_object_or_404(Answer, id=post_id) + + if not can_delete_post(request.user, post): + response_data['allowed'] = -2 + elif post.deleted: + onDeleteCanceled(post, request.user) + response_data['status'] = 1 + else: + onDeleted(post, request.user) + delete_post_or_answer.send(sender=post.__class__, instance=post, delete_by=request.user) + else: + response_data['success'] = 0 + response_data['message'] = u'Request mode is not supported. Please try again.' + + data = simplejson.dumps(response_data) + + except Exception, e: + response_data['message'] = str(e) + data = simplejson.dumps(response_data) + return HttpResponse(data, mimetype="application/json") + +def users(request): + is_paginated = True + sortby = request.GET.get('sort', 'reputation') + suser = request.REQUEST.get('q', "") + try: + page = int(request.GET.get('page', '1')) + except ValueError: + page = 1 + + if suser == "": + if sortby == "newest": + objects_list = Paginator(User.objects.all().order_by('-date_joined'), USERS_PAGE_SIZE) + elif sortby == "last": + objects_list = Paginator(User.objects.all().order_by('date_joined'), USERS_PAGE_SIZE) + elif sortby == "user": + objects_list = Paginator(User.objects.all().order_by('username'), USERS_PAGE_SIZE) + # default + else: + objects_list = Paginator(User.objects.all().order_by('-reputation'), USERS_PAGE_SIZE) + base_url = '/users/?sort=%s&' % sortby + else: + sortby = "reputation" + objects_list = Paginator(User.objects.extra(where=['username like %s'], params=['%' + suser + '%']).order_by('-reputation'), USERS_PAGE_SIZE) + base_url = '/users/?name=%s&sort=%s&' % (suser, sortby) + + try: + users = objects_list.page(page) + except (EmptyPage, InvalidPage): + users = objects_list.page(objects_list.num_pages) + + return render_to_response('users.html', { + "users" : users, + "suser" : suser, + "keywords" : suser, + "tab_id" : sortby, + "context" : { + 'is_paginated' : is_paginated, + 'pages': objects_list.num_pages, + 'page': page, + 'has_previous': users.has_previous(), + 'has_next': users.has_next(), + 'previous': users.previous_page_number(), + 'next': users.next_page_number(), + 'base_url' : base_url + } + + }, context_instance=RequestContext(request)) + +def user(request, id): + sort = request.GET.get('sort', 'stats') + user_view = dict((v.id, v) for v in USER_TEMPLATE_VIEWS).get(sort, USER_TEMPLATE_VIEWS[0]) + from forum import views + func = getattr(views, user_view.view_name) + return func(request, id, user_view) + +@login_required +def edit_user(request, id): + user = get_object_or_404(User, id=id) + if request.user != user: + raise Http404 + if request.method == "POST": + form = EditUserForm(user, request.POST) + if form.is_valid(): + user.email = sanitize_html(form.cleaned_data['email']) + user.real_name = sanitize_html(form.cleaned_data['realname']) + user.website = sanitize_html(form.cleaned_data['website']) + user.location = sanitize_html(form.cleaned_data['city']) + user.date_of_birth = sanitize_html(form.cleaned_data['birthday']) + if len(user.date_of_birth) == 0: + user.date_of_birth = '1900-01-01' + user.about = sanitize_html(form.cleaned_data['about']) + + user.save() + # send user updated singal if full fields have been updated + if user.email and user.real_name and user.website and user.location and \ + user.date_of_birth and user.about: + user_updated.send(sender=user.__class__, instance=user, updated_by=user) + return HttpResponseRedirect(user.get_profile_url()) + else: + form = EditUserForm(user) + return render_to_response('user_edit.html', { + 'form' : form, + }, context_instance=RequestContext(request)) + +def user_stats(request, user_id, user_view): + user = get_object_or_404(User, id=user_id) + questions = Question.objects.extra( + select={ + 'vote_count' : 'question.score', + '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', + 'la_user_silver' : 'auth_user.silver', + 'la_user_bronze' : 'auth_user.bronze', + 'la_user_reputation' : 'auth_user.reputation' + }, + select_params=[user_id], + tables=['question', 'auth_user'], + where=['question.deleted = 0 AND question.author_id=%s AND question.last_activity_by_id = auth_user.id'], + params=[user_id], + order_by=['-vote_count', '-last_activity_at'] + ).values('vote_count', + 'favorited_myself', + 'id', + 'title', + 'author_id', + 'added_at', + 'answer_accepted', + 'answer_count', + 'comment_count', + 'view_count', + 'favourite_count', + 'summary', + 'tagnames', + 'vote_up_count', + 'vote_down_count', + 'last_activity_at', + 'la_user_id', + 'la_username', + 'la_user_gold', + 'la_user_silver', + 'la_user_bronze', + 'la_user_reputation')[:100] + + answered_questions = Question.objects.extra( + select={ + 'vote_up_count' : 'answer.vote_up_count', + 'vote_down_count' : 'answer.vote_down_count', + 'answer_id' : 'answer.id', + 'accepted' : 'answer.accepted', + 'vote_count' : 'answer.score', + 'comment_count' : 'answer.comment_count' + }, + tables=['question', 'answer'], + where=['answer.deleted=0 AND answer.author_id=%s AND answer.question_id=question.id'], + params=[user_id], + order_by=['-vote_count', '-answer_id'], + select_params=[user_id] + ).distinct().values('comment_count', + 'id', + 'answer_id', + 'title', + 'author_id', + 'accepted', + 'vote_count', + 'answer_count', + 'vote_up_count', + 'vote_down_count')[:100] + up_votes = Vote.objects.get_up_vote_count_from_user(user) + down_votes = Vote.objects.get_down_vote_count_from_user(user) + votes_today = Vote.objects.get_votes_count_today_from_user(user) + votes_total = VOTE_RULES['scope_votes_per_user_per_day'] + tags = user.created_tags.all().order_by('-used_count')[:50] + awards = Award.objects.extra( + select={'id': 'badge.id', 'count': 'count(badge_id)', 'name':'badge.name', 'description': 'badge.description', 'type': 'badge.type'}, + tables=['award', 'badge'], + order_by=['-awarded_at'], + where=['user_id=%s AND badge_id=badge.id'], + params=[user.id] + ).values('id', 'count', 'name', 'description', 'type') + total_awards = awards.count() + awards.query.group_by = ['badge_id'] + + return render_to_response(user_view.template_file,{ + "tab_name" : user_view.id, + "tab_description" : user_view.tab_description, + "page_title" : user_view.page_title, + "view_user" : user, + "questions" : questions, + "answered_questions" : answered_questions, + "up_votes" : up_votes, + "down_votes" : down_votes, + "total_votes": up_votes + down_votes, + "votes_today_left": votes_total-votes_today, + "votes_total_per_day": votes_total, + "tags" : tags, + "awards": awards, + "total_awards" : total_awards, + }, context_instance=RequestContext(request)) + +def user_recent(request, user_id, user_view): + user = get_object_or_404(User, id=user_id) + def get_type_name(type_id): + for item in TYPE_ACTIVITY: + if type_id in item: + return item[1] + + class Event: + def __init__(self, time, type, title, summary, answer_id, question_id): + self.time = time + self.type = get_type_name(type) + self.type_id = type + self.title = title + self.summary = summary + self.title_link = u'/questions/%s/%s#%s' %(question_id, title, answer_id)\ + if int(answer_id) > 0 else u'/questions/%s/%s' %(question_id, title) + class AwardEvent: + def __init__(self, time, type, id): + self.time = time + self.type = get_type_name(type) + self.type_id = type + self.badge = get_object_or_404(Badge, id=id) + + activities = [] + # ask questions + questions = Activity.objects.extra( + select={ + 'title' : 'question.title', + 'question_id' : 'question.id', + 'active_at' : 'activity.active_at', + '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'], + params=[question_type_id, user_id, TYPE_ACTIVITY_ASK_QUESTION], + order_by=['-activity.active_at'] + ).values( + 'title', + 'question_id', + 'active_at', + 'activity_type' + ) + if len(questions) > 0: + questions = [(Event(q['active_at'], q['activity_type'], q['title'], '', '0', \ + q['question_id'])) for q in questions] + activities.extend(questions) + + # answers + answers = Activity.objects.extra( + select={ + 'title' : 'question.title', + 'question_id' : 'question.id', + 'answer_id' : 'answer.id', + 'active_at' : 'activity.active_at', + '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'], + params=[answer_type_id, user_id, TYPE_ACTIVITY_ANSWER], + order_by=['-activity.active_at'] + ).values( + 'title', + 'question_id', + 'answer_id', + 'active_at', + 'activity_type' + ) + if len(answers) > 0: + answers = [(Event(q['active_at'], q['activity_type'], q['title'], '', q['answer_id'], \ + q['question_id'])) for q in answers] + activities.extend(answers) + + # question comments + comments = Activity.objects.extra( + select={ + 'title' : 'question.title', + 'question_id' : 'comment.object_id', + 'added_at' : 'comment.added_at', + 'activity_type' : 'activity.activity_type' + }, + 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'], + params=[comment_type_id, question_type_id, user_id, TYPE_ACTIVITY_COMMENT_QUESTION], + order_by=['-comment.added_at'] + ).values( + 'title', + 'question_id', + 'added_at', + 'activity_type' + ) + + if len(comments) > 0: + comments = [(Event(q['added_at'], q['activity_type'], q['title'], '', '0', \ + q['question_id'])) for q in comments] + activities.extend(comments) + + # answer comments + comments = Activity.objects.extra( + select={ + 'title' : 'question.title', + 'question_id' : 'question.id', + 'answer_id' : 'answer.id', + 'added_at' : 'comment.added_at', + 'activity_type' : 'activity.activity_type' + }, + 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'], + params=[comment_type_id, answer_type_id, user_id, TYPE_ACTIVITY_COMMENT_ANSWER], + order_by=['-comment.added_at'] + ).values( + 'title', + 'question_id', + 'answer_id', + 'added_at', + 'activity_type' + ) + + if len(comments) > 0: + comments = [(Event(q['added_at'], q['activity_type'], q['title'], '', q['answer_id'], \ + q['question_id'])) for q in comments] + activities.extend(comments) + + # question revisions + revisions = Activity.objects.extra( + select={ + 'title' : 'question_revision.title', + 'question_id' : 'question_revision.question_id', + 'added_at' : 'activity.active_at', + 'activity_type' : 'activity.activity_type', + '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'], + params=[question_revision_type_id, user_id, TYPE_ACTIVITY_UPDATE_QUESTION], + order_by=['-activity.active_at'] + ).values( + 'title', + 'question_id', + 'added_at', + 'activity_type', + 'summary' + ) + + if len(revisions) > 0: + revisions = [(Event(q['added_at'], q['activity_type'], q['title'], q['summary'], '0', \ + q['question_id'])) for q in revisions] + activities.extend(revisions) + + # answer revisions + revisions = Activity.objects.extra( + select={ + 'title' : 'question.title', + 'question_id' : 'question.id', + 'answer_id' : 'answer.id', + 'added_at' : 'activity.active_at', + 'activity_type' : 'activity.activity_type', + 'summary' : 'answer_revision.summary' + }, + 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'], + params=[answer_revision_type_id, user_id, TYPE_ACTIVITY_UPDATE_ANSWER], + order_by=['-activity.active_at'] + ).values( + 'title', + 'question_id', + 'added_at', + 'answer_id', + 'activity_type', + 'summary' + ) + + if len(revisions) > 0: + revisions = [(Event(q['added_at'], q['activity_type'], q['title'], q['summary'], \ + q['answer_id'], q['question_id'])) for q in revisions] + activities.extend(revisions) + + # accepted answers + accept_answers = Activity.objects.extra( + select={ + 'title' : 'question.title', + 'question_id' : 'question.id', + 'added_at' : 'activity.active_at', + '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'], + params=[answer_type_id, user_id, TYPE_ACTIVITY_MARK_ANSWER], + order_by=['-activity.active_at'] + ).values( + 'title', + 'question_id', + 'added_at', + 'activity_type', + ) + if len(accept_answers) > 0: + accept_answers = [(Event(q['added_at'], q['activity_type'], q['title'], '', '0', \ + q['question_id'])) for q in accept_answers] + activities.extend(accept_answers) + #award history + awards = Activity.objects.extra( + select={ + 'badge_id' : 'badge.id', + 'awarded_at': 'award.awarded_at', + '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'], + params=[user_id, TYPE_ACTIVITY_PRIZE], + order_by=['-activity.active_at'] + ).values( + 'badge_id', + 'awarded_at', + 'activity_type' + ) + if len(awards) > 0: + awards = [(AwardEvent(q['awarded_at'], q['activity_type'], q['badge_id'])) for q in awards] + activities.extend(awards) + + activities.sort(lambda x,y: cmp(y.time, x.time)) + + return render_to_response(user_view.template_file,{ + "tab_name" : user_view.id, + "tab_description" : user_view.tab_description, + "page_title" : user_view.page_title, + "view_user" : user, + "activities" : activities[:user_view.data_size] + }, context_instance=RequestContext(request)) + +def user_responses(request, user_id, user_view): + """ + We list answers for question, comments, and answer accepted by others for this user. + """ + class Response: + def __init__(self, type, title, question_id, answer_id, time, username, user_id, content): + self.type = type + self.title = title + self.titlelink = u'/questions/%s/%s#%s' % (question_id, title, answer_id) + self.time = time + self.userlink = u'/users/%s/%s/' % (user_id, username) + self.username = username + self.content = u'%s ...' % strip_tags(content)[:300] + + def __unicode__(self): + return u'%s %s' % (self.type, self.titlelink) + + user = get_object_or_404(User, id=user_id) + responses = [] + answers = Answer.objects.extra( + select={ + 'title' : 'question.title', + 'question_id' : 'question.id', + 'answer_id' : 'answer.id', + 'added_at' : 'answer.added_at', + 'html' : 'answer.html', + 'username' : 'auth_user.username', + 'user_id' : 'auth_user.id' + }, + 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'], + params=[user_id, user_id], + order_by=['-answer.id'] + ).values( + 'title', + 'question_id', + 'answer_id', + 'added_at', + 'html', + 'username', + 'user_id' + ) + if len(answers) > 0: + answers = [(Response(TYPE_RESPONSE['QUESTION_ANSWERED'], a['title'], a['question_id'], + a['answer_id'], a['added_at'], a['username'], a['user_id'], a['html'])) for a in answers] + responses.extend(answers) + + + # question comments + comments = Comment.objects.extra( + select={ + 'title' : 'question.title', + 'question_id' : 'comment.object_id', + 'added_at' : 'comment.added_at', + 'comment' : 'comment.comment', + 'username' : 'auth_user.username', + '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'], + params=[user_id, question_type_id, user_id], + order_by=['-comment.added_at'] + ).values( + 'title', + 'question_id', + 'added_at', + 'comment', + 'username', + 'user_id' + ) + + if len(comments) > 0: + comments = [(Response(TYPE_RESPONSE['QUESTION_COMMENTED'], c['title'], c['question_id'], + '', c['added_at'], c['username'], c['user_id'], c['comment'])) for c in comments] + responses.extend(comments) + + # answer comments + comments = Comment.objects.extra( + select={ + 'title' : 'question.title', + 'question_id' : 'question.id', + 'answer_id' : 'answer.id', + 'added_at' : 'comment.added_at', + 'comment' : 'comment.comment', + 'username' : 'auth_user.username', + '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'], + params=[user_id, answer_type_id, user_id], + order_by=['-comment.added_at'] + ).values( + 'title', + 'question_id', + 'answer_id', + 'added_at', + 'comment', + 'username', + 'user_id' + ) + + if len(comments) > 0: + comments = [(Response(TYPE_RESPONSE['ANSWER_COMMENTED'], c['title'], c['question_id'], + c['answer_id'], c['added_at'], c['username'], c['user_id'], c['comment'])) for c in comments] + responses.extend(comments) + + # answer has been accepted + answers = Answer.objects.extra( + select={ + 'title' : 'question.title', + 'question_id' : 'question.id', + 'answer_id' : 'answer.id', + 'added_at' : 'answer.accepted_at', + 'html' : 'answer.html', + 'username' : 'auth_user.username', + 'user_id' : 'auth_user.id' + }, + 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'], + params=[user_id], + order_by=['-answer.id'] + ).values( + 'title', + 'question_id', + 'answer_id', + 'added_at', + 'html', + 'username', + 'user_id' + ) + if len(answers) > 0: + answers = [(Response(TYPE_RESPONSE['ANSWER_ACCEPTED'], a['title'], a['question_id'], + a['answer_id'], a['added_at'], a['username'], a['user_id'], a['html'])) for a in answers] + responses.extend(answers) + + # sort posts by time + responses.sort(lambda x,y: cmp(y.time, x.time)) + + return render_to_response(user_view.template_file,{ + "tab_name" : user_view.id, + "tab_description" : user_view.tab_description, + "page_title" : user_view.page_title, + "view_user" : user, + "responses" : responses[:user_view.data_size], + + }, context_instance=RequestContext(request)) + +def user_votes(request, user_id, user_view): + user = get_object_or_404(User, id=user_id) + if not can_view_user_votes(request.user, user): + raise Http404 + votes = [] + question_votes = Vote.objects.extra( + select={ + 'title' : 'question.title', + 'question_id' : 'question.id', + 'answer_id' : 0, + 'voted_at' : 'vote.voted_at', + 'vote' : 'vote', + }, + 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'], + params=[question_type_id, user_id], + order_by=['-vote.id'] + ).values( + 'title', + 'question_id', + 'answer_id', + 'voted_at', + 'vote', + ) + if(len(question_votes) > 0): + votes.extend(question_votes) + + answer_votes = Vote.objects.extra( + select={ + 'title' : 'question.title', + 'question_id' : 'question.id', + 'answer_id' : 'answer.id', + 'voted_at' : 'vote.voted_at', + 'vote' : 'vote', + }, + 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'], + params=[answer_type_id, user_id], + order_by=['-vote.id'] + ).values( + 'title', + 'question_id', + 'answer_id', + 'voted_at', + 'vote', + ) + if(len(answer_votes) > 0): + votes.extend(answer_votes) + votes.sort(lambda x,y: cmp(y['voted_at'], x['voted_at'])) + return render_to_response(user_view.template_file,{ + "tab_name" : user_view.id, + "tab_description" : user_view.tab_description, + "page_title" : user_view.page_title, + "view_user" : user, + "votes" : votes[:user_view.data_size] + + }, context_instance=RequestContext(request)) + +def user_reputation(request, user_id, user_view): + user = get_object_or_404(User, id=user_id) + reputation = Repute.objects.extra( + select={'positive': 'sum(positive)', 'negative': 'sum(negative)', 'question_id':'question_id', + 'title': 'question.title'}, + tables=['repute', 'question'], + order_by=['-reputed_at'], + where=['user_id=%s AND question_id=question.id'], + params=[user.id] + ).values('positive', 'negative', 'question_id', 'title', 'reputed_at', 'reputation') + + reputation.query.group_by = ['question_id'] + + + rep_list = [] + for rep in Repute.objects.filter(user=user).order_by('reputed_at'): + dic = '[%s,%s]' % (calendar.timegm(rep.reputed_at.timetuple()) * 1000, rep.reputation) + rep_list.append(dic) + reps = ','.join(rep_list) + reps = '[%s]' % reps + + return render_to_response(user_view.template_file,{ + "tab_name" : user_view.id, + "tab_description" : user_view.tab_description, + "page_title" : user_view.page_title, + "view_user" : user, + "reputation" : reputation, + "reps" : reps + }, context_instance=RequestContext(request)) + +def user_favorites(request, user_id, user_view): + user = get_object_or_404(User, id=user_id) + 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', + 'la_user_id' : 'auth_user.id', + 'la_username' : 'auth_user.username', + 'la_user_gold' : 'auth_user.gold', + 'la_user_silver' : 'auth_user.silver', + 'la_user_bronze' : 'auth_user.bronze', + 'la_user_reputation' : 'auth_user.reputation' + }, + 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'], + params=[user_id], + order_by=['-vote_count', '-question.id'] + ).values('vote_count', + 'favorited_myself', + 'id', + 'title', + 'author_id', + 'added_at', + 'answer_accepted', + 'answer_count', + 'comment_count', + 'view_count', + 'favourite_count', + 'summary', + 'tagnames', + 'vote_up_count', + 'vote_down_count', + 'last_activity_at', + 'la_user_id', + 'la_username', + 'la_user_gold', + 'la_user_silver', + 'la_user_bronze', + 'la_user_reputation') + return render_to_response(user_view.template_file,{ + "tab_name" : user_view.id, + "tab_description" : user_view.tab_description, + "page_title" : user_view.page_title, + "questions" : questions[:user_view.data_size], + "view_user" : user + }, context_instance=RequestContext(request)) + + +def user_preferences(request, user_id, user_view): + user = get_object_or_404(User, id=user_id) + return render_to_response(user_view.template_file,{ + "tab_name" : user_view.id, + "tab_description" : user_view.tab_description, + "page_title" : user_view.page_title, + "view_user" : user, + }, context_instance=RequestContext(request)) + +def question_comments(request, id): + question = get_object_or_404(Question, id=id) + user = request.user + return __comments(request, question, 'question', user) + +def answer_comments(request, id): + answer = get_object_or_404(Answer, id=id) + user = request.user + return __comments(request, answer, 'answer', user) + +def __comments(request, obj, type, user): + # only support get comments by ajax now + if request.is_ajax(): + if request.method == "GET": + return __generate_comments_json(obj, type, user) + elif request.method == "POST": + comment_data = request.POST.get('comment') + comment = Comment(content_object=obj, comment=comment_data, user=request.user) + comment.save() + obj.comment_count = obj.comment_count + 1 + obj.save() + return __generate_comments_json(obj, type, user) + +def __generate_comments_json(obj, type, user): + comments = obj.comments.all().order_by('-id') + # {"Id":6,"PostId":38589,"CreationDate":"an hour ago","Text":"hello there!","UserDisplayName":"Jarrod Dixon","UserUrl":"/users/3/jarrod-dixon","DeleteUrl":null} + json_comments = [] + for comment in comments: + comment_user = comment.user + delete_url = "" + if user != None and auth.can_delete_comment(user, comment): + #/posts/392845/comments/219852/delete + delete_url = "/" + type + "s/%s/comments/%s/delete/" % (obj.id, comment.id) + json_comments.append({"id" : comment.id, + "object_id" : obj.id, + "add_date" : comment.added_at.strftime('%Y-%m-%d'), + "text" : comment.comment, + "user_display_name" : comment_user.username, + "user_url" : "/users/%s/%s" % (comment_user.id, comment_user.username), + "delete_url" : delete_url + }) + + data = simplejson.dumps(json_comments) + return HttpResponse(data, mimetype="application/json") + +def delete_question_comment(request, question_id, comment_id): + if request.is_ajax(): + question = get_object_or_404(Question, id=question_id) + comment = get_object_or_404(Comment, id=comment_id) + + question.comments.remove(comment) + question.comment_count = question.comment_count - 1 + question.save() + user = request.user + return __generate_comments_json(question, 'question', user) + +def delete_answer_comment(request, answer_id, comment_id): + if request.is_ajax(): + answer = get_object_or_404(Answer, id=answer_id) + comment = get_object_or_404(Comment, id=comment_id) + + answer.comments.remove(comment) + answer.comment_count = answer.comment_count - 1 + answer.save() + user = request.user + return __generate_comments_json(answer, 'answer', user) + +def logout(request): + url = request.GET.get('next') + return render_to_response('logout.html', { + 'next' : url, + }, context_instance=RequestContext(request)) + +def badges(request): + badges = Badge.objects.all().order_by('type') + my_badges = [] + if request.user.is_authenticated(): + my_badges = Award.objects.filter(user=request.user) + my_badges.query.group_by = ['badge_id'] + + return render_to_response('badges.html', { + 'badges' : badges, + 'mybadges' : my_badges, + }, context_instance=RequestContext(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'}, + tables=['award', 'auth_user'], + where=['badge_id=%s AND user_id=auth_user.id'], + params=[id] + ).values('id').distinct() + + return render_to_response('badge.html', { + 'awards' : awards, + 'badge' : badge, + }, context_instance=RequestContext(request)) + +def read_message(request): + if request.method == "POST": + if request.POST['formdata'] == 'required': + request.session['message_silent'] = 1 + + if request.user.is_authenticated(): + request.user.delete_messages() + return HttpResponse('') + +def upload(request): + class FileTypeNotAllow(Exception): + pass + class FileSizeNotAllow(Exception): + pass + class UploadPermissionNotAuthorized(Exception): + pass + + #<result><msg><![CDATA[%s]]></msg><error><![CDATA[%s]]></error><file_url>%s</file_url></result> + xml_template = "<result><msg><![CDATA[%s]]></msg><error><![CDATA[%s]]></error><file_url>%s</file_url></result>" + + try: + f = request.FILES['file-upload'] + # check upload permission + if not can_upload_files(request.user): + raise UploadPermissionNotAuthorized + + # check file type + file_name_suffix = os.path.splitext(f.name)[1].lower() + if not file_name_suffix in settings.ALLOW_FILE_TYPES: + raise FileTypeNotAllow + + # genetate new file name + new_file_name = str(time.time()).replace('.', str(random.randint(0,100000))) + file_name_suffix + # use default storage to store file + default_storage.save(new_file_name, f) + # check file size + # byte + size = default_storage.size(new_file_name) + if size > settings.ALLOW_MAX_FILE_SIZE: + default_storage.delete(new_file_name) + raise FileSizeNotAllow + + result = xml_template % ('Good', '', default_storage.url(new_file_name)) + except UploadPermissionNotAuthorized: + result = xml_template % ('', _('uploading images is limited to users with >60 reputation points'), '') + except FileTypeNotAllow: + result = xml_template % ('', _("allowed file types are 'jpg', 'jpeg', 'gif', 'bmp', 'png', 'tiff'"), '') + except FileSizeNotAllow: + result = xml_template % ('', _("maximum upload file size is %sK") % settings.ALLOW_MAX_FILE_SIZE / 1024, '') + except Exception: + result = xml_template % ('', _('Error uploading file. Please contact the site administrator. Thank you. %s' % Exception), '') + + return HttpResponse(result, mimetype="application/xml") + +def books(request): + return HttpResponseRedirect("/books/mysql-zhaoyang") + +def book(request, short_name, unanswered=False): + """ + 1. questions list + 2. book info + 3. author info and blog rss items + """ + """ + List of Questions, Tagged questions, and Unanswered questions. + """ + books = Book.objects.extra(where=['short_name = %s'], params=[short_name]) + match_count = len(books) + if match_count == 0 : + raise Http404 + else: + # the book info + book = books[0] + # get author info + author_info = BookAuthorInfo.objects.get(book=book) + # get author rss info + author_rss = BookAuthorRss.objects.filter(book=book) + + # 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: + page = int(request.GET.get('page', '1')) + except ValueError: + page = 1 + + view_id = request.GET.get('sort', None) + view_dic = {"latest":"-added_at", "active":"-last_activity_at", "hottest":"-answer_count", "mostvoted":"-score" } + try: + orderby = view_dic[view_id] + except KeyError: + view_id = "latest" + orderby = "-added_at" + + # check if request is from tagged questions + if unanswered: + # check if request is from unanswered questions + # Article.objects.filter(publications__id__exact=1) + objects = Question.objects.filter(book__id__exact=book.id, deleted=False, answer_count=0).order_by(orderby) + else: + objects = Question.objects.filter(book__id__exact=book.id, deleted=False).order_by(orderby) + + # RISK - inner join queries + objects = objects.select_related(); + objects_list = Paginator(objects, user_page_size) + questions = objects_list.page(page) + + return render_to_response('book.html', { + "book" : book, + "author_info" : author_info, + "author_rss" : author_rss, + "questions" : questions, + "context" : { + 'is_paginated' : True, + 'pages': objects_list.num_pages, + 'page': page, + 'has_previous': questions.has_previous(), + 'has_next': questions.has_next(), + 'previous': questions.previous_page_number(), + 'next': questions.next_page_number(), + 'base_url' : request.path + '?sort=%s&' % view_id, + 'pagesize' : user_page_size + } + }, context_instance=RequestContext(request)) + +@login_required +def ask_book(request, short_name): + if request.method == "POST": + form = AskForm(request.POST) + if form.is_valid(): + added_at = datetime.datetime.now() + html = sanitize_html(markdowner.convert(form.cleaned_data['text'])) + question = Question( + title = strip_tags(form.cleaned_data['title']), + author = request.user, + added_at = added_at, + last_activity_at = added_at, + last_activity_by = request.user, + wiki = form.cleaned_data['wiki'], + tagnames = form.cleaned_data['tags'].strip(), + html = html, + summary = strip_tags(html)[:120] + ) + if question.wiki: + question.last_edited_by = question.author + question.last_edited_at = added_at + question.wikified_at = added_at + + question.save() + + # create the first revision + QuestionRevision.objects.create( + question = question, + revision = 1, + title = question.title, + author = request.user, + revised_at = added_at, + tagnames = question.tagnames, + summary = CONST['default_version'], + text = form.cleaned_data['text'] + ) + + books = Book.objects.extra(where=['short_name = %s'], params=[short_name]) + match_count = len(books) + if match_count == 1: + # the book info + book = books[0] + book.questions.add(question) + + return HttpResponseRedirect(question.get_absolute_url()) + else: + form = AskForm() + + tags = _get_tags_cache_json() + return render_to_response('ask.html', { + 'form' : form, + 'tags' : tags, + }, context_instance=RequestContext(request)) + +def search(request): + """ + Search by question, user and tag keywords. + For questions now we only search keywords in question title. + """ + if request.method == "GET": + keywords = request.GET.get("q") + search_type = request.GET.get("t") + try: + page = int(request.GET.get('page', '1')) + except ValueError: + page = 1 + if keywords is None: + return HttpResponseRedirect('/') + if search_type == 'tag': + return HttpResponseRedirect('/tags/?q=%s&page=%s' % (keywords.strip(), page)) + elif search_type == "user": + return HttpResponseRedirect('/users/?q=%s&page=%s' % (keywords.strip(), page)) + elif search_type == "question": + + template_file = "questions.html" + # 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: + 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" } + try: + orderby = view_dic[view_id] + except KeyError: + view_id = "latest" + orderby = "-added_at" + + objects = Question.objects.filter(deleted=False).extra(where=['title like %s'], params=['%' + keywords + '%']).order_by(orderby) + + # RISK - inner join queries + objects = objects.select_related(); + 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) + + return render_to_response(template_file, { + "questions" : questions, + "tab_id" : view_id, + "questions_count" : objects_list.count, + "tags" : related_tags, + "searchtag" : None, + "searchtitle" : keywords, + "keywords" : keywords, + "is_unanswered" : False, + "context" : { + 'is_paginated' : True, + 'pages': objects_list.num_pages, + 'page': page, + 'has_previous': questions.has_previous(), + 'has_next': questions.has_next(), + 'previous': questions.previous_page_number(), + 'next': questions.next_page_number(), + 'base_url' : request.path + '?t=question&q=%s&sort=%s&' % (keywords, view_id), + 'pagesize' : pagesize + }}, context_instance=RequestContext(request)) + + else: + raise Http404 + @@ -0,0 +1,7 @@ +/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 --git a/lanai.psproj b/lanai.psproj new file mode 100644 index 00000000..7f44d7ff --- /dev/null +++ b/lanai.psproj @@ -0,0 +1,557 @@ +[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 --git a/locale/en/LC_MESSAGES/django.mo b/locale/en/LC_MESSAGES/django.mo Binary files differdeleted file mode 100644 index 8c359972..00000000 --- a/locale/en/LC_MESSAGES/django.mo +++ /dev/null diff --git a/locale/en/LC_MESSAGES/django.po b/locale/en/LC_MESSAGES/django.po index 93cfdfe4..c4c1e674 100644 --- a/locale/en/LC_MESSAGES/django.po +++ b/locale/en/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-07-28 15:57+0000\n" +"POT-Creation-Date: 2009-06-22 20:40-0400\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" @@ -16,11 +16,11 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: settings.py:12 +#: settings.py:32 msgid "account/" msgstr "" -#: settings.py:12 django_authopenid/urls.py:9 django_authopenid/urls.py:11 +#: settings.py:32 django_authopenid/urls.py:9 django_authopenid/urls.py:11 msgid "signin/" msgstr "" @@ -237,7 +237,7 @@ msgstr "" msgid "question" msgstr "" -#: forum/const.py:57 templates/book.html:110 +#: forum/const.py:57 templates/book.html:110 templates/backup/book.html:110 msgid "answer" msgstr "" @@ -317,7 +317,12 @@ msgstr "" msgid "retagged" msgstr "" -#: forum/feed.py:17 +#: forum/feed.py:17 templates/base.html:7 templates/base_content.html:6 +#: templates/faq.html:25 templates/faq.html.py:108 +#: templates/backup/base.html:7 templates/backup/base_content.html:6 +#: templates/backup/faq.html:25 templates/backup/faq.html.py:108 +#: templates/tough/faq.html:23 templates/tough/faq.html.py:106 +#: templates/tough/question_retag.html:89 msgid "site title" msgstr "" @@ -325,7 +330,8 @@ msgstr "" msgid " - " msgstr "" -#: forum/feed.py:17 +#: forum/feed.py:17 templates/base.html:7 templates/base_content.html:6 +#: templates/backup/base.html:7 templates/backup/base_content.html:6 msgid "site slogan" msgstr "" @@ -333,16 +339,21 @@ msgstr "" msgid "latest questions" msgstr "" -#: forum/feed.py:20 +#: forum/feed.py:19 templates/index.html:8 templates/backup/index.html:8 msgid "meta site content" msgstr "" -#: forum/feed.py:22 +#: forum/feed.py:21 msgid "copyright message" msgstr "" -#: forum/forms.py:14 templates/question_edit_tips.html:31 +#: forum/forms.py:14 templates/answer_edit_tips.html:34 +#: templates/answer_edit_tips.html.py:39 templates/question_edit_tips.html:31 #: templates/question_edit_tips.html:36 +#: templates/backup/answer_edit_tips.html:33 +#: templates/backup/answer_edit_tips.html:38 +#: templates/backup/question_edit_tips.html:29 +#: templates/backup/question_edit_tips.html:34 msgid "title" msgstr "" @@ -363,6 +374,7 @@ msgid "question content must be > 10 characters" msgstr "" #: forum/forms.py:45 templates/header.html:30 templates/header.html.py:61 +#: templates/backup/header.html:30 templates/backup/header.html.py:59 msgid "tags" msgstr "" @@ -389,8 +401,13 @@ msgid "" msgstr "" #: forum/forms.py:74 templates/index.html:56 templates/question.html:196 -#: templates/question.html.py:377 templates/unanswered.html:48 -#: templates/unanswered.html.py:60 +#: templates/question.html.py:377 templates/questions.html:58 +#: templates/questions.html.py:70 templates/unanswered.html:48 +#: templates/unanswered.html.py:60 templates/backup/index.html:56 +#: templates/backup/question.html:195 templates/backup/question.html.py:367 +#: templates/backup/questions.html:57 templates/backup/questions.html.py:69 +#: templates/backup/unanswered.html:47 templates/backup/unanswered.html:59 +#: templates/tough/unanswered.html:46 templates/tough/unanswered.html.py:58 msgid "community wiki" msgstr "" @@ -442,123 +459,134 @@ msgstr "" msgid "this email has already been registered, please use another one" msgstr "" -#: forum/models.py:316 templates/badges.html:50 +#: forum/models.py:316 templates/badges.html:52 +#: templates/backup/badges.html:52 msgid "gold" msgstr "" -#: forum/models.py:317 templates/badges.html:58 +#: forum/models.py:317 templates/badges.html:62 +#: templates/backup/badges.html:62 msgid "silver" msgstr "" -#: forum/models.py:318 templates/badges.html:65 +#: forum/models.py:318 templates/badges.html:70 +#: templates/backup/badges.html:70 msgid "bronze" msgstr "" -#: forum/user.py:17 templates/user_tabs.html:7 +#: forum/user.py:16 templates/user_tabs.html:7 +#: templates/backup/user_tabs.html:6 msgid "overview" msgstr "" -#: forum/user.py:18 +#: forum/user.py:17 msgid "user profile" msgstr "" -#: forum/user.py:19 +#: forum/user.py:18 msgid "user profile overview" msgstr "" -#: forum/user.py:25 templates/user_tabs.html:9 +#: forum/user.py:24 templates/user_tabs.html:9 +#: templates/backup/user_tabs.html:8 msgid "recent activity" msgstr "" -#: forum/user.py:26 +#: forum/user.py:25 msgid "recent user activity" msgstr "" -#: forum/user.py:27 +#: forum/user.py:26 msgid "profile - recent activity" msgstr "" -#: forum/user.py:34 templates/user_tabs.html:13 +#: forum/user.py:33 templates/user_tabs.html:13 +#: templates/backup/user_tabs.html:12 msgid "responses" msgstr "" -#: forum/user.py:35 templates/user_tabs.html:12 +#: forum/user.py:34 templates/user_tabs.html:12 +#: templates/backup/user_tabs.html:11 msgid "comments and answers to others questions" msgstr "" -#: forum/user.py:36 +#: forum/user.py:35 msgid "profile - responses" msgstr "" -#: forum/user.py:43 templates/user_info.html:23 templates/users.html:25 +#: forum/user.py:42 templates/user_info.html:23 templates/users.html:26 +#: templates/backup/user_info.html:22 templates/backup/users.html:25 msgid "reputation" msgstr "" -#: forum/user.py:44 +#: forum/user.py:43 msgid "user reputation in the community" msgstr "" -#: forum/user.py:45 +#: forum/user.py:44 msgid "profile - user reputation" msgstr "" -#: forum/user.py:51 +#: forum/user.py:50 msgid "favorite questions" msgstr "" -#: forum/user.py:52 +#: forum/user.py:51 msgid "users favorite questions" msgstr "" -#: forum/user.py:53 +#: forum/user.py:52 msgid "profile - favorite questions" msgstr "" -#: forum/user.py:60 templates/user_tabs.html:20 +#: forum/user.py:59 templates/user_tabs.html:20 +#: templates/backup/user_tabs.html:19 msgid "casted votes" -msgstr "" +msgstr "votes" -#: forum/user.py:61 templates/user_tabs.html:20 +#: forum/user.py:60 templates/user_tabs.html:20 +#: templates/backup/user_tabs.html:19 msgid "user vote record" msgstr "" -#: forum/user.py:62 +#: forum/user.py:61 msgid "profile - votes" msgstr "" -#: forum/user.py:69 +#: forum/user.py:68 msgid "preferences" msgstr "" -#: forum/user.py:70 templates/user_tabs.html:28 +#: forum/user.py:69 templates/user_tabs.html:28 +#: templates/backup/user_tabs.html:27 msgid "user preference settings" msgstr "" -#: forum/user.py:71 +#: forum/user.py:70 msgid "profile - user preferences" msgstr "" -#: forum/views.py:1726 +#: forum/views.py:1730 msgid "uploading images is limited to users with >60 reputation points" msgstr "" -#: forum/views.py:1728 +#: forum/views.py:1732 msgid "allowed file types are 'jpg', 'jpeg', 'gif', 'bmp', 'png', 'tiff'" msgstr "" -#: forum/views.py:1730 +#: forum/views.py:1734 #, python-format msgid "maximum upload file size is %sK" msgstr "" -#: forum/views.py:1732 +#: forum/views.py:1736 #, python-format msgid "" "Error uploading file. Please contact the site administrator. Thank you. %s" msgstr "" #: forum/templatetags/extra_tags.py:139 forum/templatetags/extra_tags.py:168 -#: templates/header.html:33 +#: templates/header.html:33 templates/backup/header.html:33 msgid "badges" msgstr "" @@ -570,669 +598,1135 @@ msgstr "" msgid " ago" msgstr "" -#: templates/404.html:24 +#: templates/404.html:24 templates/backup/404.html:24 msgid "Sorry, could not find the page you requested." msgstr "" -#: templates/404.html:26 +#: templates/404.html:26 templates/backup/404.html:26 msgid "This might have happened for the following reasons:" msgstr "" -#: templates/404.html:28 +#: templates/404.html:28 templates/backup/404.html:28 msgid "this question or answer has been deleted;" msgstr "" -#: templates/404.html:29 +#: templates/404.html:29 templates/backup/404.html:29 msgid "url has error - please check it;" msgstr "" -#: templates/404.html:30 +#: templates/404.html:30 templates/backup/404.html:30 msgid "" "the page you tried to visit is protected or you don't have sufficient " "points, see" msgstr "" -#: templates/404.html:31 +#: templates/404.html:31 templates/backup/404.html:31 msgid "if you believe this error 404 should not have occured, please" msgstr "" -#: templates/404.html:32 +#: templates/404.html:32 templates/backup/404.html:32 msgid "report this problem" msgstr "" -#: templates/404.html:41 templates/500.html:27 +#: templates/404.html:41 templates/500.html:27 templates/backup/404.html:41 +#: templates/backup/500.html:27 msgid "back to previous page" msgstr "" -#: templates/404.html:42 +#: templates/404.html:42 templates/backup/404.html:42 msgid "see all questions" msgstr "" -#: templates/404.html:43 +#: templates/404.html:43 templates/backup/404.html:43 msgid "see all tags" msgstr "" -#: templates/500.html:24 +#: templates/500.html:24 templates/backup/500.html:24 msgid "system error log is recorded, error will be fixed as soon as possible" msgstr "" -#: templates/500.html:25 +#: templates/500.html:25 templates/backup/500.html:25 msgid "please report the error to the site administrators if you wish" msgstr "" -#: templates/500.html:28 +#: templates/500.html:28 templates/backup/500.html:28 msgid "see latest questions" msgstr "" -#: templates/500.html:29 +#: templates/500.html:29 templates/backup/500.html:29 msgid "see tags" msgstr "" +#: templates/about.html:6 templates/about.html.py:11 +#: templates/backup/about.html:6 templates/backup/about.html.py:11 +msgid "About" +msgstr "" + #: templates/answer_edit.html:4 templates/answer_edit.html.py:47 +#: templates/backup/answer_edit.html:3 templates/backup/answer_edit.html:46 msgid "Edit answer" msgstr "" #: templates/answer_edit.html:24 templates/answer_edit.html.py:27 #: templates/ask.html:25 templates/ask.html.py:28 templates/question.html:37 #: templates/question.html.py:40 templates/question_edit.html:27 +#: templates/backup/answer_edit.html:23 templates/backup/answer_edit.html:26 +#: templates/backup/ask.html:24 templates/backup/ask.html.py:27 +#: templates/backup/question.html:36 templates/backup/question.html.py:39 +#: templates/backup/question_edit.html:25 msgid "hide preview" msgstr "" #: templates/answer_edit.html:27 templates/ask.html:28 #: templates/question.html:40 templates/question_edit.html:27 +#: templates/backup/answer_edit.html:26 templates/backup/ask.html:27 +#: templates/backup/question.html:39 templates/backup/question_edit.html:25 msgid "show preview" msgstr "" #: templates/answer_edit.html:47 templates/question_edit.html:65 #: templates/revisions_answer.html:36 templates/revisions_question.html:36 +#: templates/backup/answer_edit.html:46 templates/backup/question_edit.html:63 +#: templates/backup/revisions_answer.html:35 +#: templates/backup/revisions_question.html:34 +#: templates/tough/question_retag.html:51 msgid "back" msgstr "" #: templates/answer_edit.html:52 templates/question_edit.html:70 #: templates/revisions_answer.html:47 templates/revisions_question.html:47 +#: templates/backup/answer_edit.html:51 templates/backup/question_edit.html:68 +#: templates/backup/revisions_answer.html:46 +#: templates/backup/revisions_question.html:45 msgid "revision" msgstr "" #: templates/answer_edit.html:55 templates/question_edit.html:74 +#: templates/backup/answer_edit.html:54 templates/backup/question_edit.html:72 msgid "select revision" msgstr "" #: templates/answer_edit.html:62 templates/ask.html:81 #: templates/question.html:447 templates/question_edit.html:91 +#: templates/backup/answer_edit.html:61 templates/backup/ask.html:80 +#: templates/backup/question.html:437 templates/backup/question_edit.html:89 msgid "Toggle the real time Markdown editor preview" msgstr "" #: templates/answer_edit.html:62 templates/ask.html:81 #: templates/question.html:447 templates/question_edit.html:91 +#: templates/backup/answer_edit.html:61 templates/backup/ask.html:80 +#: templates/backup/question.html:437 templates/backup/question_edit.html:89 msgid "toggle preview" msgstr "" #: templates/answer_edit.html:73 templates/question_edit.html:119 +#: templates/backup/answer_edit.html:72 +#: templates/backup/question_edit.html:117 msgid "Save edit" msgstr "" #: templates/answer_edit.html:74 templates/close.html:29 #: templates/question_edit.html:120 templates/reopen.html:30 -#: templates/user_edit.html:83 +#: templates/user_edit.html:83 templates/backup/answer_edit.html:73 +#: templates/backup/close.html:29 templates/backup/question_edit.html:118 +#: templates/backup/reopen.html:28 templates/backup/user_edit.html:81 +#: templates/tough/question_retag.html:75 msgid "Cancel" msgstr "" -#: templates/ask.html:4 templates/ask.html.py:60 +#: templates/answer_edit_tips.html:4 +msgid "answer tips" +msgstr "Tips" + +#: templates/answer_edit_tips.html:7 templates/backup/answer_edit_tips.html:6 +msgid "please make your answer relevant to this community" +msgstr "" + +#: templates/answer_edit_tips.html:10 templates/backup/answer_edit_tips.html:9 +msgid "try to give an answer, rather than engage into a discussion" +msgstr "" + +#: templates/answer_edit_tips.html:13 +#: templates/backup/answer_edit_tips.html:12 +msgid "please try to provide details" +msgstr "" + +#: templates/answer_edit_tips.html:16 templates/question_edit_tips.html:13 +#: templates/backup/answer_edit_tips.html:15 +#: templates/backup/question_edit_tips.html:11 +msgid "be clear and concise" +msgstr "" + +#: templates/answer_edit_tips.html:19 templates/question_edit_tips.html:16 +#: templates/backup/answer_edit_tips.html:18 +#: templates/backup/question_edit_tips.html:14 +msgid "see frequently asked questions" +msgstr "" + +#: templates/answer_edit_tips.html:25 templates/question_edit_tips.html:22 +#: templates/backup/answer_edit_tips.html:24 +#: templates/backup/question_edit_tips.html:20 +msgid "Markdown tips" +msgstr "Markdown basics" + +#: templates/answer_edit_tips.html:28 templates/question_edit_tips.html:25 +#: templates/backup/answer_edit_tips.html:27 +#: templates/backup/question_edit_tips.html:23 +msgid "*italic* or __italic__" +msgstr "" + +#: templates/answer_edit_tips.html:31 templates/question_edit_tips.html:28 +#: templates/backup/answer_edit_tips.html:30 +#: templates/backup/question_edit_tips.html:26 +msgid "**bold** or __bold__" +msgstr "" + +#: templates/answer_edit_tips.html:34 templates/question_edit_tips.html:31 +#: templates/backup/answer_edit_tips.html:33 +#: templates/backup/question_edit_tips.html:29 +msgid "link" +msgstr "" + +#: templates/answer_edit_tips.html:34 templates/answer_edit_tips.html.py:39 +#: templates/question_edit_tips.html:31 templates/question_edit_tips.html:36 +#: templates/backup/answer_edit_tips.html:33 +#: templates/backup/answer_edit_tips.html:38 +#: templates/backup/question_edit_tips.html:29 +#: templates/backup/question_edit_tips.html:34 +msgid "text" +msgstr "" + +#: templates/answer_edit_tips.html:39 templates/question_edit_tips.html:36 +#: templates/backup/answer_edit_tips.html:38 +#: templates/backup/question_edit_tips.html:34 +msgid "image" +msgstr "" + +#: templates/answer_edit_tips.html:43 templates/question_edit_tips.html:40 +#: templates/backup/answer_edit_tips.html:42 +#: templates/backup/question_edit_tips.html:38 +msgid "numbered list:" +msgstr "" + +#: templates/answer_edit_tips.html:48 templates/question_edit_tips.html:45 +#: templates/backup/answer_edit_tips.html:47 +#: templates/backup/question_edit_tips.html:43 +msgid "basic HTML tags are also supported" +msgstr "" + +#: templates/answer_edit_tips.html:51 templates/question_edit_tips.html:48 +#: templates/backup/answer_edit_tips.html:50 +#: templates/backup/question_edit_tips.html:46 +msgid "learn more about Markdown" +msgstr "" + +#: templates/ask.html:4 templates/ask.html.py:60 templates/backup/ask.html:3 +#: templates/backup/ask.html.py:59 msgid "Ask a question" msgstr "" -#: templates/ask.html:106 +#: templates/ask.html:106 templates/backup/ask.html:105 msgid "Use" msgstr "" -#: templates/ask.html:106 +#: templates/ask.html:106 templates/backup/ask.html:105 msgid "learn more about OpenID" msgstr "" -#: templates/ask.html:106 templates/authopenid/signin.html:35 -#: templates/authopenid/signin.html:61 +#: templates/ask.html:106 templates/authopenid/signin.html:34 +#: templates/authopenid/signin.html:60 templates/backup/ask.html:105 msgid "Login" msgstr "" -#: templates/ask.html:109 +#: templates/ask.html:109 templates/backup/ask.html:108 msgid "Get your own " msgstr "" #: templates/ask.html:117 templates/authopenid/sendpw.html:27 +#: templates/backup/ask.html:116 msgid "User name" msgstr "" -#: templates/ask.html:120 +#: templates/ask.html:120 templates/backup/ask.html:119 msgid "Email: (won't be shown to anyone)" msgstr "" -#: templates/ask.html:127 +#: templates/ask.html:127 templates/backup/ask.html:126 msgid "Ask your question" msgstr "" #: templates/badge.html:6 templates/badge.html.py:17 +#: templates/backup/badge.html:5 templates/backup/badge.html.py:16 msgid "Badge" msgstr "" -#: templates/badge.html:26 +#: templates/badge.html:26 templates/backup/badge.html:25 msgid "The users have been awarded with badges:" msgstr "" -#: templates/badges.html:5 +#: templates/badges.html:6 templates/backup/badges.html:6 msgid "Badges summary" msgstr "" -#: templates/badges.html:16 templates/user_stats.html:113 +#: templates/badges.html:17 templates/user_stats.html:113 +#: templates/backup/badges.html:17 templates/backup/user_stats.html:112 msgid "Badges" msgstr "" -#: templates/badges.html:20 +#: templates/badges.html:21 templates/backup/badges.html:21 +msgid "Community gives you awards for your questions, answers and votes." +msgstr "" + +#: templates/badges.html:22 templates/backup/badges.html:22 msgid "" -"Community gives you awards for your questions, answers and votes. Below is " -"the list of available badges and number of times each type of badge has been " -"awarded." +"Below is the list of available badges and number of times each type of badge " +"has been awarded." msgstr "" -#: templates/badges.html:47 +#: templates/badges.html:49 templates/backup/badges.html:49 msgid "Community badges" msgstr "" -#: templates/badges.html:53 -msgid "" -"Gold badge is very rare. To obtain it you have to show profound knowledge " -"and ability in addition to actively participating in the community. Gold " -"badge is the highest award in this community." +#: templates/badges.html:55 templates/backup/badges.html:55 +msgid "Gold badge is very rare." msgstr "" -#: templates/badges.html:61 +#: templates/badges.html:56 templates/backup/badges.html:56 msgid "" -"Obtaining silver badge requires significant patience. If you got one, you've " -"very significantly contributed to this community" +"To obtain it you have to show profound knowledge and ability in addition to " +"actively participating in the community." +msgstr "" + +#: templates/badges.html:57 templates/backup/badges.html:57 +msgid "Gold badge is the highest award in this community." +msgstr "" + +#: templates/badges.html:65 templates/backup/badges.html:65 +msgid "Obtaining silver badge requires significant patience." +msgstr "" + +#: templates/badges.html:66 templates/backup/badges.html:66 +msgid "If you got one, you've very significantly contributed to this community" msgstr "" -#: templates/badges.html:64 +#: templates/badges.html:69 templates/backup/badges.html:69 msgid "bronze badge: often given as a special honor" msgstr "" -#: templates/badges.html:68 +#: templates/badges.html:73 templates/backup/badges.html:73 msgid "" -"If you are active in this community, you will get this medal - still it is a " -"special honor." +"If you are active in this community, you will will get this medal - still it " +"is a special honor." msgstr "" -#: templates/base.html:61 templates/base_content.html:60 +#: templates/base.html:59 templates/base_content.html:60 +#: templates/backup/base.html:59 templates/backup/base_content.html:57 msgid "congratulations, community gave you a badge" msgstr "" -#: templates/base.html:63 templates/base_content.html:62 +#: templates/base.html:61 templates/base_content.html:62 +#: templates/backup/base.html:61 templates/backup/base_content.html:59 msgid "profile" msgstr "" -#: templates/base_content.html:61 +#: templates/base_content.html:61 templates/backup/base_content.html:58 msgid "see" msgstr "" -#: templates/book.html:7 +#: templates/book.html:7 templates/backup/book.html:7 msgid "reading channel" msgstr "" -#: templates/book.html:26 +#: templates/book.html:26 templates/backup/book.html:26 msgid "[author]" msgstr "" -#: templates/book.html:30 +#: templates/book.html:30 templates/backup/book.html:30 msgid "[publisher]" msgstr "" -#: templates/book.html:34 +#: templates/book.html:34 templates/backup/book.html:34 msgid "[publication date]" msgstr "" -#: templates/book.html:38 +#: templates/book.html:38 templates/backup/book.html:38 msgid "[price]" msgstr "" -#: templates/book.html:39 +#: templates/book.html:39 templates/backup/book.html:39 msgid "currency unit" msgstr "" -#: templates/book.html:42 +#: templates/book.html:42 templates/backup/book.html:42 msgid "[pages]" msgstr "" -#: templates/book.html:43 +#: templates/book.html:43 templates/backup/book.html:43 msgid "pages abbreviation" msgstr "" -#: templates/book.html:46 +#: templates/book.html:46 templates/backup/book.html:46 msgid "[tags]" msgstr "" -#: templates/book.html:56 +#: templates/book.html:56 templates/backup/book.html:56 msgid "author blog" msgstr "" -#: templates/book.html:62 +#: templates/book.html:62 templates/backup/book.html:62 msgid "book directory" msgstr "" -#: templates/book.html:66 +#: templates/book.html:66 templates/backup/book.html:66 msgid "buy online" msgstr "" -#: templates/book.html:79 +#: templates/book.html:79 templates/backup/book.html:79 msgid "reader questions" msgstr "" -#: templates/book.html:82 +#: templates/book.html:82 templates/backup/book.html:82 msgid "ask the author" msgstr "" #: templates/book.html:88 templates/book.html.py:93 -#: templates/users_questions.html:17 +#: templates/users_questions.html:17 templates/backup/book.html:88 +#: templates/backup/book.html.py:93 templates/backup/users_questions.html:16 msgid "this question was selected as favorite" msgstr "" #: templates/book.html:88 templates/book.html.py:93 #: templates/users_questions.html:11 templates/users_questions.html.py:17 +#: templates/backup/book.html:88 templates/backup/book.html.py:93 +#: templates/backup/users_questions.html:10 +#: templates/backup/users_questions.html:16 msgid "number of times" msgstr "" -#: templates/book.html:105 templates/index.html:47 +#: templates/book.html:105 templates/index.html:47 templates/questions.html:46 #: templates/unanswered.html:37 templates/users_questions.html:30 +#: templates/backup/book.html:105 templates/backup/index.html:47 +#: templates/backup/questions.html:45 templates/backup/unanswered.html:36 +#: templates/backup/users_questions.html:29 templates/tough/unanswered.html:35 msgid "votes" msgstr "" -#: templates/book.html:108 +#: templates/book.html:108 templates/backup/book.html:108 msgid "the answer has been accepted to be correct" msgstr "" -#: templates/book.html:115 templates/index.html:48 +#: templates/book.html:115 templates/index.html:48 templates/questions.html:47 #: templates/unanswered.html:38 templates/users_questions.html:40 +#: templates/backup/book.html:115 templates/backup/index.html:48 +#: templates/backup/questions.html:46 templates/backup/unanswered.html:37 +#: templates/backup/users_questions.html:39 templates/tough/unanswered.html:36 msgid "views" msgstr "" #: templates/book.html:125 templates/index.html:68 templates/question.html:112 -#: templates/question.html.py:479 templates/tags.html:46 +#: templates/question.html.py:479 templates/questions.html:84 +#: templates/questions.html.py:149 templates/tags.html:47 #: templates/unanswered.html:75 templates/unanswered.html.py:109 -#: templates/users_questions.html:52 +#: templates/users_questions.html:52 templates/backup/book.html:125 +#: templates/backup/index.html:68 templates/backup/index.html.py:93 +#: templates/backup/question.html:111 templates/backup/question.html.py:469 +#: templates/backup/questions.html:83 templates/backup/questions.html:148 +#: templates/backup/tags.html:46 templates/backup/unanswered.html:74 +#: templates/backup/unanswered.html:108 +#: templates/backup/users_questions.html:51 templates/tough/unanswered.html:72 +#: templates/tough/unanswered.html:105 msgid "using tags" msgstr "" -#: templates/book.html:147 +#: templates/book.html:147 templates/backup/book.html:147 msgid "subscribe to book RSS feed" msgstr "" -#: templates/book.html:147 templates/index.html:115 +#: templates/book.html:147 templates/index.html:116 +#: templates/backup/book.html:147 templates/backup/index.html:115 msgid "subscribe to the questions feed" msgstr "" #: templates/close.html:6 templates/close.html.py:16 +#: templates/backup/close.html:6 templates/backup/close.html.py:16 msgid "Close question" msgstr "" -#: templates/close.html:19 +#: templates/close.html:19 templates/backup/close.html:19 msgid "Close the question" msgstr "" -#: templates/close.html:25 +#: templates/close.html:25 templates/backup/close.html:25 msgid "Reasons" msgstr "" -#: templates/close.html:28 +#: templates/close.html:28 templates/backup/close.html:28 msgid "OK to close" msgstr "" -#: templates/footer.html:5 -msgid "About us" +#: templates/faq.html:11 templates/backup/faq.html:11 +#: templates/tough/faq.html:9 +msgid "Frequently Asked Questions " msgstr "" -#: templates/footer.html:6 templates/header.html:13 templates/index.html:83 -msgid "faq" +#: templates/faq.html:15 templates/backup/faq.html:15 +#: templates/tough/faq.html:13 +msgid "What kinds of questions can I ask here?" msgstr "" -#: templates/footer.html:8 -msgid "Contact" +#: templates/faq.html:16 templates/backup/faq.html:16 +#: templates/tough/faq.html:14 +msgid "" +"Most importanly - questions should be <strong>relevant</strong> to this " +"community." msgstr "" -#: templates/footer.html:9 -msgid "Privacy" +#: templates/faq.html:17 templates/backup/faq.html:17 +#: templates/tough/faq.html:15 +msgid "" +"Before asking the question - please make sure to use search to see whether " +"your question has alredy been answered." msgstr "" -#: templates/footer.html:10 -msgid "Feedback" +#: templates/faq.html:20 templates/backup/faq.html:20 +#: templates/tough/faq.html:18 +msgid "What questions should I avoid asking?" msgstr "" -#: templates/header.html:8 -msgid "logout" +#: templates/faq.html:21 templates/backup/faq.html:21 +#: templates/tough/faq.html:19 +msgid "" +"Please avoid asking questions that are not relevant to this community, too " +"subjective and argumentative." msgstr "" -#: templates/header.html:10 templates/authopenid/signup.html:39 -msgid "login" +#: templates/faq.html:24 templates/backup/faq.html:24 +#: templates/tough/faq.html:22 +msgid "What should I avoid in my answers?" msgstr "" -#: templates/header.html:12 templates/index.html:82 -msgid "about" +#: templates/faq.html:25 templates/backup/faq.html:25 +#: templates/tough/faq.html:23 +msgid "" +"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." msgstr "" -#: templates/header.html:23 -msgid "back to home page" +#: templates/faq.html:28 templates/backup/faq.html:28 +#: templates/tough/faq.html:26 +msgid "Who moderates this community?" +msgstr "" + +#: templates/faq.html:29 templates/backup/faq.html:29 +#: templates/tough/faq.html:27 +msgid "The short answer is: <strong>you</strong>." +msgstr "" + +#: templates/faq.html:30 templates/backup/faq.html:30 +#: templates/tough/faq.html:28 +msgid "This website is moderated by the users." +msgstr "" + +#: templates/faq.html:31 templates/backup/faq.html:31 +#: templates/tough/faq.html:29 +msgid "" +"The reputation system allows users earn the authorization to perform a " +"variety of moderation tasks." +msgstr "" + +#: templates/faq.html:34 templates/backup/faq.html:34 +#: templates/tough/faq.html:32 +msgid "How does reputation system work?" +msgstr "" + +#: templates/faq.html:35 templates/backup/faq.html:35 +#: templates/tough/faq.html:33 +msgid "" +"Anyone can ask questions and give answers, points are not necessary for that." +msgstr "" + +#: templates/faq.html:36 templates/backup/faq.html:36 +#: templates/tough/faq.html:34 +msgid "" +"As we've said before, users help running this site. Point system helps " +"select users who can administer this community." +msgstr "" + +#: templates/faq.html:37 templates/backup/faq.html:37 +#: templates/tough/faq.html:35 +msgid "" +"Reputation points roughly measure how community trusts you. These points are " +"given to you directly by other members of the community." +msgstr "" + +#: templates/faq.html:40 templates/backup/faq.html:40 +#: templates/tough/faq.html:38 +msgid "" +"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." +msgstr "" + +#: templates/faq.html:41 templates/backup/faq.html:41 +#: templates/tough/faq.html:39 +msgid "" +"If on the other hand someone gives a misleading answer, the answer will be " +"voted down and he/she loses some points." +msgstr "" + +#: templates/faq.html:42 templates/backup/faq.html:42 +#: templates/tough/faq.html:40 +msgid "" +"Each vote in favor will generate <strong>10</strong> points, each vote " +"against will subtract <strong>2</strong> points." +msgstr "" + +#: templates/faq.html:43 templates/backup/faq.html:43 +#: templates/tough/faq.html:41 +msgid "" +"Through the votes of other people you can accumulate a maximum of " +"<strong>200</strong> points." +msgstr "" + +#: templates/faq.html:44 templates/backup/faq.html:44 +msgid "After accumulating certain number of points, you can do more:" +msgstr "" + +#: templates/faq.html:52 templates/user_votes.html:14 +#: templates/backup/faq.html:52 templates/backup/user_votes.html:13 +#: templates/tough/faq.html:50 +msgid "upvote" +msgstr "" + +#: templates/faq.html:56 templates/backup/faq.html:56 +#: templates/tough/faq.html:54 +msgid "use tags" +msgstr "" + +#: templates/faq.html:60 templates/backup/faq.html:60 +#: templates/tough/faq.html:58 +msgid "add comments" msgstr "" -#: templates/header.html:29 templates/header.html.py:60 +#: templates/faq.html:64 templates/user_votes.html:16 +#: templates/backup/faq.html:64 templates/backup/user_votes.html:15 +#: templates/tough/faq.html:62 +msgid "downvote" +msgstr "" + +#: templates/faq.html:71 templates/backup/faq.html:71 +#: templates/tough/faq.html:69 +msgid "retag questions" +msgstr "" + +#: templates/faq.html:75 templates/backup/faq.html:75 +#: templates/tough/faq.html:73 +msgid "edit community wiki questions" +msgstr "" + +#: templates/faq.html:79 templates/backup/faq.html:79 +#: templates/tough/faq.html:77 +msgid "edit any answer" +msgstr "" + +#: templates/faq.html:83 templates/backup/faq.html:83 +#: templates/tough/faq.html:81 +msgid "open any closed question" +msgstr "" + +#: templates/faq.html:87 templates/backup/faq.html:87 +#: templates/tough/faq.html:85 +msgid "delete any comment" +msgstr "" + +#: templates/faq.html:91 templates/backup/faq.html:91 +#: templates/tough/faq.html:89 +msgid "delete any questions and answers and perform other moderation tasks" +msgstr "" + +#: templates/faq.html:98 templates/backup/faq.html:98 +msgid "To register, do I need to create new password?" +msgstr "" + +#: templates/faq.html:99 templates/backup/faq.html:99 +#: templates/tough/faq.html:97 +msgid "" +"No, you don't have to. You can login through any service that supports " +"OpenID, e.g. Google, Yahoo, AOL, etc." +msgstr "" + +#: templates/faq.html:100 templates/backup/faq.html:100 +#: templates/tough/faq.html:98 +msgid "Login now!" +msgstr "" + +#: templates/faq.html:103 templates/backup/faq.html:103 +#: templates/tough/faq.html:101 +msgid "Why other people can edit my questions/answers?" +msgstr "" + +#: templates/faq.html:104 templates/backup/faq.html:104 +#: templates/tough/faq.html:102 +msgid "Goal of this site is..." +msgstr "" + +#: templates/faq.html:104 templates/backup/faq.html:104 +#: templates/tough/faq.html:102 +msgid "" +"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." +msgstr "" + +#: templates/faq.html:105 templates/backup/faq.html:105 +#: templates/tough/faq.html:103 +msgid "If this approach is not for you, we respect your choice." +msgstr "" + +#: templates/faq.html:107 templates/backup/faq.html:107 +#: templates/tough/faq.html:105 +msgid "Still have questions?" +msgstr "" + +#: templates/faq.html:108 templates/backup/faq.html:108 +msgid "Please ask your question, help make our community better!" +msgstr "" + +#: templates/faq.html:108 templates/header.html:29 templates/header.html.py:60 +#: templates/backup/faq.html:108 templates/backup/header.html:29 +#: templates/backup/header.html.py:58 templates/tough/faq.html:106 msgid "questions" msgstr "" +#: templates/faq.html:108 templates/index.html:121 +#: templates/backup/faq.html:108 templates/backup/index.html:120 +#: templates/tough/faq.html:106 +msgid "." +msgstr "" + +#: templates/footer.html:7 templates/header.html:12 templates/index.html:83 +#: templates/backup/footer.html:7 templates/backup/header.html:12 +#: templates/backup/index.html:83 +msgid "about" +msgstr "" + +#: templates/footer.html:8 templates/header.html:13 templates/index.html:84 +#: templates/backup/footer.html:8 templates/backup/header.html:13 +#: templates/backup/index.html:84 +msgid "faq" +msgstr "" + +#: templates/footer.html:9 templates/backup/footer.html:9 +msgid "blog" +msgstr "" + +#: templates/footer.html:10 templates/backup/footer.html:10 +msgid "contact us" +msgstr "" + +#: templates/footer.html:11 templates/backup/footer.html:11 +msgid "privacy policy" +msgstr "" + +#: templates/footer.html:12 templates/backup/footer.html:12 +msgid "give feedback" +msgstr "" + +#: templates/footer.html:18 templates/backup/footer.html:18 +msgid "current revision" +msgstr "" + +#: templates/header.html:8 templates/backup/header.html:8 +msgid "logout" +msgstr "" + +#: templates/header.html:10 templates/authopenid/signup.html:39 +#: templates/backup/header.html:10 +msgid "login" +msgstr "" + +#: templates/header.html:23 templates/backup/header.html:23 +msgid "back to home page" +msgstr "" + #: templates/header.html:31 templates/header.html.py:62 +#: templates/backup/header.html:31 templates/backup/header.html.py:60 msgid "users" msgstr "" -#: templates/header.html:32 +#: templates/header.html:32 templates/backup/header.html:32 msgid "books" msgstr "" -#: templates/header.html:34 templates/index.html:120 +#: templates/header.html:34 templates/index.html:121 +#: templates/backup/header.html:34 templates/backup/index.html:120 msgid "unanswered questions" -msgstr "" +msgstr "unanswered" -#: templates/header.html:38 +#: templates/header.html:38 templates/backup/header.html:37 msgid "my profile" msgstr "" -#: templates/header.html:42 +#: templates/header.html:42 templates/backup/header.html:40 msgid "ask a question" msgstr "" -#: templates/header.html:57 +#: templates/header.html:57 templates/backup/header.html:55 msgid "search" msgstr "" -#: templates/index.html:6 +#: templates/index.html:6 templates/backup/index.html:6 msgid "Home" msgstr "" -#: templates/index.html:21 +#: templates/index.html:7 templates/backup/index.html:7 +msgid "meta site keywords, comma separated" +msgstr "" + +#: templates/index.html:21 templates/questions.html:7 +#: templates/backup/index.html:21 templates/backup/questions.html:6 msgid "Questions" msgstr "" -#: templates/index.html:23 +#: templates/index.html:23 templates/backup/index.html:23 msgid "last updated questions" msgstr "" -#: templates/index.html:23 templates/unanswered.html:20 +#: templates/index.html:23 templates/questions.html:25 +#: templates/unanswered.html:20 templates/backup/index.html:23 +#: templates/backup/questions.html:24 templates/backup/unanswered.html:19 +#: templates/tough/unanswered.html:18 msgid "newest" msgstr "" -#: templates/index.html:24 +#: templates/index.html:24 templates/questions.html:27 +#: templates/backup/index.html:24 templates/backup/questions.html:26 msgid "hottest questions" msgstr "" -#: templates/index.html:24 +#: templates/index.html:24 templates/questions.html:27 +#: templates/backup/index.html:24 templates/backup/questions.html:26 msgid "hottest" msgstr "" -#: templates/index.html:25 +#: templates/index.html:25 templates/questions.html:28 +#: templates/backup/index.html:25 templates/backup/questions.html:27 msgid "most voted questions" msgstr "" -#: templates/index.html:25 +#: templates/index.html:25 templates/questions.html:28 +#: templates/backup/index.html:25 templates/backup/questions.html:27 msgid "most voted" msgstr "" -#: templates/index.html:26 +#: templates/index.html:26 templates/backup/index.html:26 msgid "all questions" msgstr "" -#: templates/index.html:46 templates/unanswered.html:36 -#: templates/users_questions.html:35 +#: templates/index.html:46 templates/questions.html:45 +#: templates/unanswered.html:36 templates/users_questions.html:35 +#: templates/backup/index.html:46 templates/backup/questions.html:44 +#: templates/backup/unanswered.html:35 +#: templates/backup/users_questions.html:34 templates/tough/unanswered.html:34 msgid "answers" msgstr "" #: templates/index.html:68 templates/question.html:112 -#: templates/question.html.py:479 templates/tags.html:46 +#: templates/question.html.py:479 templates/questions.html:84 +#: templates/questions.html.py:149 templates/tags.html:47 #: templates/unanswered.html:75 templates/unanswered.html.py:109 -#: templates/users_questions.html:52 +#: templates/users_questions.html:52 templates/backup/index.html:68 +#: templates/backup/index.html.py:93 templates/backup/question.html:111 +#: templates/backup/question.html.py:469 templates/backup/questions.html:83 +#: templates/backup/questions.html:148 templates/backup/tags.html:46 +#: templates/backup/unanswered.html:74 templates/backup/unanswered.html:108 +#: templates/backup/users_questions.html:51 templates/tough/unanswered.html:72 +#: templates/tough/unanswered.html:105 msgid "see questions tagged" msgstr "" -#: templates/index.html:79 +#: templates/index.html:79 templates/backup/index.html:79 msgid "welcome to website" msgstr "" -#: templates/index.html:88 +#: templates/index.html:81 templates/backup/index.html:81 +msgid "what is this website" +msgstr "" + +#: templates/index.html:82 templates/backup/index.html:82 +msgid "what can one do on this website" +msgstr "" + +#: templates/index.html:89 templates/backup/index.html:89 msgid "Recent tags" msgstr "" -#: templates/index.html:93 +#: templates/index.html:94 #, python-format msgid "see questions tagged '%(tagname)s'" msgstr "" -#: templates/index.html:96 templates/index.html.py:120 +#: templates/index.html:97 templates/index.html.py:121 +#: templates/backup/index.html:96 templates/backup/index.html.py:120 msgid "popular tags" msgstr "" -#: templates/index.html:100 +#: templates/index.html:101 templates/backup/index.html:100 msgid "Recent awards" msgstr "" -#: templates/index.html:106 +#: templates/index.html:107 templates/backup/index.html:106 msgid "given to" msgstr "" -#: templates/index.html:111 +#: templates/index.html:112 templates/backup/index.html:111 msgid "all awards" msgstr "" -#: templates/index.html:115 +#: templates/index.html:116 templates/backup/index.html:115 msgid "subscribe to last 30 questions by RSS" msgstr "" -#: templates/index.html:120 +#: templates/index.html:121 templates/backup/index.html:120 msgid "Still looking for more? See" msgstr "" -#: templates/index.html:120 +#: templates/index.html:121 templates/backup/index.html:120 msgid "complete list of quesionts" msgstr "" -#: templates/index.html:120 +#: templates/index.html:121 templates/backup/index.html:120 msgid "or" msgstr "" -#: templates/index.html:120 -msgid "." -msgstr "" - -#: templates/index.html:120 +#: templates/index.html:121 templates/backup/index.html:120 msgid "Please help us answer" msgstr "" #: templates/logout.html:6 templates/logout.html.py:17 +#: templates/backup/logout.html:6 templates/backup/logout.html.py:17 msgid "Logout" msgstr "" -#: templates/logout.html:20 +#: templates/logout.html:20 templates/backup/logout.html:20 msgid "" "As a registered user you can login with your OpenID, log out of the site or " "permanently remove your account." msgstr "" -#: templates/logout.html:21 +#: templates/logout.html:21 templates/backup/logout.html:21 msgid "Logout now" msgstr "" -#: templates/pagesize.html:5 -msgid "Size per page:" +#: templates/pagesize.html:6 templates/backup/pagesize.html:6 +msgid "posts per page" msgstr "" -#: templates/paginator.html:5 -msgid "Previous" +#: templates/paginator.html:6 templates/paginator.html.py:7 +#: templates/backup/paginator.html:5 templates/backup/paginator.html.py:6 +msgid "previous" +msgstr "" + +#: templates/paginator.html:20 templates/backup/paginator.html:19 +msgid "current page" +msgstr "" + +#: templates/paginator.html:23 templates/paginator.html.py:30 +#: templates/backup/paginator.html:22 templates/backup/paginator.html.py:29 +msgid "page number " +msgstr "" + +#: templates/paginator.html:23 templates/paginator.html.py:30 +#: templates/backup/paginator.html:22 templates/backup/paginator.html.py:29 +msgid "number - make blank in english" +msgstr "" + +#: templates/paginator.html:34 templates/backup/paginator.html:33 +msgid "next page" msgstr "" #: templates/privacy.html:6 templates/privacy.html.py:11 +#: templates/backup/privacy.html:5 templates/backup/privacy.html.py:10 msgid "Privacy policy" msgstr "" -#: templates/privacy.html:15 +#: templates/privacy.html:15 templates/backup/privacy.html:14 msgid "general message about privacy" msgstr "" -#: templates/privacy.html:18 +#: templates/privacy.html:18 templates/backup/privacy.html:17 msgid "Site Visitors" msgstr "" -#: templates/privacy.html:20 +#: templates/privacy.html:20 templates/backup/privacy.html:19 msgid "what technical information is collected about visitors" msgstr "" -#: templates/privacy.html:23 +#: templates/privacy.html:23 templates/backup/privacy.html:22 msgid "Personal Information" msgstr "" -#: templates/privacy.html:25 +#: templates/privacy.html:25 templates/backup/privacy.html:24 msgid "details on personal information policies" msgstr "" -#: templates/privacy.html:28 +#: templates/privacy.html:28 templates/backup/privacy.html:27 msgid "Other Services" msgstr "" -#: templates/privacy.html:30 +#: templates/privacy.html:30 templates/backup/privacy.html:29 msgid "details on sharing data with third parties" msgstr "" -#: templates/privacy.html:35 +#: templates/privacy.html:35 templates/backup/privacy.html:34 msgid "cookie policy details" msgstr "" -#: templates/privacy.html:37 +#: templates/privacy.html:37 templates/backup/privacy.html:36 msgid "Policy Changes" msgstr "" -#: templates/privacy.html:38 +#: templates/privacy.html:38 templates/backup/privacy.html:37 msgid "how privacy policies can be changed" msgstr "" #: templates/question.html:66 templates/question.html.py:78 +#: templates/backup/question.html:65 templates/backup/question.html.py:77 msgid "i like this post (click again to cancel)" msgstr "" #: templates/question.html:68 templates/question.html.py:80 -#: templates/question.html:273 +#: templates/question.html:273 templates/backup/question.html:67 +#: templates/backup/question.html.py:79 templates/backup/question.html:272 msgid "current number of votes" msgstr "" #: templates/question.html:73 templates/question.html.py:84 +#: templates/backup/question.html:72 templates/backup/question.html.py:83 msgid "i dont like this post (click again to cancel)" msgstr "" -#: templates/question.html:90 +#: templates/question.html:90 templates/backup/question.html:89 msgid "mark this question as favorite (click again to cancel)" msgstr "" -#: templates/question.html:96 +#: templates/question.html:96 templates/backup/question.html:95 msgid "remove favorite mark from this question (click again to restore mark)" msgstr "" #: templates/question.html:121 templates/question.html.py:304 #: templates/revisions_answer.html:53 templates/revisions_question.html:53 +#: templates/backup/question.html:120 templates/backup/question.html.py:303 +#: templates/backup/revisions_answer.html:52 +#: templates/backup/revisions_question.html:51 msgid "edit" msgstr "" #: templates/question.html:125 templates/question.html.py:314 +#: templates/backup/question.html:124 templates/backup/question.html.py:307 msgid "delete" msgstr "" -#: templates/question.html:130 +#: templates/question.html:130 templates/backup/question.html:129 msgid "reopen" msgstr "" -#: templates/question.html:135 +#: templates/question.html:135 templates/backup/question.html:134 msgid "close" msgstr "" #: templates/question.html:141 templates/question.html.py:327 +#: templates/backup/question.html:140 templates/backup/question.html.py:317 msgid "" "report as offensive (i.e containing spam, advertising, malicious text, etc.)" msgstr "" #: templates/question.html:142 templates/question.html.py:328 +#: templates/backup/question.html:141 templates/backup/question.html.py:318 msgid "flag offensive" msgstr "" #: templates/question.html:154 templates/question.html.py:337 #: templates/revisions_answer.html:65 templates/revisions_question.html:65 +#: templates/backup/question.html:153 templates/backup/question.html.py:327 +#: templates/backup/revisions_answer.html:64 +#: templates/backup/revisions_question.html:63 msgid "updated" msgstr "" #: templates/question.html:203 templates/question.html.py:384 #: templates/revisions_answer.html:63 templates/revisions_question.html:63 +#: templates/backup/question.html:202 templates/backup/question.html.py:374 +#: templates/backup/revisions_answer.html:62 +#: templates/backup/revisions_question.html:61 msgid "asked" msgstr "" #: templates/question.html:233 templates/question.html.py:411 +#: templates/backup/question.html:232 templates/backup/question.html.py:401 msgid "comments" msgstr "" #: templates/question.html:234 templates/question.html.py:412 +#: templates/backup/question.html:233 templates/backup/question.html.py:402 msgid "add comment" msgstr "" -#: templates/question.html:247 +#: templates/question.html:247 templates/backup/question.html:246 #, python-format msgid "" "The question has been closed for the following reason \"%(question." "get_close_reason_display)s\" by" msgstr "" -#: templates/question.html:249 +#: templates/question.html:249 templates/backup/question.html:248 #, python-format msgid "close date %(question.closed_at)s" msgstr "" -#: templates/question.html:256 templates/questions.html:44 -#: templates/user_stats.html:28 +#: templates/question.html:256 templates/user_stats.html:28 +#: templates/backup/question.html:255 templates/backup/user_stats.html:27 msgid "Answers" -msgstr "" +msgstr " Answers" -#: templates/question.html:258 +#: templates/question.html:258 templates/backup/question.html:257 msgid "oldest answers will be shown first" msgstr "" -#: templates/question.html:258 +#: templates/question.html:258 templates/backup/question.html:257 msgid "oldest answers" -msgstr "" +msgstr "oldest" -#: templates/question.html:259 +#: templates/question.html:259 templates/backup/question.html:258 msgid "newest answers will be shown first" msgstr "" -#: templates/question.html:259 +#: templates/question.html:259 templates/backup/question.html:258 msgid "newest answers" -msgstr "" +msgstr "newest" -#: templates/question.html:260 +#: templates/question.html:260 templates/backup/question.html:259 msgid "most voted answers will be shown first" msgstr "" -#: templates/question.html:260 +#: templates/question.html:260 templates/backup/question.html:259 msgid "popular answers" -msgstr "" +msgstr "most voted" -#: templates/question.html:272 +#: templates/question.html:272 templates/backup/question.html:271 msgid "i like this answer (click again to cancel)" msgstr "" -#: templates/question.html:278 +#: templates/question.html:278 templates/backup/question.html:277 msgid "i dont like this answer (click again to cancel)" msgstr "" -#: templates/question.html:284 +#: templates/question.html:284 templates/backup/question.html:283 msgid "mark this answer as favorite (click again to undo)" msgstr "" -#: templates/question.html:289 +#: templates/question.html:289 templates/backup/question.html:288 msgid "the author of the question has selected this answer as correct" msgstr "" @@ -1240,294 +1734,295 @@ msgstr "" msgid "undelete" msgstr "" -#: templates/question.html:321 +#: templates/question.html:321 templates/backup/question.html:311 msgid "answer permanent link" msgstr "" -#: templates/question.html:322 +#: templates/question.html:322 templates/backup/question.html:312 msgid "permanent link" msgstr "" -#: templates/question.html:436 +#: templates/question.html:436 templates/backup/question.html:426 msgid "Your answer" msgstr "" -#: templates/question.html:460 +#: templates/question.html:460 templates/backup/question.html:450 msgid "Answer the question" msgstr "" -#: templates/question.html:462 +#: templates/question.html:462 templates/backup/question.html:452 msgid "Login to answer" msgstr "" -#: templates/question.html:474 +#: templates/question.html:474 templates/backup/question.html:464 msgid "Question tags" -msgstr "" +msgstr "Tags" -#: templates/question.html:484 +#: templates/question.html:484 templates/backup/question.html:474 msgid "question asked" -msgstr "" +msgstr "Asked" #: templates/question.html:484 templates/question.html.py:490 -#: templates/user_info.html:51 +#: templates/user_info.html:51 templates/backup/question.html:474 +#: templates/backup/question.html.py:480 templates/backup/user_info.html:50 msgid "ago" msgstr "" -#: templates/question.html:487 +#: templates/question.html:487 templates/backup/question.html:477 msgid "question was seen" -msgstr "" +msgstr "Seen" -#: templates/question.html:487 +#: templates/question.html:487 templates/backup/question.html:477 msgid "times" msgstr "" -#: templates/question.html:490 +#: templates/question.html:490 templates/backup/question.html:480 msgid "last updated" -msgstr "" +msgstr "Last updated" -#: templates/question.html:495 +#: templates/question.html:495 templates/backup/question.html:485 msgid "Related questions" msgstr "" #: templates/question_edit.html:4 templates/question_edit.html.py:65 +#: templates/backup/question_edit.html:2 +#: templates/backup/question_edit.html:63 msgid "Edit question" msgstr "" #: templates/question_edit_tips.html:4 msgid "question tips" -msgstr "" +msgstr "Tips" #: templates/question_edit_tips.html:7 +#: templates/backup/question_edit_tips.html:5 msgid "please ask a relevant question" msgstr "" #: templates/question_edit_tips.html:10 +#: templates/backup/question_edit_tips.html:8 msgid "please try provide enough details" -msgstr "" - -#: templates/question_edit_tips.html:13 -msgid "be clear and concise" -msgstr "" +msgstr "provide enough details" -#: templates/question_edit_tips.html:16 -msgid "see frequently asked questions" -msgstr "" +#: templates/questions.html:23 templates/backup/questions.html:22 +msgid "Found by tags" +msgstr "Tagged questions" -#: templates/question_edit_tips.html:22 -msgid "Markdown tips" -msgstr "" - -#: templates/question_edit_tips.html:25 -msgid "*italic* or __italic__" -msgstr "" - -#: templates/question_edit_tips.html:28 -msgid "**bold** or __bold__" -msgstr "" - -#: templates/question_edit_tips.html:31 -msgid "link" -msgstr "" - -#: templates/question_edit_tips.html:31 templates/question_edit_tips.html:36 -msgid "text" -msgstr "" - -#: templates/question_edit_tips.html:36 -msgid "image" -msgstr "" - -#: templates/question_edit_tips.html:40 -msgid "numbered list:" +#: templates/questions.html:23 templates/backup/questions.html:22 +msgid "Found by title" msgstr "" -#: templates/question_edit_tips.html:45 -msgid "basic HTML tags are also supported" -msgstr "" - -#: templates/question_edit_tips.html:48 -msgid "learn more about Markdown" -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:22 +#: templates/questions.html:23 templates/backup/questions.html:22 msgid "All questions" msgstr "" -#: templates/questions.html:24 -msgid "New questions" +#: templates/questions.html:25 templates/unanswered.html:20 +#: templates/backup/questions.html:24 templates/backup/unanswered.html:19 +#: templates/tough/unanswered.html:18 +msgid "most recently asked questions" msgstr "" -#: templates/questions.html:24 -msgid "Newest" +#: templates/questions.html:26 templates/backup/questions.html:25 +msgid "most recently updated questions" msgstr "" -#: templates/questions.html:25 -msgid "Newest updated questions" +#: templates/questions.html:26 templates/backup/questions.html:25 +msgid "active" msgstr "" -#: templates/questions.html:25 -msgid "Active" -msgstr "" +#: templates/questions.html:109 +#, python-format +msgid "" +"\n" +"\t\t\thave total %(q_num)s questions tagged %(tagname)s\n" +"\t\t\t" +msgid_plural "" +"\n" +"\t\t\thave total %(q_num)s questions tagged %(tagname)s\n" +"\t\t\t" +msgstr[0] "" +"\n" +"<div class=\"questions-count\">%(q_num)s</div><p>question tagged</p><p><span " +"class=\"tag\">%(tagname)s</span></p>" +msgstr[1] "" +"\n" +"<div class=\"questions-count\">%(q_num)s</div><p>questions tagged</" +"p><p><span class=\"tag\">%(tagname)s</span></p>" + +#: templates/questions.html:116 +#, python-format +msgid "" +"\n" +"\t\t\thave total %(q_num)s questions containing %(searchtitle)s\n" +"\t\t\t" +msgid_plural "" +"\n" +"\t\t\thave total %(q_num)s questions containing %(searchtitle)s\n" +"\t\t\t" +msgstr[0] "" +"\n" +"<div class=\"questions-count\">%(q_num)s</div><p>question with title " +"containing <strong><span class=\"darkred\">%(searchtitle)s</span></strong></" +"p>" +msgstr[1] "" +"\n" +"<div class=\"questions-count\">%(q_num)s</div><p>questions with title " +"containing <strong><span class=\"darkred\">%(searchtitle)s</span></strong></" +"p>" -#: templates/questions.html:26 -msgid "Questions with most answers" -msgstr "" +#: templates/questions.html:124 +msgid "latest questions info" +msgstr "<strong>Newest</strong> questions are shown first." -#: templates/questions.html:26 -msgid "Hottest" +#: templates/questions.html:128 templates/backup/questions.html:127 +msgid "Questions are sorted by the <strong>time of last update</strong>." msgstr "" -#: templates/questions.html:27 -msgid "Questions with most votes" +#: templates/questions.html:129 templates/backup/questions.html:128 +msgid "Most recently answered ones are shown first." msgstr "" -#: templates/questions.html:27 -msgid "Best" +#: templates/questions.html:133 templates/backup/questions.html:132 +msgid "Questions sorted by <strong>number of responses</strong>." msgstr "" -#: templates/questions.html:45 -msgid "Votes" +#: templates/questions.html:134 templates/backup/questions.html:133 +msgid "Most answered questions are shown first." msgstr "" -#: templates/questions.html:46 -msgid "Visits" +#: templates/questions.html:138 templates/backup/questions.html:137 +msgid "Questions are sorted by the <strong>number of votes</strong>." msgstr "" -#: templates/questions.html:57 templates/questions.html.py:69 -msgid "Community wiki" +#: templates/questions.html:139 templates/backup/questions.html:138 +msgid "Most voted questions are shown first." msgstr "" -#: templates/questions.html:83 -msgid "Browse questions with tag of " -msgstr "" - -#: templates/questions.html:125 templates/unanswered.html:105 +#: templates/questions.html:146 templates/unanswered.html:105 +#: templates/backup/questions.html:145 templates/backup/unanswered.html:104 +#: templates/tough/unanswered.html:101 msgid "Related tags" -msgstr "" +msgstr "Tags" #: templates/reopen.html:6 templates/reopen.html.py:16 +#: templates/backup/reopen.html:4 templates/backup/reopen.html.py:14 msgid "Reopen question" msgstr "" -#: templates/reopen.html:19 +#: templates/reopen.html:19 templates/backup/reopen.html:17 msgid "Open the previously closed question" msgstr "" -#: templates/reopen.html:22 +#: templates/reopen.html:22 templates/backup/reopen.html:20 msgid "The question was closed for the following reason " msgstr "" -#: templates/reopen.html:22 +#: templates/reopen.html:22 templates/backup/reopen.html:20 msgid "reason - leave blank in english" msgstr "" -#: templates/reopen.html:22 +#: templates/reopen.html:22 templates/backup/reopen.html:20 msgid "on " msgstr "" -#: templates/reopen.html:22 +#: templates/reopen.html:22 templates/backup/reopen.html:20 msgid "date closed" msgstr "" -#: templates/reopen.html:29 +#: templates/reopen.html:29 templates/backup/reopen.html:27 msgid "Reopen this question" msgstr "" #: templates/revisions_answer.html:7 templates/revisions_answer.html.py:36 #: templates/revisions_question.html:8 templates/revisions_question.html:36 +#: templates/backup/revisions_answer.html:6 +#: templates/backup/revisions_answer.html:35 +#: templates/backup/revisions_question.html:6 +#: templates/backup/revisions_question.html:34 msgid "Revision history" msgstr "" -#: templates/tags.html:5 templates/tags.html.py:28 +#: templates/tags.html:6 templates/tags.html.py:29 +#: templates/backup/tags.html:5 templates/backup/tags.html.py:28 msgid "Tag list" msgstr "" -#: templates/tags.html:30 +#: templates/tags.html:31 templates/backup/tags.html:30 msgid "sorted alphabetically" msgstr "" -#: templates/tags.html:30 +#: templates/tags.html:31 templates/backup/tags.html:30 msgid "by name" msgstr "" -#: templates/tags.html:31 +#: templates/tags.html:32 templates/backup/tags.html:31 msgid "sorted by frequency of tag use" msgstr "" -#: templates/tags.html:31 +#: templates/tags.html:32 templates/backup/tags.html:31 msgid "by popularity" msgstr "" -#: templates/tags.html:37 +#: templates/tags.html:38 templates/backup/tags.html:37 msgid "All tags matching query" msgstr "" -#: templates/tags.html:37 +#: templates/tags.html:38 templates/backup/tags.html:37 msgid "all tags - make this empty in english" msgstr "" -#: templates/tags.html:40 +#: templates/tags.html:41 templates/backup/tags.html:40 msgid "Nothing found" msgstr "" #: templates/unanswered.html:7 templates/unanswered.html.py:18 +#: templates/backup/unanswered.html:6 templates/backup/unanswered.html:17 +#: templates/tough/unanswered.html:5 templates/tough/unanswered.html.py:16 msgid "Unanswered questions" msgstr "" -#: templates/unanswered.html:20 -msgid "most recently asked questions" -msgstr "" - #: templates/unanswered.html:97 #, python-format msgid "have %(num_q)s unanswered questions" msgstr "" +"<div class=\"questions-count\">%(num_q)s</div><strong>unanswered</strong> " +"questions" -#: templates/unanswered.html:99 +#: templates/unanswered.html:99 templates/backup/questions.html:107 +#: templates/backup/unanswered.html:97 msgid "Have a total of" msgstr "" -#: templates/user_edit.html:6 +#: templates/user_edit.html:6 templates/backup/user_edit.html:4 msgid "Edit user profile" msgstr "" -#: templates/user_edit.html:19 +#: templates/user_edit.html:19 templates/backup/user_edit.html:17 msgid "edit profile" msgstr "" -#: templates/user_edit.html:31 +#: templates/user_edit.html:31 templates/backup/user_edit.html:29 msgid "image associated with your email address" msgstr "" -#: templates/user_edit.html:31 +#: templates/user_edit.html:31 templates/backup/user_edit.html:29 msgid "avatar" msgstr "" #: templates/user_edit.html:36 templates/user_info.html:31 +#: templates/backup/user_edit.html:34 templates/backup/user_info.html:30 msgid "Registered user" msgstr "" -#: templates/user_edit.html:82 +#: templates/user_edit.html:82 templates/backup/user_edit.html:80 msgid "Update" msgstr "" -#: templates/user_info.html:34 +#: templates/user_info.html:34 templates/backup/user_info.html:33 msgid "update profile" msgstr "" -#: templates/user_info.html:40 +#: templates/user_info.html:40 templates/backup/user_info.html:39 msgid "real name" msgstr "" @@ -1535,35 +2030,35 @@ msgstr "" msgid "member for" msgstr "" -#: templates/user_info.html:50 +#: templates/user_info.html:50 templates/backup/user_info.html:49 msgid "last seen" msgstr "" -#: templates/user_info.html:56 +#: templates/user_info.html:56 templates/backup/user_info.html:55 msgid "user website" msgstr "" -#: templates/user_info.html:62 +#: templates/user_info.html:62 templates/backup/user_info.html:61 msgid "location" msgstr "" -#: templates/user_info.html:69 +#: templates/user_info.html:69 templates/backup/user_info.html:68 msgid "age" msgstr "" -#: templates/user_info.html:70 +#: templates/user_info.html:70 templates/backup/user_info.html:69 msgid "age unit" msgstr "" -#: templates/user_info.html:75 +#: templates/user_info.html:75 templates/backup/user_info.html:74 msgid "todays unused votes" msgstr "" -#: templates/user_info.html:76 +#: templates/user_info.html:76 templates/backup/user_info.html:75 msgid "votes left" msgstr "" -#: templates/user_stats.html:15 +#: templates/user_stats.html:15 templates/backup/user_stats.html:14 msgid "User questions" msgstr "" @@ -1572,94 +2067,87 @@ msgstr "" msgid "the answer has been voted for %(vote_count)s times" msgstr "" -#: templates/user_stats.html:37 +#: templates/user_stats.html:37 templates/backup/user_stats.html:36 msgid "this answer has been selected as correct" msgstr "" -#: templates/user_stats.html:43 +#: templates/user_stats.html:43 templates/backup/user_stats.html:42 #, python-format msgid "the answer has been commented %(answered_question.comment_count)s times" msgstr "" -#: templates/user_stats.html:56 +#: templates/user_stats.html:56 templates/backup/user_stats.html:55 msgid "votes total" -msgstr "" +msgstr "Votes" -#: templates/user_stats.html:65 +#: templates/user_stats.html:65 templates/backup/user_stats.html:64 msgid "user has voted up this many times" msgstr "" -#: templates/user_stats.html:70 +#: templates/user_stats.html:70 templates/backup/user_stats.html:69 msgid "user voted down this many times" msgstr "" -#: templates/user_stats.html:84 +#: templates/user_stats.html:84 templates/backup/user_stats.html:83 msgid "Tags" msgstr "" -#: templates/user_stats.html:94 +#: templates/user_stats.html:94 templates/backup/user_stats.html:93 #, python-format msgid "see other questions tagged '%(tag)s' " msgstr "" -#: templates/user_tabs.html:7 +#: templates/user_tabs.html:7 templates/backup/user_tabs.html:6 msgid "User profile" msgstr "" -#: templates/user_tabs.html:16 +#: templates/user_tabs.html:16 templates/backup/user_tabs.html:15 msgid "graph of user reputation" msgstr "" -#: templates/user_tabs.html:17 +#: templates/user_tabs.html:17 templates/backup/user_tabs.html:16 msgid "reputation history" msgstr "" -#: templates/user_tabs.html:24 +#: templates/user_tabs.html:24 templates/backup/user_tabs.html:23 msgid "favorites" msgstr "" -#: templates/user_tabs.html:29 +#: templates/user_tabs.html:29 templates/backup/user_tabs.html:28 msgid "settings" msgstr "" -#: templates/user_votes.html:14 -msgid "upvote" -msgstr "" - -#: templates/user_votes.html:16 -msgid "downvote" -msgstr "" - -#: templates/users.html:5 templates/users.html.py:23 +#: templates/users.html:6 templates/users.html.py:24 +#: templates/backup/users.html:5 templates/backup/users.html.py:23 msgid "Users" msgstr "" -#: templates/users.html:26 +#: templates/users.html:27 templates/backup/users.html:26 msgid "recent" msgstr "" -#: templates/users.html:27 +#: templates/users.html:28 templates/backup/users.html:27 msgid "oldest" msgstr "" -#: templates/users.html:28 +#: templates/users.html:29 templates/backup/users.html:28 msgid "by username" msgstr "" -#: templates/users.html:34 +#: templates/users.html:35 templates/backup/users.html:34 #, python-format msgid "users matching query %(suser)s:" msgstr "" -#: templates/users.html:38 +#: templates/users.html:39 templates/backup/users.html:38 msgid "Nothing found." msgstr "" -#: templates/users_questions.html:11 +#: templates/users_questions.html:11 templates/backup/users_questions.html:10 msgid "this questions was selected as favorite" msgstr "" -#: templates/users_questions.html:33 +#: templates/users_questions.html:33 templates/backup/users_questions.html:32 msgid "this answer has been accepted to be correct" msgstr "" @@ -1686,7 +2174,7 @@ msgid "Email" msgstr "" #: templates/authopenid/changeemail.html:29 -#: templates/authopenid/signin.html:60 +#: templates/authopenid/signin.html:59 msgid "Password" msgstr "" @@ -1752,7 +2240,7 @@ msgid "This account already exists, please use another." msgstr "" #: templates/authopenid/complete.html:16 templates/authopenid/complete.html:29 -#: templates/authopenid/signin.html:43 +#: templates/authopenid/signin.html:42 msgid "Sorry, looks like we have some errors:" msgstr "" @@ -1788,7 +2276,7 @@ msgstr "" msgid "Register" msgstr "" -#: templates/authopenid/complete.html:62 templates/authopenid/signin.html:62 +#: templates/authopenid/complete.html:62 templates/authopenid/signin.html:61 msgid "Forgot your password?" msgstr "" @@ -1885,6 +2373,8 @@ msgstr "" #: templates/authopenid/signin.html:21 msgid "we support two login modes" msgstr "" +"You can log in either through one of these services or traditionally - using " +"local username/password." #: templates/authopenid/signin.html:26 templates/authopenid/signup.html:49 msgid "Login with your OpenID" @@ -1892,49 +2382,53 @@ msgstr "" #: templates/authopenid/signin.html:28 msgid "select openid provider" -msgstr "" +msgstr "1) Please select your id service provider." #: templates/authopenid/signin.html:32 msgid "verify openid link and login" msgstr "" +"2) Please verify the OpenID URL (type your login name over {username}, if present)" +" and then log in." -#: templates/authopenid/signin.html:58 +#: templates/authopenid/signin.html:57 msgid "Use login name and password" msgstr "" -#: templates/authopenid/signin.html:59 +#: templates/authopenid/signin.html:58 msgid "Login name" msgstr "" -#: templates/authopenid/signin.html:63 +#: templates/authopenid/signin.html:62 msgid "Create new acccount" msgstr "" -#: templates/authopenid/signin.html:72 +#: templates/authopenid/signin.html:71 msgid "Why use OpenID?" msgstr "" -#: templates/authopenid/signin.html:76 +#: templates/authopenid/signin.html:75 msgid "with openid it is easier" -msgstr "" +msgstr "With the OpenID you don't need to create new username and password." -#: templates/authopenid/signin.html:79 +#: templates/authopenid/signin.html:78 msgid "reuse openid" -msgstr "" +msgstr "You can safely re-use the same login for all OpenID-enabled websites." -#: templates/authopenid/signin.html:82 +#: templates/authopenid/signin.html:81 msgid "openid is widely adopted" msgstr "" +"There are > 160,000,000 OpenID account in use. Over 10,000 sites are OpenID-" +"enabled." -#: templates/authopenid/signin.html:85 +#: templates/authopenid/signin.html:84 msgid "openid is supported open standard" -msgstr "" +msgstr "OpenID is based on an open standard, supported by many organizations." -#: templates/authopenid/signin.html:89 +#: templates/authopenid/signin.html:88 msgid "Find out more" msgstr "" -#: templates/authopenid/signin.html:90 +#: templates/authopenid/signin.html:89 msgid "Get OpenID" msgstr "" @@ -1971,3 +2465,76 @@ msgstr "" #: templates/authopenid/signup.html:46 msgid "Register with your OpenID" msgstr "" + +# +#: templates/backup/answer_edit_tips.html:3 +#: templates/backup/question_edit_tips.html:2 +msgid "editing tips" +msgstr "Tips" + +#: templates/backup/questions.html:108 +msgid "number of questions" +msgstr "" + +#: templates/backup/questions.html:110 +msgid "tagged with" +msgstr "" + +#: templates/backup/questions.html:116 +msgid "whose title contains" +msgstr "" + +#: templates/backup/questions.html:121 +msgid "number of questions end of sentence." +msgstr "" + +#: templates/backup/questions.html:123 +msgid "Questions are sorted by <strong>entry date</strong>." +msgstr "" + +#: templates/backup/questions.html:123 +msgid "Newest questions shown first." +msgstr "" +"Questions are sorted by <strong>entry date</strong>.Newest questions shown " +"first." + +#: templates/backup/unanswered.html:98 templates/tough/unanswered.html:95 +msgid "number of <strong>unanswered</strong> questions" +msgstr "" + +#: templates/backup/user_info.html:44 +msgid "member since" +msgstr "" + +#: templates/backup/user_stats.html:36 +#, python-format +msgid "the answer has been voted for %(answered_question.vote_count)s times" +msgstr "" + +#: templates/tough/question_retag.html:2 +msgid "Revise tags" +msgstr "" + +#: templates/tough/question_retag.html:37 +msgid "tags are requried" +msgstr "" + +#: templates/tough/question_retag.html:38 +msgid "up to 5 tags, less than 20 characters each" +msgstr "" + +#: templates/tough/question_retag.html:51 +msgid "Change tags" +msgstr "" + +#: templates/tough/question_retag.html:74 +msgid "Change now" +msgstr "" + +#: templates/tough/question_retag.html:85 +msgid "Why use and modify tags?" +msgstr "" + +#: templates/tough/question_retag.html:96 +msgid "tag editors receive special awards from the community" +msgstr "" diff --git a/locale/es/LC_MESSAGES/django.mo b/locale/es/LC_MESSAGES/django.mo Binary files differdeleted file mode 100644 index 8c359972..00000000 --- a/locale/es/LC_MESSAGES/django.mo +++ /dev/null diff --git a/locale/es/LC_MESSAGES/django.po b/locale/es/LC_MESSAGES/django.po index 93cfdfe4..fe0aab7c 100644 --- a/locale/es/LC_MESSAGES/django.po +++ b/locale/es/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-07-28 15:57+0000\n" +"POT-Creation-Date: 2009-07-23 01:11-0300\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" @@ -16,120 +16,128 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: settings.py:12 +#: settings.py:27 msgid "account/" -msgstr "" +msgstr "cuenta/" -#: settings.py:12 django_authopenid/urls.py:9 django_authopenid/urls.py:11 +#: settings.py:27 django_authopenid/urls.py:9 django_authopenid/urls.py:11 msgid "signin/" -msgstr "" +msgstr "ingresar/" #: django_authopenid/forms.py:67 django_authopenid/views.py:93 msgid "i-names are not supported" -msgstr "" +msgstr "i-names no son soportados" #: django_authopenid/forms.py:102 django_authopenid/forms.py:207 msgid "" "Usernames can only contain letters, numbers and " "underscores" msgstr "" +"Los nombres de usuario solo pueden contener letras, números y guión bajo" #: django_authopenid/forms.py:109 msgid "" "This username does not exist in our database. Please " "choose another." msgstr "" +"Este nombre de usuario no existe en nuestra base de datos. Por favor elija " +"otro." #: 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 "" +"Por favor ingrese un usuario y contraseña validos. Ambos campos son " +"sensibles a mayúsculas y minúsculas." #: django_authopenid/forms.py:130 django_authopenid/forms.py:235 msgid "This account is inactive." -msgstr "" +msgstr "Esta cuenta esta inactiva." #: django_authopenid/forms.py:158 msgid "invalid user name" -msgstr "" +msgstr "nombre de usuario no valido" #: django_authopenid/forms.py:160 msgid "sorry, this name can not be used, please try another" msgstr "" +"perdón, pero este nombre de usuario no puede ser usado, intente con otro" #: django_authopenid/forms.py:162 msgid "username too short" -msgstr "" +msgstr "nombre de usuario muy corto" #: django_authopenid/forms.py:170 django_authopenid/forms.py:171 msgid "this name is already in use - please try anoter" -msgstr "" +msgstr "este nombre ya está tomado - por favor intente con otro" #: django_authopenid/forms.py:184 msgid "" "This email is already registered in our database. Please " "choose another." msgstr "" +"Este email ya está registrado en nuestra base de datos. Por favor, intente " +"con otro." #: django_authopenid/forms.py:214 msgid "" "This username don't exist. Please choose another." -msgstr "" +msgstr "Este nombre de usuario no existe, por favor ingrese otro." #: django_authopenid/forms.py:253 msgid "choose a username" -msgstr "" +msgstr "elija un nombre de usuario" #: django_authopenid/forms.py:255 templates/authopenid/signup.html:36 msgid "your email address" -msgstr "" +msgstr "su email (correo electrónico)" #: django_authopenid/forms.py:257 templates/authopenid/signup.html:37 msgid "choose password" -msgstr "" +msgstr "elija una contraseña" #: django_authopenid/forms.py:259 templates/authopenid/signup.html:38 msgid "retype password" -msgstr "" +msgstr "re-ingrese la contraseña" #: django_authopenid/forms.py:330 msgid "" "Old password is incorrect. Please enter the correct " "password." -msgstr "" +msgstr "La antigua contraseña es incorrecta. Por favor ingrese la correcta" #: django_authopenid/forms.py:342 msgid "new passwords do not match" -msgstr "" +msgstr "la nueva contraseña no coincide" #: django_authopenid/forms.py:434 msgid "Incorrect username." -msgstr "" +msgstr "Nombre de usuario incorrecto" #: django_authopenid/urls.py:10 msgid "signout/" -msgstr "" +msgstr "salir/" #: django_authopenid/urls.py:11 msgid "complete/" -msgstr "" +msgstr "completado/" #: django_authopenid/urls.py:13 msgid "register/" -msgstr "" +msgstr "registrarse/" #: django_authopenid/urls.py:14 msgid "signup/" -msgstr "" +msgstr "registrarse/" #: django_authopenid/urls.py:16 msgid "sendpw/" -msgstr "" +msgstr "enviarcontrasena/" #: django_authopenid/urls.py:26 msgid "delete/" -msgstr "" +msgstr "borrar/" #: django_authopenid/views.py:99 #, python-format @@ -138,50 +146,50 @@ msgstr "" #: django_authopenid/views.py:366 msgid "Welcome" -msgstr "" +msgstr "Bienvenido" #: django_authopenid/views.py:456 msgid "Password changed." -msgstr "" +msgstr "Contraseña modificada" #: django_authopenid/views.py:488 msgid "Email changed." -msgstr "" +msgstr "Email modificado." #: django_authopenid/views.py:519 django_authopenid/views.py:671 #, python-format msgid "No OpenID %s found associated in our database" -msgstr "" +msgstr "La OpenID %s no esta asociada en nuestra base de datos" #: 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 "" +msgstr "La OpenID %s no esta asociada al usuario actualmente autenticado" #: django_authopenid/views.py:531 msgid "Email Changed." -msgstr "" +msgstr "Email modificado" #: django_authopenid/views.py:606 msgid "This OpenID is already associated with another account." -msgstr "" +msgstr "Esta OpenID ya está asociada a otra cuenta." #: django_authopenid/views.py:611 #, python-format msgid "OpenID %s is now associated with your account." -msgstr "" +msgstr "La OpenID %s está ahora asociada con tu cuenta." #: django_authopenid/views.py:681 msgid "Account deleted." -msgstr "" +msgstr "Cuenta borrada." #: django_authopenid/views.py:721 msgid "Request for new password" -msgstr "" +msgstr "Pedir nueva contraseña" #: django_authopenid/views.py:734 msgid "A new password has been sent to your email address." -msgstr "" +msgstr "Una nueva contraseña ha sido enviada a tu cuenta de Email." #: django_authopenid/views.py:764 #, python-format @@ -189,995 +197,1379 @@ msgid "" "Could not change password. Confirmation key '%s' is not " "registered." msgstr "" +"No se ha podido modificar la contraseña. La clave de confirmación '%s' no " +"está registrada" #: django_authopenid/views.py:773 msgid "" "Can not change password. User don't exist anymore in our " "database." msgstr "" +"No se puede cambiar la contraseña. El usuario no existe más en nuestra base " +"de datos." #: django_authopenid/views.py:782 #, python-format msgid "Password changed for %s. You may now sign in." -msgstr "" +msgstr "Contraseña cambiada por %s. Ahora puedes ingresar." #: forum/const.py:8 msgid "duplicate question" -msgstr "" +msgstr "pregunta duplicada" #: forum/const.py:9 msgid "question if off-topic or not relevant" -msgstr "" +msgstr "pregunta esta fuera de tema o no es relevante" #: forum/const.py:10 msgid "too subjective and argumentative" -msgstr "" +msgstr "demasiado subjetiva o argumentativa" #: forum/const.py:11 msgid "is not an answer to the question" -msgstr "" +msgstr "no es una respuesta a la pregunta" #: forum/const.py:12 msgid "the question is answered, right answer was accepted" -msgstr "" +msgstr "la pregunta esta respondida, se ha aceptado la respuesta correcta" #: forum/const.py:13 msgid "problem is not reproducible or outdated" -msgstr "" +msgstr "el problema no es reproducible o caducó" #: forum/const.py:15 msgid "question contains offensive inappropriate, or malicious remarks" -msgstr "" +msgstr "la pregunta contiene frases ofensivas, inapropiadas o maliciosas." #: forum/const.py:16 msgid "spam or advertising" -msgstr "" +msgstr "spam o publicidad" #: forum/const.py:56 msgid "question" -msgstr "" +msgstr "pregunta" #: forum/const.py:57 templates/book.html:110 msgid "answer" -msgstr "" +msgstr "resputa" #: forum/const.py:58 msgid "commented question" -msgstr "" +msgstr "pregunta comentada" #: forum/const.py:59 msgid "commented answer" -msgstr "" +msgstr "respuesta comentada" #: forum/const.py:60 msgid "edited question" -msgstr "" +msgstr "pregunta editada" #: forum/const.py:61 msgid "edited answer" -msgstr "" +msgstr "respuesta editada" #: forum/const.py:62 msgid "received award" -msgstr "" +msgstr "premio recibido" #: forum/const.py:63 msgid "marked best answer" -msgstr "" +msgstr "marcada como mejor respuesta" #: forum/const.py:64 msgid "upvoted" -msgstr "" +msgstr "votada positivo" #: forum/const.py:65 msgid "downvoted" -msgstr "" +msgstr "votada negativo" #: forum/const.py:66 msgid "canceled vote" -msgstr "" +msgstr "voto cancelado" #: forum/const.py:67 msgid "deleted question" -msgstr "" +msgstr "pregunta borrada" #: forum/const.py:68 msgid "deleted answer" -msgstr "" +msgstr "respuesta borrada" #: forum/const.py:69 msgid "marked offensive" -msgstr "" +msgstr "marcada como ofensiva" #: forum/const.py:70 msgid "updated tags" -msgstr "" +msgstr "etiquetas actualizadas" #: forum/const.py:71 msgid "selected favorite" -msgstr "" +msgstr "seleccionada como favorita" #: forum/const.py:72 msgid "completed user profile" -msgstr "" +msgstr "completó perfil de usuario" #: forum/const.py:83 msgid "[closed]" -msgstr "" +msgstr "[cerrada]" #: forum/const.py:84 msgid "[deleted]" -msgstr "" +msgstr "[borrada]" #: forum/const.py:85 msgid "initial version" -msgstr "" +msgstr "versión inicial" #: forum/const.py:86 msgid "retagged" -msgstr "" +msgstr "re-etiquetada" -#: forum/feed.py:17 +#: forum/feed.py:17 templates/base.html:7 templates/base_content.html:6 +#: templates/faq.html:25 templates/faq.html.py:108 templates/tough/faq.html:23 +#: templates/tough/faq.html.py:106 templates/tough/question_retag.html:89 msgid "site title" -msgstr "" +msgstr "titulo del sitio" #: forum/feed.py:17 msgid " - " -msgstr "" +msgstr " - " -#: forum/feed.py:17 +#: forum/feed.py:17 templates/base.html:7 templates/base_content.html:6 msgid "site slogan" -msgstr "" +msgstr " slogan del sitio" #: forum/feed.py:17 msgid "latest questions" -msgstr "" +msgstr "últimas preguntas" -#: forum/feed.py:20 +#: forum/feed.py:20 templates/index.html:8 msgid "meta site content" -msgstr "" +msgstr "meta descripción" #: forum/feed.py:22 msgid "copyright message" -msgstr "" +msgstr "mensaje de copyright" -#: forum/forms.py:14 templates/question_edit_tips.html:31 +#: forum/forms.py:14 templates/answer_edit_tips.html:34 +#: templates/answer_edit_tips.html.py:39 templates/question_edit_tips.html:31 #: templates/question_edit_tips.html:36 msgid "title" -msgstr "" +msgstr "titulo" #: forum/forms.py:15 msgid "please enter a descriptive title for your question" -msgstr "" +msgstr "ingrese un titulo descriptivo para su pregunta" #: forum/forms.py:20 msgid "title must be > 10 characters" -msgstr "" +msgstr "el titulo debe tener al menos 10 caracteres" #: forum/forms.py:29 msgid "content" -msgstr "" +msgstr "contenido" #: forum/forms.py:35 msgid "question content must be > 10 characters" -msgstr "" +msgstr "el contenido de la pregunta debe ser al menos de 10 caracteres" #: forum/forms.py:45 templates/header.html:30 templates/header.html.py:61 msgid "tags" -msgstr "" +msgstr "etiquetas" #: forum/forms.py:46 msgid "please use space to separate tags (this enables autocomplete feature)" msgstr "" +"por favor utilice espacio para separar las etiquetas (esto habilitael auto-" +"completado)" #: forum/forms.py:53 msgid "tags are required" -msgstr "" +msgstr "las etiquetas son requeridas" #: forum/forms.py:57 msgid "please use 5 tags or less" -msgstr "" +msgstr "por favor use 5 o menos etiquetas" #: forum/forms.py:60 msgid "tags must be shorter than 20 characters" -msgstr "" +msgstr "las etiquetas deben ser menores a 20 caracteres" #: forum/forms.py:64 msgid "" "please use following characters in tags: letters 'a-z', numbers, and " "characters '.-_#'" msgstr "" +"por favor use solo los siguientes caracteres en los nombres de etiquetas: " +"letras 'a-z', números y caracteres '.-_#'" #: forum/forms.py:74 templates/index.html:56 templates/question.html:196 -#: templates/question.html.py:377 templates/unanswered.html:48 -#: templates/unanswered.html.py:60 +#: templates/question.html.py:377 templates/questions.html:58 +#: templates/questions.html.py:70 templates/unanswered.html:48 +#: templates/unanswered.html.py:60 templates/tough/unanswered.html:46 +#: templates/tough/unanswered.html.py:58 msgid "community wiki" -msgstr "" +msgstr "wiki de comunidad" #: forum/forms.py:75 msgid "" "if you choose community wiki option, the question and answer do not generate " "points and name of author will not be shown" msgstr "" +"si marca la opción 'wiki de comunidad', la pregunta y respuestas no generan " +"puntos y el nombre del autor no será mostrado" #: forum/forms.py:84 msgid "update summary:" -msgstr "" +msgstr "resumen de modificación" #: forum/forms.py:85 msgid "" "enter a brief summary of your revision (e.g. fixed spelling, grammar, " "improved style, this field is optional)" msgstr "" +"ingresa un breve resumen de tu revisión (ej. error ortográfico, gramática, " +"mejoras de estilo. Este campo es opcional." #: forum/forms.py:160 msgid "this email does not have to be linked to gravatar" -msgstr "" +msgstr "este email no tiene porque estar asociado a un Gravatar" #: forum/forms.py:161 msgid "Real name" -msgstr "" +msgstr "Nombre real" #: forum/forms.py:162 msgid "Website" -msgstr "" +msgstr "Sitio Web" #: forum/forms.py:163 msgid "Location" -msgstr "" +msgstr "Ubicación" #: forum/forms.py:164 msgid "Date of birth" -msgstr "" +msgstr "Fecha de nacimiento" #: forum/forms.py:164 msgid "will not be shown, used to calculate age, format: YYYY-MM-DD" -msgstr "" +msgstr "no será mostrado, usado para calcular la edad. Formato: YYY-MM-DD" -#: forum/forms.py:165 templates/authopenid/settings.html:20 +#: forum/forms.py:165 templates/base.html:64 +#: templates/authopenid/settings.html:20 msgid "Profile" -msgstr "" +msgstr "Perfil" #: forum/forms.py:190 forum/forms.py:191 msgid "this email has already been registered, please use another one" -msgstr "" +msgstr "este email ya ha sido registrado, por favor use otro" -#: forum/models.py:316 templates/badges.html:50 +#: forum/models.py:316 templates/badges.html:51 msgid "gold" -msgstr "" +msgstr "oro" -#: forum/models.py:317 templates/badges.html:58 +#: forum/models.py:317 templates/badges.html:59 msgid "silver" -msgstr "" +msgstr "plata" -#: forum/models.py:318 templates/badges.html:65 +#: forum/models.py:318 templates/badges.html:66 msgid "bronze" -msgstr "" +msgstr "bronze" -#: forum/user.py:17 templates/user_tabs.html:7 +#: forum/user.py:16 templates/user_tabs.html:7 msgid "overview" -msgstr "" +msgstr "vista general" -#: forum/user.py:18 +#: forum/user.py:17 msgid "user profile" -msgstr "" +msgstr "perfil de usuario" -#: forum/user.py:19 +#: forum/user.py:18 msgid "user profile overview" -msgstr "" +msgstr "vista general del perfil de usuario" -#: forum/user.py:25 templates/user_tabs.html:9 +#: forum/user.py:24 templates/user_tabs.html:9 msgid "recent activity" -msgstr "" +msgstr "actividades recientes" -#: forum/user.py:26 +#: forum/user.py:25 msgid "recent user activity" -msgstr "" +msgstr "actividades recientes del usuario" -#: forum/user.py:27 +#: forum/user.py:26 msgid "profile - recent activity" -msgstr "" +msgstr "perfil - actividades recientes" -#: forum/user.py:34 templates/user_tabs.html:13 +#: forum/user.py:33 templates/user_tabs.html:13 msgid "responses" -msgstr "" +msgstr "respuestas" -#: forum/user.py:35 templates/user_tabs.html:12 +#: forum/user.py:34 templates/user_tabs.html:12 msgid "comments and answers to others questions" -msgstr "" +msgstr "comentarios y respuestas a preguntas de otros" -#: forum/user.py:36 +#: forum/user.py:35 msgid "profile - responses" -msgstr "" +msgstr "perfil - respuestas" -#: forum/user.py:43 templates/user_info.html:23 templates/users.html:25 +#: forum/user.py:42 templates/user_info.html:23 templates/users.html:26 msgid "reputation" -msgstr "" +msgstr "reputación" -#: forum/user.py:44 +#: forum/user.py:43 msgid "user reputation in the community" -msgstr "" +msgstr "reputación del usuario en la comunidad" -#: forum/user.py:45 +#: forum/user.py:44 msgid "profile - user reputation" -msgstr "" +msgstr "perfil - reputación del usuario" -#: forum/user.py:51 +#: forum/user.py:50 msgid "favorite questions" -msgstr "" +msgstr "preguntas favoritas" -#: forum/user.py:52 +#: forum/user.py:51 msgid "users favorite questions" -msgstr "" +msgstr "preguntas favoritas del usuario" -#: forum/user.py:53 +#: forum/user.py:52 msgid "profile - favorite questions" -msgstr "" +msgstr "perfil - preguntas favoritas" -#: forum/user.py:60 templates/user_tabs.html:20 +#: forum/user.py:59 templates/user_tabs.html:20 msgid "casted votes" -msgstr "" +msgstr "votos" -#: forum/user.py:61 templates/user_tabs.html:20 +#: forum/user.py:60 templates/user_tabs.html:20 msgid "user vote record" -msgstr "" +msgstr "historial de votación" -#: forum/user.py:62 +#: forum/user.py:61 msgid "profile - votes" -msgstr "" +msgstr "perfil - votos" -#: forum/user.py:69 +#: forum/user.py:68 msgid "preferences" -msgstr "" +msgstr "preferencias" -#: forum/user.py:70 templates/user_tabs.html:28 +#: forum/user.py:69 templates/user_tabs.html:28 msgid "user preference settings" -msgstr "" +msgstr "preferencias del usuario" -#: forum/user.py:71 +#: forum/user.py:70 msgid "profile - user preferences" -msgstr "" +msgstr "perfil - preferencia de " -#: forum/views.py:1726 +#: forum/views.py:1730 msgid "uploading images is limited to users with >60 reputation points" -msgstr "" +msgstr "para subir imagenes debes tener más de 60 puntos de reputación" -#: forum/views.py:1728 +#: forum/views.py:1732 msgid "allowed file types are 'jpg', 'jpeg', 'gif', 'bmp', 'png', 'tiff'" msgstr "" +"los tipos de archivos permitidos son 'jpg', 'jpeg', 'gif', 'bmp', 'png', " +"'tiff'" -#: forum/views.py:1730 +#: forum/views.py:1734 #, python-format msgid "maximum upload file size is %sK" -msgstr "" +msgstr "tamaño máximo permitido es archivo %sK" -#: forum/views.py:1732 +#: forum/views.py:1736 #, python-format msgid "" "Error uploading file. Please contact the site administrator. Thank you. %s" msgstr "" +"Error al subir el archivo. Por favor, contacte al administrador. Gracias. %s" #: forum/templatetags/extra_tags.py:139 forum/templatetags/extra_tags.py:168 #: templates/header.html:33 msgid "badges" -msgstr "" +msgstr "distinciones" #: forum/templatetags/extra_tags.py:140 forum/templatetags/extra_tags.py:167 msgid "reputation points" -msgstr "" +msgstr "puntos de reputación" #: forum/templatetags/extra_tags.py:221 msgid " ago" -msgstr "" +msgstr " atras" #: templates/404.html:24 msgid "Sorry, could not find the page you requested." -msgstr "" +msgstr "Disculpe, no se pudo encontrar la página que solicito." #: templates/404.html:26 msgid "This might have happened for the following reasons:" -msgstr "" +msgstr "Esto puede haber sucedido por alguno de los siguientes motivos:" #: templates/404.html:28 msgid "this question or answer has been deleted;" -msgstr "" +msgstr "esta pregunta o respuesta ha sido borrada;" #: templates/404.html:29 msgid "url has error - please check it;" -msgstr "" +msgstr "la url tiene un error - por favor compruebelo;" #: templates/404.html:30 msgid "" "the page you tried to visit is protected or you don't have sufficient " "points, see" msgstr "" +"La pagina que intentas acceder esta protegida o no tienes los puntos de " +"reputación suficientes, ver" #: templates/404.html:31 msgid "if you believe this error 404 should not have occured, please" -msgstr "" +msgstr "si consideras que este error 404 no debería haber sucedido, por favor" #: templates/404.html:32 msgid "report this problem" -msgstr "" +msgstr "reporta este problema" #: templates/404.html:41 templates/500.html:27 msgid "back to previous page" -msgstr "" +msgstr "volver a la página siguiente" #: templates/404.html:42 msgid "see all questions" -msgstr "" +msgstr "ver todas las preguntas" #: templates/404.html:43 msgid "see all tags" -msgstr "" +msgstr "ver todas las tags" #: templates/500.html:24 msgid "system error log is recorded, error will be fixed as soon as possible" msgstr "" +"el error del sistema ha sido registrado, y será solucionado lo antes postible" #: templates/500.html:25 msgid "please report the error to the site administrators if you wish" -msgstr "" +msgstr "por favor reportar el error al administrador de ser posible" #: templates/500.html:28 msgid "see latest questions" -msgstr "" +msgstr "ver ultimas preguntas" #: templates/500.html:29 msgid "see tags" -msgstr "" +msgstr "ver tags" + +#: templates/about.html:6 templates/about.html.py:11 +msgid "About" +msgstr "Acerca de" #: templates/answer_edit.html:4 templates/answer_edit.html.py:47 msgid "Edit answer" -msgstr "" +msgstr "Editar respuesta" #: templates/answer_edit.html:24 templates/answer_edit.html.py:27 #: templates/ask.html:25 templates/ask.html.py:28 templates/question.html:37 #: templates/question.html.py:40 templates/question_edit.html:27 msgid "hide preview" -msgstr "" +msgstr "ocultar previsualización" #: templates/answer_edit.html:27 templates/ask.html:28 #: templates/question.html:40 templates/question_edit.html:27 msgid "show preview" -msgstr "" +msgstr "ver previsualización" #: templates/answer_edit.html:47 templates/question_edit.html:65 #: templates/revisions_answer.html:36 templates/revisions_question.html:36 +#: templates/tough/question_retag.html:51 msgid "back" -msgstr "" +msgstr "volver" #: templates/answer_edit.html:52 templates/question_edit.html:70 #: templates/revisions_answer.html:47 templates/revisions_question.html:47 msgid "revision" -msgstr "" +msgstr "revisión" #: templates/answer_edit.html:55 templates/question_edit.html:74 msgid "select revision" -msgstr "" +msgstr "seleccionar revisión" #: templates/answer_edit.html:62 templates/ask.html:81 #: templates/question.html:447 templates/question_edit.html:91 msgid "Toggle the real time Markdown editor preview" -msgstr "" +msgstr "Activar la visualización en tiempo real de Markdown" #: templates/answer_edit.html:62 templates/ask.html:81 #: templates/question.html:447 templates/question_edit.html:91 msgid "toggle preview" -msgstr "" +msgstr "Activar previsualización" #: templates/answer_edit.html:73 templates/question_edit.html:119 msgid "Save edit" -msgstr "" +msgstr "Guardar la edición" #: templates/answer_edit.html:74 templates/close.html:29 #: templates/question_edit.html:120 templates/reopen.html:30 -#: templates/user_edit.html:83 +#: templates/user_edit.html:83 templates/tough/question_retag.html:75 msgid "Cancel" -msgstr "" +msgstr "Cancelar" + +#: templates/answer_edit_tips.html:4 +msgid "answer tips" +msgstr "sugerencias sobre respuestas" + +#: templates/answer_edit_tips.html:7 +msgid "please make your answer relevant to this community" +msgstr "por favor, haz que tu respuesta sea relevante a esta comunidad" + +#: templates/answer_edit_tips.html:10 +msgid "try to give an answer, rather than engage into a discussion" +msgstr "intenta dar una respuesta, más que entablar un debate o discusión" + +#: templates/answer_edit_tips.html:13 +msgid "please try to provide details" +msgstr "por favor, intenta brindar detalles" + +#: templates/answer_edit_tips.html:16 templates/question_edit_tips.html:13 +msgid "be clear and concise" +msgstr "ser claro y conciso" + +#: templates/answer_edit_tips.html:19 templates/question_edit_tips.html:16 +msgid "see frequently asked questions" +msgstr "ver preguntas frecuentes" + +#: templates/answer_edit_tips.html:25 templates/question_edit_tips.html:22 +msgid "Markdown tips" +msgstr "sugerencias de Markdown" + +#: templates/answer_edit_tips.html:28 templates/question_edit_tips.html:25 +msgid "*italic* or __italic__" +msgstr "*itálica* o __itálica__" + +#: templates/answer_edit_tips.html:31 templates/question_edit_tips.html:28 +msgid "**bold** or __bold__" +msgstr "**negrita** o __negrita__" + +#: templates/answer_edit_tips.html:34 templates/question_edit_tips.html:31 +msgid "link" +msgstr "enlace" + +#: templates/answer_edit_tips.html:34 templates/answer_edit_tips.html.py:39 +#: templates/question_edit_tips.html:31 templates/question_edit_tips.html:36 +msgid "text" +msgstr "texto" + +#: templates/answer_edit_tips.html:39 templates/question_edit_tips.html:36 +msgid "image" +msgstr "imagen" + +#: templates/answer_edit_tips.html:43 templates/question_edit_tips.html:40 +msgid "numbered list:" +msgstr "lista numerada" + +#: templates/answer_edit_tips.html:48 templates/question_edit_tips.html:45 +msgid "basic HTML tags are also supported" +msgstr "etiquetas básicas de HTML permitidas" + +#: templates/answer_edit_tips.html:51 templates/question_edit_tips.html:48 +msgid "learn more about Markdown" +msgstr "aprender mas sobre Markdown" #: templates/ask.html:4 templates/ask.html.py:60 msgid "Ask a question" -msgstr "" +msgstr "Hacer una pregunta" #: templates/ask.html:106 msgid "Use" -msgstr "" +msgstr "Usar" #: templates/ask.html:106 msgid "learn more about OpenID" -msgstr "" +msgstr "aprender mas sobre OpenID" #: templates/ask.html:106 templates/authopenid/signin.html:35 #: templates/authopenid/signin.html:61 msgid "Login" -msgstr "" +msgstr "Ingresar" #: templates/ask.html:109 msgid "Get your own " -msgstr "" +msgstr "Obtiene tu propio " #: templates/ask.html:117 templates/authopenid/sendpw.html:27 msgid "User name" -msgstr "" +msgstr "Nombre de usuario" #: templates/ask.html:120 msgid "Email: (won't be shown to anyone)" -msgstr "" +msgstr "Email: (no será mostrado a nadie)" #: templates/ask.html:127 msgid "Ask your question" -msgstr "" +msgstr "Haz tu pregunta" #: templates/badge.html:6 templates/badge.html.py:17 msgid "Badge" -msgstr "" +msgstr "Distinción" #: templates/badge.html:26 msgid "The users have been awarded with badges:" -msgstr "" +msgstr "Usuarios han sido galardonados con distinciones:" -#: templates/badges.html:5 +#: templates/badges.html:6 msgid "Badges summary" -msgstr "" +msgstr "Resumen de distinciones" -#: templates/badges.html:16 templates/user_stats.html:113 +#: templates/badges.html:17 templates/user_stats.html:113 msgid "Badges" -msgstr "" +msgstr "Distinciones" -#: templates/badges.html:20 +#: templates/badges.html:21 msgid "" "Community gives you awards for your questions, answers and votes. Below is " "the list of available badges and number of times each type of badge has been " "awarded." msgstr "" +"La comunidad te condecora con distinciones por tus preguntas, respuestas y " +"votos. Debajo esta la lista de las distinciones disponibles y la cantidad de " +"veces que han sido asignadas." -#: templates/badges.html:47 +#: templates/badges.html:48 msgid "Community badges" -msgstr "" +msgstr "Distinciones de la comunidad" -#: templates/badges.html:53 +#: templates/badges.html:54 msgid "" "Gold badge is very rare. To obtain it you have to show profound knowledge " "and ability in addition to actively participating in the community. Gold " "badge is the highest award in this community." msgstr "" +"Las distinciones de Oro son excepcionales. Para obtenerla debes demostrar un " +"profundo conocimiento y habilidad además de participar activamente en la " +"comunidad. La distinción de Oro es la condecoración máxima en esta comunidad" -#: templates/badges.html:61 +#: templates/badges.html:62 msgid "" "Obtaining silver badge requires significant patience. If you got one, you've " "very significantly contributed to this community" msgstr "" +"Obtener una distinción de Plata requiere de paciencia. Si has logrado una, " +"quiere decir que haz significativamente aportado a esta comunidad." -#: templates/badges.html:64 +#: templates/badges.html:65 msgid "bronze badge: often given as a special honor" msgstr "" +"distinción de bronce: con frecuencia entregada como reconocimiento especial." -#: templates/badges.html:68 +#: templates/badges.html:69 msgid "" "If you are active in this community, you will get this medal - still it is a " "special honor." msgstr "" +"Si eres un usuario activo de esta comunidad, recibirás esta distinción - de " +"todas maneras es un honor especial." -#: templates/base.html:61 templates/base_content.html:60 -msgid "congratulations, community gave you a badge" -msgstr "" +#: templates/base.html:62 +#, fuzzy +msgid "Congratulations! You have new badges: " +msgstr "felicitaciones, la comunidad te ha otorgado una distinción" -#: templates/base.html:63 templates/base_content.html:62 -msgid "profile" -msgstr "" +#: templates/base.html:63 +#, fuzzy +msgid "go to see" +msgstr "OK para cerrar" #: templates/base_content.html:61 +msgid "congratulations, community gave you a badge" +msgstr "felicitaciones, la comunidad te ha otorgado una distinción" + +#: templates/base_content.html:62 msgid "see" -msgstr "" +msgstr "ver" + +#: templates/base_content.html:63 +msgid "profile" +msgstr "perfil" #: templates/book.html:7 msgid "reading channel" -msgstr "" +msgstr "canal de lectura" #: templates/book.html:26 msgid "[author]" -msgstr "" +msgstr "[autor]" #: templates/book.html:30 msgid "[publisher]" -msgstr "" +msgstr "[editorial]" #: templates/book.html:34 msgid "[publication date]" -msgstr "" +msgstr "[fecha de publicación]" #: templates/book.html:38 msgid "[price]" -msgstr "" +msgstr "[precio]" #: templates/book.html:39 msgid "currency unit" -msgstr "" +msgstr "unidad de moneda" #: templates/book.html:42 msgid "[pages]" -msgstr "" +msgstr "[páginas]" #: templates/book.html:43 msgid "pages abbreviation" -msgstr "" +msgstr "abreviación de páginas" #: templates/book.html:46 msgid "[tags]" -msgstr "" +msgstr "[etiquetas]" #: templates/book.html:56 msgid "author blog" -msgstr "" +msgstr "blog del autor" #: templates/book.html:62 msgid "book directory" -msgstr "" +msgstr "directorio del libro" #: templates/book.html:66 msgid "buy online" -msgstr "" +msgstr "comprar en-linea" #: templates/book.html:79 msgid "reader questions" -msgstr "" +msgstr "pregunta de lector" #: templates/book.html:82 msgid "ask the author" -msgstr "" +msgstr "preguntar al autor" #: templates/book.html:88 templates/book.html.py:93 #: templates/users_questions.html:17 msgid "this question was selected as favorite" -msgstr "" +msgstr "esta pregunta ha sido seleccionada como favorita" #: templates/book.html:88 templates/book.html.py:93 #: templates/users_questions.html:11 templates/users_questions.html.py:17 msgid "number of times" -msgstr "" +msgstr "numero de veces" -#: templates/book.html:105 templates/index.html:47 +#: templates/book.html:105 templates/index.html:47 templates/questions.html:46 #: templates/unanswered.html:37 templates/users_questions.html:30 +#: templates/tough/unanswered.html:35 msgid "votes" -msgstr "" +msgstr "votos" #: templates/book.html:108 msgid "the answer has been accepted to be correct" -msgstr "" +msgstr "la respuesta ha sido aceptada como correcta" -#: templates/book.html:115 templates/index.html:48 +#: templates/book.html:115 templates/index.html:48 templates/questions.html:47 #: templates/unanswered.html:38 templates/users_questions.html:40 +#: templates/tough/unanswered.html:36 msgid "views" -msgstr "" +msgstr "vistas" #: templates/book.html:125 templates/index.html:68 templates/question.html:112 -#: templates/question.html.py:479 templates/tags.html:46 +#: templates/question.html.py:479 templates/questions.html:84 +#: templates/questions.html.py:149 templates/tags.html:47 #: templates/unanswered.html:75 templates/unanswered.html.py:109 -#: templates/users_questions.html:52 +#: templates/users_questions.html:52 templates/tough/unanswered.html:72 +#: templates/tough/unanswered.html:105 msgid "using tags" -msgstr "" +msgstr "usando etiquetas" #: templates/book.html:147 msgid "subscribe to book RSS feed" -msgstr "" +msgstr "suscribirse al RSS del libro" -#: templates/book.html:147 templates/index.html:115 +#: templates/book.html:147 templates/index.html:116 msgid "subscribe to the questions feed" -msgstr "" +msgstr "suscribirse al agregado de noticias" #: templates/close.html:6 templates/close.html.py:16 msgid "Close question" -msgstr "" +msgstr "Cerrar pregunta" #: templates/close.html:19 msgid "Close the question" -msgstr "" +msgstr "Cerrar la pregunta" #: templates/close.html:25 msgid "Reasons" -msgstr "" +msgstr "Razón" #: templates/close.html:28 msgid "OK to close" +msgstr "OK para cerrar" + +#: templates/faq.html:11 templates/tough/faq.html:9 +msgid "Frequently Asked Questions " +msgstr "Preguntas Frecuentes" + +#: templates/faq.html:15 templates/tough/faq.html:13 +msgid "What kinds of questions can I ask here?" +msgstr "¿Qué clase de preguntas puedo hacer aquí?" + +#: templates/faq.html:16 templates/tough/faq.html:14 +msgid "" +"Most importanly - questions should be <strong>relevant</strong> to this " +"community." msgstr "" +"Por encima de todo - las preguntas deben ser <strong>relevantes</strong>a " +"esta comunidad." -#: templates/footer.html:5 -msgid "About us" +#: templates/faq.html:17 templates/tough/faq.html:15 +msgid "" +"Before asking the question - please make sure to use search to see whether " +"your question has alredy been answered." msgstr "" +"Antes de hacer tu pregunta - por favor usa el buscador para asegurarte que " +"la pregunta no este ya hecha." -#: templates/footer.html:6 templates/header.html:13 templates/index.html:83 -msgid "faq" +#: templates/faq.html:20 templates/tough/faq.html:18 +msgid "What questions should I avoid asking?" +msgstr "¿Qué preguntas debería evitar preguntar?" + +#: templates/faq.html:21 templates/tough/faq.html:19 +msgid "" +"Please avoid asking questions that are not relevant to this community, too " +"subjective and argumentative." msgstr "" +"Evita hacer preguntas que no son relevantes a la comunidad, demasiado " +"subjetivas o argumentativas." + +#: templates/faq.html:24 templates/tough/faq.html:22 +msgid "What should I avoid in my answers?" +msgstr "¿Que debo evitar en mis respuestas?" -#: templates/footer.html:8 -msgid "Contact" +#: templates/faq.html:25 templates/tough/faq.html:23 +msgid "" +"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." msgstr "" +"es un sitio de Preguntas y Respuestas, no un grupo de discusión. Por ende, " +"intenta evitar discusiones en tus respuestas. Los comentarios permiten " +"realizar pequeñas discusiones." -#: templates/footer.html:9 -msgid "Privacy" +#: templates/faq.html:28 templates/tough/faq.html:26 +msgid "Who moderates this community?" +msgstr "¿Quién modera esta comunidad?" + +#: templates/faq.html:29 templates/tough/faq.html:27 +msgid "The short answer is: <strong>you</strong>." +msgstr "La respuesta corta es: <strong>tú</strong>" + +#: templates/faq.html:30 templates/tough/faq.html:28 +msgid "This website is moderated by the users." +msgstr "Este sitio es moderado por los usuarios." + +#: templates/faq.html:31 templates/tough/faq.html:29 +msgid "" +"The reputation system allows users earn the authorization to perform a " +"variety of moderation tasks." msgstr "" +"El sistema de reputación permite a los usuarios adquirir autorización para " +"realizar diversas tareas de moderación." -#: templates/footer.html:10 -msgid "Feedback" +#: templates/faq.html:34 templates/tough/faq.html:32 +msgid "How does reputation system work?" +msgstr "¿Cómo funciona el sistema de reputación?" + +#: templates/faq.html:35 templates/tough/faq.html:33 +msgid "" +"Anyone can ask questions and give answers, points are not necessary for that." msgstr "" +"Cualquier usuario puede hacer preguntas y dar respuestas, no es necesario " +"tener reputación para ello." -#: templates/header.html:8 -msgid "logout" +#: templates/faq.html:36 templates/tough/faq.html:34 +msgid "" +"As we've said before, users help running this site. Point system helps " +"select users who can administer this community." msgstr "" +"Como dijimos antes, los usuarios ayudan a crear este sitio. El sistema de " +"reputación permite seleccionar usuarios que pueden moderar esta comunidad." -#: templates/header.html:10 templates/authopenid/signup.html:39 -msgid "login" +#: templates/faq.html:37 templates/tough/faq.html:35 +msgid "" +"Reputation points roughly measure how community trusts you. These points are " +"given to you directly by other members of the community." msgstr "" +"Los puntos de reputación miden a groso modo que tan respetado eres en la " +"comunidad. Los puntos son dados a ti directamente por otros miembros de la " +"comunidad" -#: templates/header.html:12 templates/index.html:82 -msgid "about" +#: templates/faq.html:40 templates/tough/faq.html:38 +msgid "" +"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." msgstr "" +"Por ejemplo, si haces una pregunta interesante, o das una respuesta valiosa, " +"tu entrada va a ser votada positivamente y tu ganarás confianza en la " +"comunidad." -#: templates/header.html:23 -msgid "back to home page" +#: templates/faq.html:41 templates/tough/faq.html:39 +msgid "" +"If on the other hand someone gives a misleading answer, the answer will be " +"voted down and he/she loses some points." +msgstr "" +"Si por el contrario, alguien da una respuesta que no corresponde, la " +"respuesta será votada negativamente y el usuario perderá puntos." + +#: templates/faq.html:42 templates/tough/faq.html:40 +msgid "" +"Each vote in favor will generate <strong>10</strong> points, each vote " +"against will subtract <strong>2</strong> points." +msgstr "" +"Cada voto a favor generará <strong>10</strong> puntos, cada voto negativo " +"restará <strong>2</strong> puntos." + +#: templates/faq.html:43 templates/tough/faq.html:41 +msgid "" +"Through the votes of other people you can accumulate a maximum of " +"<strong>200</strong> points." +msgstr "" +"A través del voto de otras personas puedes acumular un máximo de " +"<strong>200</strong> puntos." + +#: templates/faq.html:44 +msgid "After accumulating certain number of points, you can do more:" +msgstr "Luego de haber acumulado cierta cantidad de puntos, puedes hacer más:" + +#: templates/faq.html:52 templates/user_votes.html:14 +#: templates/tough/faq.html:50 +msgid "upvote" +msgstr "votar positivo" + +#: templates/faq.html:56 templates/tough/faq.html:54 +msgid "use tags" +msgstr "etiquetas usadas" + +#: templates/faq.html:60 templates/tough/faq.html:58 +msgid "add comments" +msgstr "agregar comentarios" + +#: templates/faq.html:64 templates/user_votes.html:16 +#: templates/tough/faq.html:62 +msgid "downvote" +msgstr "votar negativo" + +#: templates/faq.html:71 templates/tough/faq.html:69 +msgid "retag questions" +msgstr "re-etiquetar preguntas" + +#: templates/faq.html:75 templates/tough/faq.html:73 +msgid "edit community wiki questions" +msgstr "editar preguntas de la wiki comunitaria" + +#: templates/faq.html:79 templates/tough/faq.html:77 +msgid "edit any answer" +msgstr "editar cualquier pregunta" + +#: templates/faq.html:83 templates/tough/faq.html:81 +msgid "open any closed question" +msgstr "abrir cualquier pregunta cerrada" + +#: templates/faq.html:87 templates/tough/faq.html:85 +msgid "delete any comment" +msgstr "borrar cualquier comentario" + +#: templates/faq.html:91 templates/tough/faq.html:89 +msgid "delete any questions and answers and perform other moderation tasks" +msgstr "" +"borrar cualquier pregunta o respuesta y realizar otras tareas de " +"administración." + +#: templates/faq.html:98 +msgid "To register, do I need to create new password?" +msgstr "¿Para registrarme, debo crearme una cuenta?" + +#: templates/faq.html:99 templates/tough/faq.html:97 +msgid "" +"No, you don't have to. You can login through any service that supports " +"OpenID, e.g. Google, Yahoo, AOL, etc." +msgstr "" +"No tienes porqué. Puedes ingresar usando cualquiera de los servicios que " +"soportan OpenID, ej. Google, Yahoo, AOL, MyOpenID, etc." + +#: templates/faq.html:100 templates/tough/faq.html:98 +msgid "Login now!" +msgstr "Ingresa ahora!" + +#: templates/faq.html:103 templates/tough/faq.html:101 +msgid "Why other people can edit my questions/answers?" +msgstr "¿Porqué otras personas pueden editar mis preguntas y respuestas?" + +#: templates/faq.html:104 templates/tough/faq.html:102 +msgid "Goal of this site is..." +msgstr "El objetivo de este sitio es..." + +#: templates/faq.html:104 templates/tough/faq.html:102 +msgid "" +"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." msgstr "" +"Entonces, las preguntas y respuestas pueden ser editadas como wiki por " +"usuarios con experiencia, y esto mejora la calidad general del conocimiento " +"guardado." -#: templates/header.html:29 templates/header.html.py:60 +#: templates/faq.html:105 templates/tough/faq.html:103 +msgid "If this approach is not for you, we respect your choice." +msgstr "" +"Si esta forma de funcionamiento no es de tu agrado, respetamos tu elección." + +#: templates/faq.html:107 templates/tough/faq.html:105 +msgid "Still have questions?" +msgstr "¿Aún tienes preguntas?" + +#: templates/faq.html:108 +msgid "Please ask your question, help make our community better!" +msgstr "Por favor haz tu pregunta, ¡ayudanos a mejorar nuestra comunidad!" + +#: templates/faq.html:108 templates/header.html:29 templates/header.html.py:60 +#: templates/tough/faq.html:106 msgid "questions" +msgstr "preguntas" + +#: templates/faq.html:108 templates/index.html:121 +#: templates/tough/faq.html:106 +msgid "." msgstr "" +#: templates/footer.html:7 templates/header.html:12 templates/index.html:83 +msgid "about" +msgstr "acerca de" + +#: templates/footer.html:8 templates/header.html:13 templates/index.html:84 +msgid "faq" +msgstr "preguntas frecuentes" + +#: templates/footer.html:9 +msgid "blog" +msgstr "blog" + +#: templates/footer.html:10 +msgid "contact us" +msgstr "contactenos" + +#: templates/footer.html:11 +msgid "privacy policy" +msgstr "código de privacidad" + +#: templates/footer.html:12 +msgid "give feedback" +msgstr "envía comentarios" + +#: templates/footer.html:18 +msgid "current revision" +msgstr "revisión actual" + +#: templates/header.html:8 +msgid "logout" +msgstr "salir" + +#: templates/header.html:10 templates/authopenid/signup.html:39 +msgid "login" +msgstr "entrar" + +#: templates/header.html:23 +msgid "back to home page" +msgstr "volver al inicio" + #: templates/header.html:31 templates/header.html.py:62 msgid "users" -msgstr "" +msgstr "usuarios" #: templates/header.html:32 msgid "books" -msgstr "" +msgstr "libros" -#: templates/header.html:34 templates/index.html:120 +#: templates/header.html:34 templates/index.html:121 msgid "unanswered questions" -msgstr "" +msgstr "sin respuesta" #: templates/header.html:38 msgid "my profile" -msgstr "" +msgstr "mi perfil" #: templates/header.html:42 msgid "ask a question" -msgstr "" +msgstr "hacer una pregunta" #: templates/header.html:57 msgid "search" -msgstr "" +msgstr "buscar" #: templates/index.html:6 msgid "Home" -msgstr "" +msgstr "Inicio" -#: templates/index.html:21 +#: templates/index.html:7 +msgid "meta site keywords, comma separated" +msgstr "palabras claves" + +#: templates/index.html:21 templates/questions.html:7 msgid "Questions" -msgstr "" +msgstr "Preguntas" #: templates/index.html:23 msgid "last updated questions" -msgstr "" +msgstr "ultimas preguntas actualizadas" -#: templates/index.html:23 templates/unanswered.html:20 +#: templates/index.html:23 templates/questions.html:25 +#: templates/unanswered.html:20 templates/tough/unanswered.html:18 msgid "newest" -msgstr "" +msgstr "más nuevas" -#: templates/index.html:24 +#: templates/index.html:24 templates/questions.html:27 msgid "hottest questions" -msgstr "" +msgstr "preguntas más calientes" -#: templates/index.html:24 +#: templates/index.html:24 templates/questions.html:27 msgid "hottest" -msgstr "" +msgstr "más calientes" -#: templates/index.html:25 +#: templates/index.html:25 templates/questions.html:28 msgid "most voted questions" -msgstr "" +msgstr "preguntas más votadas" -#: templates/index.html:25 +#: templates/index.html:25 templates/questions.html:28 msgid "most voted" -msgstr "" +msgstr "más votadas" #: templates/index.html:26 msgid "all questions" -msgstr "" +msgstr "todas las preguntas" -#: templates/index.html:46 templates/unanswered.html:36 -#: templates/users_questions.html:35 +#: templates/index.html:46 templates/questions.html:45 +#: templates/unanswered.html:36 templates/users_questions.html:35 +#: templates/tough/unanswered.html:34 msgid "answers" -msgstr "" +msgstr "respuestas" #: templates/index.html:68 templates/question.html:112 -#: templates/question.html.py:479 templates/tags.html:46 +#: templates/question.html.py:479 templates/questions.html:84 +#: templates/questions.html.py:149 templates/tags.html:47 #: templates/unanswered.html:75 templates/unanswered.html.py:109 -#: templates/users_questions.html:52 +#: templates/users_questions.html:52 templates/tough/unanswered.html:72 +#: templates/tough/unanswered.html:105 msgid "see questions tagged" -msgstr "" +msgstr "ver preguntas etiquetadas" #: templates/index.html:79 msgid "welcome to website" -msgstr "" +msgstr "bienvenido a sitio" -#: templates/index.html:88 +#: templates/index.html:81 +msgid "what is this website" +msgstr "que es este sitio" + +#: templates/index.html:82 +msgid "what can one do on this website" +msgstr "que puede uno hacer en este sitio" + +#: templates/index.html:89 msgid "Recent tags" -msgstr "" +msgstr "Etiquetas recientes" -#: templates/index.html:93 +#: templates/index.html:94 #, python-format msgid "see questions tagged '%(tagname)s'" -msgstr "" +msgstr "ver preguntas etiquetadas '%(tagname)s'" -#: templates/index.html:96 templates/index.html.py:120 +#: templates/index.html:97 templates/index.html.py:121 msgid "popular tags" -msgstr "" +msgstr "etiquetas populares" -#: templates/index.html:100 +#: templates/index.html:101 msgid "Recent awards" -msgstr "" +msgstr "Reconocimientos recientes" -#: templates/index.html:106 +#: templates/index.html:107 msgid "given to" -msgstr "" +msgstr "dados a" -#: templates/index.html:111 +#: templates/index.html:112 msgid "all awards" -msgstr "" +msgstr "todos los reconocimientos" -#: templates/index.html:115 +#: templates/index.html:116 msgid "subscribe to last 30 questions by RSS" -msgstr "" +msgstr "suscribirse a las últimas 30 preguntas por RSS" -#: templates/index.html:120 +#: templates/index.html:121 msgid "Still looking for more? See" -msgstr "" +msgstr "¿Aún sigues buscando más? Ver" -#: templates/index.html:120 +#: templates/index.html:121 msgid "complete list of quesionts" -msgstr "" +msgstr "lista completa de preguntas" -#: templates/index.html:120 +#: templates/index.html:121 msgid "or" -msgstr "" - -#: templates/index.html:120 -msgid "." -msgstr "" +msgstr "ó" -#: templates/index.html:120 +#: templates/index.html:121 msgid "Please help us answer" -msgstr "" +msgstr "Ayudanos a responder" #: templates/logout.html:6 templates/logout.html.py:17 msgid "Logout" -msgstr "" +msgstr "Salir" #: templates/logout.html:20 msgid "" "As a registered user you can login with your OpenID, log out of the site or " "permanently remove your account." msgstr "" +"Como usuario registrado puedes ingresar con tu OpenID, salir del sitio o " +"eliminar de forma permanente tu cuenta." #: templates/logout.html:21 msgid "Logout now" -msgstr "" +msgstr "Salir ahora" -#: templates/pagesize.html:5 -msgid "Size per page:" -msgstr "" +#: templates/pagesize.html:6 +msgid "posts per page" +msgstr "entradas por página" -#: templates/paginator.html:5 -msgid "Previous" -msgstr "" +#: templates/paginator.html:6 templates/paginator.html.py:7 +msgid "previous" +msgstr "previo" + +#: templates/paginator.html:20 +msgid "current page" +msgstr "página actúal" + +#: templates/paginator.html:23 templates/paginator.html.py:30 +msgid "page number " +msgstr "número de página" + +#: templates/paginator.html:23 templates/paginator.html.py:30 +msgid "number - make blank in english" +msgstr " " + +#: templates/paginator.html:34 +msgid "next page" +msgstr "próxima página" #: templates/privacy.html:6 templates/privacy.html.py:11 msgid "Privacy policy" -msgstr "" +msgstr "Código de Privacidad" #: templates/privacy.html:15 msgid "general message about privacy" -msgstr "" +msgstr "mensaje de privacidad" #: templates/privacy.html:18 msgid "Site Visitors" -msgstr "" +msgstr "Visitantes del Sitio" #: templates/privacy.html:20 msgid "what technical information is collected about visitors" -msgstr "" +msgstr "que información es recolectada sobre los usuarios" #: templates/privacy.html:23 msgid "Personal Information" -msgstr "" +msgstr "Información Personal" #: templates/privacy.html:25 msgid "details on personal information policies" -msgstr "" +msgstr "describir código de manejo de la información personal" #: templates/privacy.html:28 msgid "Other Services" -msgstr "" +msgstr "Otros servicios" #: templates/privacy.html:30 msgid "details on sharing data with third parties" -msgstr "" +msgstr "detalles sobre compartir información con terceros" #: templates/privacy.html:35 msgid "cookie policy details" -msgstr "" +msgstr "uso de cookies" #: templates/privacy.html:37 msgid "Policy Changes" -msgstr "" +msgstr "Cambios de Códigos" #: templates/privacy.html:38 msgid "how privacy policies can be changed" -msgstr "" +msgstr "como pueden ser cambiados los códigos de privacidad" #: templates/question.html:66 templates/question.html.py:78 msgid "i like this post (click again to cancel)" -msgstr "" +msgstr "Me gusta esta entrada (clickear devuelta para cancelar)" #: templates/question.html:68 templates/question.html.py:80 #: templates/question.html:273 msgid "current number of votes" -msgstr "" +msgstr "número actual de votos" #: templates/question.html:73 templates/question.html.py:84 msgid "i dont like this post (click again to cancel)" -msgstr "" +msgstr "No me gusta esta entrada (clickear devuelta para cancelar)" #: templates/question.html:90 msgid "mark this question as favorite (click again to cancel)" -msgstr "" +msgstr "marcar esta pregunta como favorita (clickear devuelta para cancelar)" #: templates/question.html:96 msgid "remove favorite mark from this question (click again to restore mark)" msgstr "" +"remover marca de favorito a esta pregunta (clickear devuelta para volver a " +"marcar)" #: templates/question.html:121 templates/question.html.py:304 #: templates/revisions_answer.html:53 templates/revisions_question.html:53 msgid "edit" -msgstr "" +msgstr "editar" #: templates/question.html:125 templates/question.html.py:314 msgid "delete" -msgstr "" +msgstr "borrar" #: templates/question.html:130 msgid "reopen" -msgstr "" +msgstr "re-abrir" #: templates/question.html:135 msgid "close" -msgstr "" +msgstr "cerrar" #: templates/question.html:141 templates/question.html.py:327 msgid "" "report as offensive (i.e containing spam, advertising, malicious text, etc.)" msgstr "" +"reportar como ofensivo (ej. contiene spam, publicidad, texto malicioso, etc.)" #: templates/question.html:142 templates/question.html.py:328 msgid "flag offensive" -msgstr "" +msgstr "marcar como ofensivo" #: templates/question.html:154 templates/question.html.py:337 #: templates/revisions_answer.html:65 templates/revisions_question.html:65 msgid "updated" -msgstr "" +msgstr "actualizado" #: templates/question.html:203 templates/question.html.py:384 #: templates/revisions_answer.html:63 templates/revisions_question.html:63 msgid "asked" -msgstr "" +msgstr "preguntado" #: templates/question.html:233 templates/question.html.py:411 msgid "comments" -msgstr "" +msgstr "comentarios" #: templates/question.html:234 templates/question.html.py:412 msgid "add comment" -msgstr "" +msgstr "agregar comentario" #: templates/question.html:247 #, python-format @@ -1185,343 +1577,322 @@ msgid "" "The question has been closed for the following reason \"%(question." "get_close_reason_display)s\" by" msgstr "" +"La pregunta ha sido cerrada por el siguiente motivo \"%(question." +"get_close_reason_display)s\" por" #: templates/question.html:249 #, python-format msgid "close date %(question.closed_at)s" -msgstr "" +msgstr "fecha de cerrada %(question.closed_at)s" -#: templates/question.html:256 templates/questions.html:44 -#: templates/user_stats.html:28 +#: templates/question.html:256 templates/user_stats.html:28 msgid "Answers" -msgstr "" +msgstr "Respuestas" #: templates/question.html:258 msgid "oldest answers will be shown first" -msgstr "" +msgstr "la respuesta mas vieja será mostrada primero" #: templates/question.html:258 msgid "oldest answers" -msgstr "" +msgstr "pregunta más vieja" #: templates/question.html:259 msgid "newest answers will be shown first" -msgstr "" +msgstr "preguntas más nuevas serán mostradas primero" #: templates/question.html:259 msgid "newest answers" -msgstr "" +msgstr "más nuevas" #: templates/question.html:260 msgid "most voted answers will be shown first" -msgstr "" +msgstr "las preguntas más votadas serán mostradas primero" #: templates/question.html:260 msgid "popular answers" -msgstr "" +msgstr "respuestas populares serán mostradas primero" #: templates/question.html:272 msgid "i like this answer (click again to cancel)" -msgstr "" +msgstr "me gusta esta respuesta (clickear devuelta para cancelar)" #: templates/question.html:278 msgid "i dont like this answer (click again to cancel)" -msgstr "" +msgstr "no me gusta esta respuesta (clickear devuelta para cancelar)" #: templates/question.html:284 msgid "mark this answer as favorite (click again to undo)" -msgstr "" +msgstr "marcar esta respuesta como favorita (clickear devuelta para deshacer)" #: templates/question.html:289 msgid "the author of the question has selected this answer as correct" -msgstr "" +msgstr "el autor de esta pregunta ha seleccionado esta respuesta como correcta" #: templates/question.html:311 msgid "undelete" -msgstr "" +msgstr "deshacer eliminar" #: templates/question.html:321 msgid "answer permanent link" -msgstr "" +msgstr "enlace permanente a respuesta" #: templates/question.html:322 msgid "permanent link" -msgstr "" +msgstr "enlace permanente" #: templates/question.html:436 msgid "Your answer" -msgstr "" +msgstr "Tu respuesta" #: templates/question.html:460 msgid "Answer the question" -msgstr "" +msgstr "Responde la pregunta" #: templates/question.html:462 msgid "Login to answer" -msgstr "" +msgstr "Ingresa para responder" #: templates/question.html:474 msgid "Question tags" -msgstr "" +msgstr "Etiquetas de la pregunta" #: templates/question.html:484 msgid "question asked" -msgstr "" +msgstr "pregunta preguntada" #: templates/question.html:484 templates/question.html.py:490 #: templates/user_info.html:51 msgid "ago" -msgstr "" +msgstr "atrás" #: templates/question.html:487 msgid "question was seen" -msgstr "" +msgstr "la pregunta fue vista" #: templates/question.html:487 msgid "times" -msgstr "" +msgstr "veces" #: templates/question.html:490 msgid "last updated" -msgstr "" +msgstr "última vez actualizada" #: templates/question.html:495 msgid "Related questions" -msgstr "" +msgstr "Preguntas relacionadas" #: templates/question_edit.html:4 templates/question_edit.html.py:65 msgid "Edit question" -msgstr "" +msgstr "Editar pregunta" #: templates/question_edit_tips.html:4 msgid "question tips" -msgstr "" +msgstr "sugerencias sobre pregunta" #: templates/question_edit_tips.html:7 msgid "please ask a relevant question" -msgstr "" +msgstr "por favor hacer preguntas relevantes" #: templates/question_edit_tips.html:10 msgid "please try provide enough details" -msgstr "" - -#: templates/question_edit_tips.html:13 -msgid "be clear and concise" -msgstr "" - -#: templates/question_edit_tips.html:16 -msgid "see frequently asked questions" -msgstr "" - -#: templates/question_edit_tips.html:22 -msgid "Markdown tips" -msgstr "" - -#: templates/question_edit_tips.html:25 -msgid "*italic* or __italic__" -msgstr "" - -#: templates/question_edit_tips.html:28 -msgid "**bold** or __bold__" -msgstr "" +msgstr "intente proveer suficientes detalles" -#: templates/question_edit_tips.html:31 -msgid "link" -msgstr "" - -#: templates/question_edit_tips.html:31 templates/question_edit_tips.html:36 -msgid "text" -msgstr "" - -#: templates/question_edit_tips.html:36 -msgid "image" -msgstr "" +#: templates/questions.html:23 +msgid "Found by tags" +msgstr "Encontradas por etiqueta" -#: templates/question_edit_tips.html:40 -msgid "numbered list:" -msgstr "" - -#: templates/question_edit_tips.html:45 -msgid "basic HTML tags are also supported" -msgstr "" - -#: templates/question_edit_tips.html:48 -msgid "learn more about Markdown" -msgstr "" - -#: templates/questions.html:6 -msgid "Question list" -msgstr "" +#: templates/questions.html:23 +msgid "Found by title" +msgstr "Encontradas por titulo" -#: templates/questions.html:22 -msgid "Tagged questions" -msgstr "" - -#: templates/questions.html:22 -msgid "Query result" -msgstr "" - -#: templates/questions.html:22 +#: templates/questions.html:23 msgid "All questions" -msgstr "" +msgstr "Todas las preguntas" -#: templates/questions.html:24 -msgid "New questions" -msgstr "" - -#: templates/questions.html:24 -msgid "Newest" -msgstr "" - -#: templates/questions.html:25 -msgid "Newest updated questions" -msgstr "" - -#: templates/questions.html:25 -msgid "Active" -msgstr "" +#: templates/questions.html:25 templates/unanswered.html:20 +#: templates/tough/unanswered.html:18 +msgid "most recently asked questions" +msgstr "preguntas hechas más recientemente" #: templates/questions.html:26 -msgid "Questions with most answers" -msgstr "" +msgid "most recently updated questions" +msgstr "preguntas actualizadas más recientemente" #: templates/questions.html:26 -msgid "Hottest" -msgstr "" - -#: templates/questions.html:27 -msgid "Questions with most votes" -msgstr "" - -#: templates/questions.html:27 -msgid "Best" -msgstr "" +msgid "active" +msgstr "actividad" -#: templates/questions.html:45 -msgid "Votes" -msgstr "" - -#: templates/questions.html:46 -msgid "Visits" -msgstr "" - -#: templates/questions.html:57 templates/questions.html.py:69 -msgid "Community wiki" -msgstr "" - -#: templates/questions.html:83 -msgid "Browse questions with tag of " -msgstr "" - -#: templates/questions.html:125 templates/unanswered.html:105 +#: templates/questions.html:109 +#, fuzzy, python-format +msgid "" +"\n" +"\t\t\thave total %(q_num)s question tagged %(tagname)s\n" +"\t\t\t" +msgid_plural "" +"\n" +"\t\t\thave total %(q_num)s questions tagged %(tagname)s\n" +"\t\t\t" +msgstr[0] "ver preguntas etiquetadas '%(tagname)s'" +msgstr[1] "ver pregunta etiquetada '%(tagname)s'" + +#: templates/questions.html:116 +#, python-format +msgid "" +"\n" +"\t\t\thave total %(q_num)s question containing %(searchtitle)s\n" +"\t\t\t" +msgid_plural "" +"\n" +"\t\t\thave total %(q_num)s questions containing %(searchtitle)s\n" +"\t\t\t" +msgstr[0] "" +"\n" +"\t\t\thay un total de %(q_num)s preguntas que contienen %(searchtitle)s\n" +"\t\t\t" +msgstr[1] "" +"\n" +"\t\t\thay un total de %(q_num)s pregunta que contiene %(searchtitle)s\n" +"\t\t\t" + +#: templates/questions.html:124 +msgid "latest questions info" +msgstr "<strong>Más recientes</strong> preguntas son mostradas primero." + +#: templates/questions.html:128 +msgid "Questions are sorted by the <strong>time of last update</strong>." +msgstr "" +"Las preguntas estan ordenadas por <strong>fecha de último update</strong>." + +#: templates/questions.html:129 +msgid "Most recently answered ones are shown first." +msgstr "Las más recientemente respondidas son mostradas primero." + +#: templates/questions.html:133 +msgid "Questions sorted by <strong>number of responses</strong>." +msgstr "Preguntas ordenadas por <strong>número de respuestas</strong>." + +#: templates/questions.html:134 +msgid "Most answered questions are shown first." +msgstr "Preguntas más respondidas aparecen primero." + +#: templates/questions.html:138 +msgid "Questions are sorted by the <strong>number of votes</strong>." +msgstr "Las preguntas son ordenadas por el <strong>número de votos</strong>." + +#: templates/questions.html:139 +msgid "Most voted questions are shown first." +msgstr "Las preguntas más votadas son mostradas primero." + +#: templates/questions.html:146 templates/unanswered.html:105 +#: templates/tough/unanswered.html:101 msgid "Related tags" -msgstr "" +msgstr "Etiquetas relacionadas" #: templates/reopen.html:6 templates/reopen.html.py:16 msgid "Reopen question" -msgstr "" +msgstr "Re-abrir pregunta" #: templates/reopen.html:19 msgid "Open the previously closed question" -msgstr "" +msgstr "Abrir pregunta previamente cerrada" #: templates/reopen.html:22 msgid "The question was closed for the following reason " -msgstr "" +msgstr "La pregunta fue cerrada por el siguiente motivo " #: templates/reopen.html:22 msgid "reason - leave blank in english" -msgstr "" +msgstr "razón - " #: templates/reopen.html:22 msgid "on " -msgstr "" +msgstr "el " #: templates/reopen.html:22 msgid "date closed" -msgstr "" +msgstr "fecha cerrada" #: templates/reopen.html:29 msgid "Reopen this question" -msgstr "" +msgstr "Re-abrir esta pregunta" #: templates/revisions_answer.html:7 templates/revisions_answer.html.py:36 #: templates/revisions_question.html:8 templates/revisions_question.html:36 msgid "Revision history" -msgstr "" +msgstr "Historial de revisiones" -#: templates/tags.html:5 templates/tags.html.py:28 +#: templates/tags.html:6 templates/tags.html.py:29 msgid "Tag list" -msgstr "" +msgstr "Lista de etiquetas" -#: templates/tags.html:30 +#: templates/tags.html:31 msgid "sorted alphabetically" -msgstr "" +msgstr "ordenar alfabéticamente" -#: templates/tags.html:30 +#: templates/tags.html:31 msgid "by name" -msgstr "" +msgstr "por nombre" -#: templates/tags.html:31 +#: templates/tags.html:32 msgid "sorted by frequency of tag use" -msgstr "" +msgstr "ordenar por frecuencia de uso de la etiqueta" -#: templates/tags.html:31 +#: templates/tags.html:32 msgid "by popularity" -msgstr "" +msgstr "por popularidad" -#: templates/tags.html:37 +#: templates/tags.html:38 msgid "All tags matching query" -msgstr "" +msgstr "Todas las etiquetas que coincidan con la busqueda" -#: templates/tags.html:37 +#: templates/tags.html:38 msgid "all tags - make this empty in english" -msgstr "" +msgstr "todas las tags" -#: templates/tags.html:40 +#: templates/tags.html:41 msgid "Nothing found" -msgstr "" +msgstr "Nada encontrado" #: templates/unanswered.html:7 templates/unanswered.html.py:18 +#: templates/tough/unanswered.html:5 templates/tough/unanswered.html.py:16 msgid "Unanswered questions" -msgstr "" - -#: templates/unanswered.html:20 -msgid "most recently asked questions" -msgstr "" +msgstr "Preguntas sin respuesta" #: templates/unanswered.html:97 #, python-format msgid "have %(num_q)s unanswered questions" msgstr "" +"<div class=\"questions-count\">%(num_q)s</div> preguntas <strong>sin " +"respuesta</strong> " #: templates/unanswered.html:99 msgid "Have a total of" -msgstr "" +msgstr "Hay un total de" #: templates/user_edit.html:6 msgid "Edit user profile" -msgstr "" +msgstr "Editar perfil de usuario" #: templates/user_edit.html:19 msgid "edit profile" -msgstr "" +msgstr "editar perfil" #: templates/user_edit.html:31 msgid "image associated with your email address" -msgstr "" +msgstr "imagen asociada con tu email" #: templates/user_edit.html:31 msgid "avatar" -msgstr "" +msgstr "avatar" #: templates/user_edit.html:36 templates/user_info.html:31 msgid "Registered user" -msgstr "" +msgstr "Usuario registrado" #: templates/user_edit.html:82 msgid "Update" -msgstr "" +msgstr "Actualización" #: templates/user_info.html:34 msgid "update profile" @@ -1529,143 +1900,136 @@ msgstr "" #: templates/user_info.html:40 msgid "real name" -msgstr "" +msgstr "nombre real" #: templates/user_info.html:45 msgid "member for" -msgstr "" +msgstr "miembro de" #: templates/user_info.html:50 msgid "last seen" -msgstr "" +msgstr "última vez visto" #: templates/user_info.html:56 msgid "user website" -msgstr "" +msgstr "sitio web del usuario" #: templates/user_info.html:62 msgid "location" -msgstr "" +msgstr "ubicación" #: templates/user_info.html:69 msgid "age" -msgstr "" +msgstr "edad" #: templates/user_info.html:70 msgid "age unit" -msgstr "" +msgstr "unidad de edad" #: templates/user_info.html:75 msgid "todays unused votes" -msgstr "" +msgstr "votos de hoy no usados" #: templates/user_info.html:76 msgid "votes left" -msgstr "" +msgstr "votos restantes" #: templates/user_stats.html:15 msgid "User questions" -msgstr "" +msgstr "Preguntas del usuario" #: templates/user_stats.html:37 #, python-format msgid "the answer has been voted for %(vote_count)s times" -msgstr "" +msgstr "la respuesta ha sido votada %(vote_count)s veces" #: templates/user_stats.html:37 msgid "this answer has been selected as correct" -msgstr "" +msgstr "esta respuesta ha sido seleccionada como correcta" #: templates/user_stats.html:43 #, python-format msgid "the answer has been commented %(answered_question.comment_count)s times" msgstr "" +"la respuesta ha sido comentada %(answered_question.comment_count)s veces" #: templates/user_stats.html:56 msgid "votes total" -msgstr "" +msgstr "votos totales" #: templates/user_stats.html:65 msgid "user has voted up this many times" -msgstr "" +msgstr "el usuario ha votado positivo esta cantidad de veces" #: templates/user_stats.html:70 msgid "user voted down this many times" -msgstr "" +msgstr "el usuario voto negativo esta cantidad de veces" #: templates/user_stats.html:84 msgid "Tags" -msgstr "" +msgstr "Etiquetas" #: templates/user_stats.html:94 #, python-format msgid "see other questions tagged '%(tag)s' " -msgstr "" +msgstr "ver otras preguntas etiqueteadas '%(tag)s'" #: templates/user_tabs.html:7 msgid "User profile" -msgstr "" +msgstr "Perfil de usuario" #: templates/user_tabs.html:16 msgid "graph of user reputation" -msgstr "" +msgstr "gráfica de la reputación del usuario" #: templates/user_tabs.html:17 msgid "reputation history" -msgstr "" +msgstr "historial de reputación" #: templates/user_tabs.html:24 msgid "favorites" -msgstr "" +msgstr "favoritos" #: templates/user_tabs.html:29 msgid "settings" -msgstr "" +msgstr "preferencias" -#: templates/user_votes.html:14 -msgid "upvote" -msgstr "" - -#: templates/user_votes.html:16 -msgid "downvote" -msgstr "" - -#: templates/users.html:5 templates/users.html.py:23 +#: templates/users.html:6 templates/users.html.py:24 msgid "Users" -msgstr "" +msgstr "Usuarios" -#: templates/users.html:26 +#: templates/users.html:27 msgid "recent" -msgstr "" +msgstr "reciente" -#: templates/users.html:27 +#: templates/users.html:28 msgid "oldest" -msgstr "" +msgstr "más viejo" -#: templates/users.html:28 +#: templates/users.html:29 msgid "by username" -msgstr "" +msgstr "por nombre de usuario" -#: templates/users.html:34 +#: templates/users.html:35 #, python-format msgid "users matching query %(suser)s:" -msgstr "" +msgstr "usuarios que coincidan con la busqueda %(suser)s:" -#: templates/users.html:38 +#: templates/users.html:39 msgid "Nothing found." -msgstr "" +msgstr "Nada encontrado." #: templates/users_questions.html:11 msgid "this questions was selected as favorite" -msgstr "" +msgstr "esta pregunta ha sido seleccionada como favorita" #: templates/users_questions.html:33 msgid "this answer has been accepted to be correct" -msgstr "" +msgstr "esta respuesta ha sido aceptada como correcta" #: templates/authopenid/changeemail.html:6 msgid "Account: change email" -msgstr "" +msgstr "Cuenta: cambiar el email" #: templates/authopenid/changeemail.html:9 msgid "" @@ -1673,301 +2037,370 @@ msgid "" "Please keep this email address up to date so we can send you a password-" "reset email if you request one." msgstr "" +"Aquí es donde puedes cambiar el email asociado a tu cuenta de usuario.Por " +"favor manten esta dirección de correo al día de forma que podamos mandarte " +"un cambio de contraseña si tu así lo requieres." #: templates/authopenid/changeemail.html:11 #: 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 "" +msgstr "Por favor corrija los errores debajo: " #: templates/authopenid/changeemail.html:28 msgid "Email" -msgstr "" +msgstr "Email" #: templates/authopenid/changeemail.html:29 #: templates/authopenid/signin.html:60 msgid "Password" -msgstr "" +msgstr "Contraseña" #: templates/authopenid/changeemail.html:31 msgid "Change email" -msgstr "" +msgstr "Cambiar dirección email" #: templates/authopenid/changeopenid.html:7 msgid "Account: change OpenID URL" -msgstr "" +msgstr "Cuenta: cambiar la URL de OpenID" #: templates/authopenid/changeopenid.html:11 msgid "" "This is where you can change your OpenID URL. Make sure you remember it!" -msgstr "" +msgstr "Aquí es donde puedes cambiar tu OpenID URL. Asegurate de recordarla!" #: templates/authopenid/changeopenid.html:28 msgid "OpenID URL:" -msgstr "" +msgstr "URL de OpenID:" #: templates/authopenid/changeopenid.html:29 msgid "Change OpenID" -msgstr "" +msgstr "Cambiar OpenID" #: templates/authopenid/changepw.html:13 msgid "Account: change password" -msgstr "" +msgstr "Cuenta: cambiar contraseña" #: templates/authopenid/changepw.html:16 msgid "This is where you can change your password. Make sure you remember it!" -msgstr "" +msgstr "Aquí es donde puedes cambiar tu contraseña. Asegurate de recordarlo!" #: templates/authopenid/changepw.html:26 msgid "Current password" -msgstr "" +msgstr "Contraseña actual" #: templates/authopenid/changepw.html:27 msgid "New password" -msgstr "" +msgstr "Nueva contraseña" #: templates/authopenid/changepw.html:28 msgid "New password again" -msgstr "" +msgstr "Nueva contraseña nuevamente" #: templates/authopenid/changepw.html:29 templates/authopenid/settings.html:28 msgid "Change password" -msgstr "" +msgstr "Cambiar contraseña" #: templates/authopenid/complete.html:4 msgid "Connect your OpenID with this site" -msgstr "" +msgstr "Vincular tu OpenID con este sitio" #: templates/authopenid/complete.html:7 msgid "Connect your OpenID with your account on this site" -msgstr "" +msgstr "Vincular tu OpenID con tu cuenta en este sitio" #: templates/authopenid/complete.html:10 msgid "Your OpenID is accepted. Please complete this to finish registration." msgstr "" +"Tu OpenID es aceptada. Por favor completa lo siguiente para finalizar el " +"registro." #: templates/authopenid/complete.html:11 msgid "This account already exists, please use another." -msgstr "" +msgstr "Esta cuenta ya existe, por favor usar otra." #: templates/authopenid/complete.html:16 templates/authopenid/complete.html:29 #: templates/authopenid/signin.html:43 msgid "Sorry, looks like we have some errors:" -msgstr "" +msgstr "Ups, parece que hay errores:" #: templates/authopenid/complete.html:45 msgid "New account" -msgstr "" +msgstr "Nueva cuenta" #: templates/authopenid/complete.html:46 msgid "User name (<i>will be shown to others, cannot be modified</i>)" msgstr "" +"Nombre de usuario (<i>será mostrado a otros, no puede ser modificado</i>)" #: templates/authopenid/complete.html:47 msgid "Email (<i>not shared with anyone</i>)" -msgstr "" +msgstr "Email (<i>no será compartido con nadie</i>)" #: templates/authopenid/complete.html:48 msgid "create account" -msgstr "" +msgstr "crear cuenta" #: templates/authopenid/complete.html:56 msgid "Existing account" -msgstr "" +msgstr "Cuenta existente" #: templates/authopenid/complete.html:57 msgid "user name" -msgstr "" +msgstr "nombre de usuario" #: templates/authopenid/complete.html:58 msgid "password" -msgstr "" +msgstr "contraseña" #: templates/authopenid/complete.html:61 msgid "Register" -msgstr "" +msgstr "Registrarse" #: templates/authopenid/complete.html:62 templates/authopenid/signin.html:62 msgid "Forgot your password?" -msgstr "" +msgstr "¿Olvidaste tu contraseña?" #: templates/authopenid/delete.html:8 msgid "Account: delete account" -msgstr "" +msgstr "Cuenta: borrar cuenta" #: templates/authopenid/delete.html:12 msgid "" "Note: After deleting your account, anyone will be able to register this " "username." msgstr "" +"Nota: Luego de borrar tu cuenta, cualquiera podrá registrarse con este " +"nombre de usuario." #: templates/authopenid/delete.html:16 msgid "Check confirm box, if you want delete your account." -msgstr "" +msgstr "Marca caja de confirmación, si deseas borrar tu cuenta." #: templates/authopenid/delete.html:19 msgid "Password:" -msgstr "" +msgstr "Contraseña" #: templates/authopenid/delete.html:31 msgid "I am sure I want to delete my account." -msgstr "" +msgstr "Estoy seguro que quiero borrar mi cuenta." #: templates/authopenid/delete.html:32 msgid "Password/OpenID URL" -msgstr "" +msgstr "Contraseña/OpenID URL" #: templates/authopenid/delete.html:32 msgid "(required for your security)" -msgstr "" +msgstr "(requerido por tu seguridad)" #: templates/authopenid/delete.html:34 msgid "Delete account permanently" -msgstr "" +msgstr "Borrar la cuenta de forma permanente" #: templates/authopenid/sendpw.html:3 templates/authopenid/sendpw.html.py:7 msgid "Send new password" -msgstr "" +msgstr "Enviar nueva contraseña" #: templates/authopenid/sendpw.html:11 msgid "Lost your password? No problem - here you can reset it." -msgstr "" +msgstr "¿Haz perdido tu contraseña? No hay problema - aquí puedes re-crearla." #: templates/authopenid/sendpw.html:12 msgid "" "Please enter your username below and new password will be sent to your " "registered e-mail" msgstr "" +"Por favor, ingresa tu nombre de usuario y una nueva contraseña será enviada " +"a la dirección de email registrada." #: templates/authopenid/sendpw.html:29 msgid "Reset password" -msgstr "" +msgstr "Re-crear contraseña" #: templates/authopenid/sendpw.html:29 msgid "return to login" -msgstr "" +msgstr "volver a 'Ingresar'" #: templates/authopenid/sendpw.html:32 msgid "" "Note: your new password will be activated only after you click the " "activation link in the email message" msgstr "" +"Nota: tu nueva contraseña solo será activada luego de que hagas click en el " +"link de activación en el email enviado." #: templates/authopenid/settings.html:29 msgid "Give your account a new password." -msgstr "" +msgstr "Crea una nueva contraseña para tu cuenta." #: templates/authopenid/settings.html:30 msgid "Change email " -msgstr "" +msgstr "Cambiar email " #: templates/authopenid/settings.html:31 msgid "Add or update the email address associated with your account." -msgstr "" +msgstr "Agrega o actualiza el email asociado a tu cuenta." #: templates/authopenid/settings.html:34 msgid "Change openid associated to your account" -msgstr "" +msgstr "Cambia el OpenID asociado a tu cuenta" #: templates/authopenid/settings.html:37 msgid "Delete account" -msgstr "" +msgstr "Eliminar cuenta" #: templates/authopenid/settings.html:38 msgid "Erase your username and all your data from website" -msgstr "" +msgstr "Eliminar tu nombre de usuario y toda tu información del sitio" #: templates/authopenid/signin.html:3 templates/authopenid/signin.html:16 msgid "User login" -msgstr "" +msgstr "Ingreso de usuario" #: templates/authopenid/signin.html:21 msgid "we support two login modes" msgstr "" +"Puedes ingresar por cualquiera de los siguientes servicios, o " +"tradicionalmente- usando nombre de usuario y contraseña locales" #: templates/authopenid/signin.html:26 templates/authopenid/signup.html:49 msgid "Login with your OpenID" -msgstr "" +msgstr "Ingresar con tu OpenID" #: templates/authopenid/signin.html:28 msgid "select openid provider" -msgstr "" +msgstr "1) Selecciona tu proveedor de OpenID" #: templates/authopenid/signin.html:32 msgid "verify openid link and login" msgstr "" +"2) Varifica la URL de tu OpenID (escribe tu nombre de usuario donde dice " +"{nombre de usuario} si lo ves) y luego clickea 'ingresar'" #: templates/authopenid/signin.html:58 msgid "Use login name and password" -msgstr "" +msgstr "Nombre de usuario y contraseña" #: templates/authopenid/signin.html:59 msgid "Login name" -msgstr "" +msgstr "Nombre de usuario" #: templates/authopenid/signin.html:63 msgid "Create new acccount" -msgstr "" +msgstr "Crear cuenta nueva" #: templates/authopenid/signin.html:72 msgid "Why use OpenID?" -msgstr "" +msgstr "¿Porqué usar OpenID?" #: templates/authopenid/signin.html:76 msgid "with openid it is easier" -msgstr "" +msgstr "Con OpenID no necesitas crear un nuevo nombre de usuario y contraseña." #: templates/authopenid/signin.html:79 msgid "reuse openid" msgstr "" +"Puedes de forma segura re-usar el mismo nombre de usuario para todos los " +"sitios que acepten OpenID." #: templates/authopenid/signin.html:82 msgid "openid is widely adopted" msgstr "" +"OpenID es extensamente usado. Hay más de 160,000,000 cuentas de OpenID en " +"uso en el mundo. Mas de 10,000 sitios aceptan OpenID." #: templates/authopenid/signin.html:85 msgid "openid is supported open standard" msgstr "" +"OpenID es basado en un standard abierto, apoyado por muchas organizaciones." #: templates/authopenid/signin.html:89 msgid "Find out more" -msgstr "" +msgstr "Averigua más" #: templates/authopenid/signin.html:90 msgid "Get OpenID" -msgstr "" +msgstr "Adquiere una OpenID" #: templates/authopenid/signup.html:2 templates/authopenid/signup.html.py:6 msgid "Signup" -msgstr "" +msgstr "Registrate" #: templates/authopenid/signup.html:10 msgid "" "We support two types of user registration: conventional username/password, " "and" msgstr "" +"Soportamos dos formas de registro de usuario: convencional usuario/" +"contraseña, y" #: templates/authopenid/signup.html:10 msgid "the OpenID method" -msgstr "" +msgstr "OpenID" #: templates/authopenid/signup.html:15 msgid "Sorry, looks like we have some errors" -msgstr "" +msgstr "Ups, parece que hay errores." #: templates/authopenid/signup.html:33 msgid "Conventional registration" -msgstr "" +msgstr "Registro clásico" #: templates/authopenid/signup.html:34 msgid "choose a user name" -msgstr "" +msgstr "elije un nombre de usuario" #: templates/authopenid/signup.html:40 msgid "back to login" -msgstr "" +msgstr "volver al ingreso de usuario" #: templates/authopenid/signup.html:46 msgid "Register with your OpenID" +msgstr "Registrate con tu OpenID" + +#: templates/tough/question_retag.html:2 +msgid "Revise tags" +msgstr "Revisar etiquetas" + +#: templates/tough/question_retag.html:37 +msgid "tags are requried" +msgstr "las etiquetas son requeridas" + +#: templates/tough/question_retag.html:38 +msgid "up to 5 tags, less than 20 characters each" +msgstr "hasta 5 etiquetas, menos de 20 caracteres cada una" + +#: templates/tough/question_retag.html:51 +msgid "Change tags" +msgstr "Cambiar etiquetas" + +#: templates/tough/question_retag.html:74 +msgid "Change now" +msgstr "Cambiar ahora" + +#: templates/tough/question_retag.html:85 +msgid "Why use and modify tags?" +msgstr "¿Porqué usar y modificar etiquetas?" + +#: templates/tough/question_retag.html:96 +msgid "tag editors receive special awards from the community" msgstr "" +"los editores de etiquetas reciben distinciones especiales de la comunidad" + +#: templates/tough/unanswered.html:95 +msgid "number of <strong>unanswered</strong> questions" +msgstr "número de respuestas <strong>sin responder</strong>" + +#~ msgid "Community gives you awards for your questions, answers and votes." +#~ msgstr "" +#~ "La comunidad te da distinciones por tus preguntas, respuestas y votos." + +# +#~ msgid "editing tips" +#~ msgstr "Tips" + +#~ msgid "Newest questions shown first." +#~ msgstr "" +#~ "Questions are sorted by <strong>entry date</strong>.Newest questions " +#~ "shown first." diff --git a/locale/zh_CN/LC_MESSAGES/django.mo b/locale/zh_CN/LC_MESSAGES/django.mo Binary files differdeleted file mode 100644 index 3d45237b..00000000 --- a/locale/zh_CN/LC_MESSAGES/django.mo +++ /dev/null diff --git a/locale/zh_CN/LC_MESSAGES/django.po b/locale/zh_CN/LC_MESSAGES/django.po index ba32e84a..206f4b6f 100644 --- a/locale/zh_CN/LC_MESSAGES/django.po +++ b/locale/zh_CN/LC_MESSAGES/django.po @@ -1,5 +1,3 @@ -# author Evgeny Fadeev (evgeny.fadeev@gmail.com) -# site-specific messages msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" @@ -66,7 +64,6 @@ msgid "this name is already in use - please try anoter" msgstr "该用户名已被注册,请换一个试试" #: django_authopenid/forms.py:184 -#, fuzzy msgid "" "This email is already registered in our database. Please " "choose another." @@ -78,7 +75,6 @@ msgid "" msgstr "" #: django_authopenid/forms.py:253 -#, fuzzy msgid "choose a username" msgstr "选择一个用户名" @@ -105,7 +101,6 @@ msgid "new passwords do not match" msgstr "" #: django_authopenid/forms.py:434 -#, fuzzy msgid "Incorrect username." msgstr "选择一个用户名" @@ -132,7 +127,6 @@ msgid "sendpw/" msgstr "" #: django_authopenid/urls.py:26 -#, fuzzy msgid "delete/" msgstr "删除" @@ -1020,6 +1014,8 @@ msgid "most voted questions" msgstr "投票次数最多的问题" #: templates/index.html:25 +#"最有价值问题" +#"最新问题" msgid "most voted" msgstr "最有价值的问题" @@ -1041,7 +1037,6 @@ msgid "see questions tagged" msgstr "查看有关" #: templates/index.html:79 -#, fuzzy msgid "welcome to website" msgstr "CNProg欢迎您!" @@ -1053,7 +1048,7 @@ msgstr "最新标签" #: templates/index.html:93 #, fuzzy, python-format msgid "see questions tagged '%(tagname)s'" -msgstr "查看有关'%s'的问题" +msgstr "查看有关'%(tagname)s'的问题" #: templates/index.html:96 templates/index.html.py:120 msgid "popular tags" @@ -1092,6 +1087,30 @@ msgstr "或者" msgid "." msgstr "。" +#: templates/pagesize.html:5 +msgid "posts per page" +msgstr "每页显示:" + +#: templates/paginator.html:5 +msgid "previous" +msgstr "上一页" + +#: templates/questions.html:22 +msgid "Found by tags" +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/index.html:120 msgid "Please help us answer" msgstr "请帮助我们回答" @@ -1117,12 +1136,6 @@ msgstr "点击退出登录" msgid "Size per page:" msgstr "每页显示" -# paginator.html -#: templates/paginator.html:5 -#, fuzzy -msgid "Previous" -msgstr "上一页" - #: templates/privacy.html:6 templates/privacy.html.py:11 msgid "Privacy policy" msgstr "隐私政策" @@ -1432,39 +1445,10 @@ msgstr "基本的HTML标签也是支持的" msgid "learn more about Markdown" msgstr "有关Markdown详细说明" -#: templates/questions.html:6 -#, fuzzy -msgid "Question list" -msgstr "问题列表" - -#: templates/questions.html:22 -#, fuzzy -msgid "Tagged questions" -msgstr "相似的问题" - -#: templates/questions.html:22 -msgid "Query result" -msgstr "" - #: templates/questions.html:22 msgid "All questions" msgstr "所有问题" -#: templates/questions.html:24 -#, fuzzy -msgid "New questions" -msgstr "问题" - -#: templates/questions.html:24 -#, fuzzy -msgid "Newest" -msgstr "最新问题" - -#: templates/questions.html:25 -#, fuzzy -msgid "Newest updated questions" -msgstr "最新更新的问题" - #: templates/questions.html:25 #, fuzzy msgid "Active" @@ -1475,30 +1459,10 @@ msgstr "活跃问题" msgid "Questions with most answers" msgstr "您正在浏览的问题含有以下标签" -#: templates/questions.html:26 -#, fuzzy -msgid "Hottest" -msgstr "热门问题" - #: templates/questions.html:27 msgid "Questions with most votes" msgstr "" -#: templates/questions.html:27 -#, fuzzy -msgid "Best" -msgstr "最新问题" - -#: templates/questions.html:45 -#, fuzzy -msgid "Votes" -msgstr "票" - -#: templates/questions.html:46 -#, fuzzy -msgid "Visits" -msgstr "网站访问者" - # index.html #: templates/questions.html:57 templates/questions.html.py:69 #, fuzzy @@ -2102,350 +2066,350 @@ msgstr "返回登录" msgid "Register with your OpenID" msgstr "使用OpenID注册" -#~ msgid "meta site keywords, comma separated" -#~ msgstr "" -#~ "技术问答社区,中国程序员,编程技术社区,程序员社区,程序员论坛,程序员" -#~ "wiki,程序员博客" +msgid "meta site keywords, comma separated" +msgstr "" +"技术问答社区,中国程序员,编程技术社区,程序员社区,程序员论坛,程序员" +"wiki,程序员博客" -#~ msgid "what is this website" -#~ msgstr "" -#~ "CNProg是一个<strong>面向程序员</strong>的可协作编辑的<strong>开放源代码问" -#~ "答社区</strong>。" +msgid "what is this website" +msgstr "" +"CNProg是一个<strong>面向程序员</strong>的可协作编辑的<strong>开放源代码问" +"答社区</strong>。" -#~ msgid "what can one do on this website" -#~ msgstr "" -#~ "您可以在这里提问各类<strong>程序技术问题</strong> - 问题不分语言和平台。 " -#~ "同时也希望您对力所能及的问题,给予您的宝贵答案。" +msgid "what can one do on this website" +msgstr "" +"您可以在这里提问各类<strong>程序技术问题</strong> - 问题不分语言和平台。 " +"同时也希望您对力所能及的问题,给予您的宝贵答案。" -#~ msgid "Goal of this site is..." -#~ msgstr "CNProg 是为了帮助程序员解决更多问题,更加方便的解决问题。" +msgid "Goal of this site is..." +msgstr "CNProg 是为了帮助程序员解决更多问题,更加方便的解决问题。" -#~ msgid "Community gives you awards for your questions, answers and votes." -#~ msgstr "" -#~ "提出问题,给予回答,投出你的票 - CNProg 会针对你在社区的表现,授予你各类奖" -#~ "牌。" +msgid "Community gives you awards for your questions, answers and votes." +msgstr "" +"提出问题,给予回答,投出你的票 - CNProg 会针对你在社区的表现,授予你各类奖" +"牌。" -#~ msgid "please make your answer relevant to this community" -#~ msgstr "您的问题与编程相关吗?" +msgid "please make your answer relevant to this community" +msgstr "您的问题与编程相关吗?" -#~ msgid "book technical Q&A" -#~ msgstr "图书相关的技术答疑" +msgid "book technical Q&A" +msgstr "图书相关的技术答疑" -#~ msgid "blog" -#~ msgstr "Blog" +msgid "blog" +msgstr "Blog" -#~ msgid "privacy policy" -#~ msgstr "隐私政策" +msgid "privacy policy" +msgstr "隐私政策" -#~ msgid "current revision" -#~ msgstr "当前版本" +msgid "current revision" +msgstr "当前版本" -#~ msgid "number of votes" -#~ msgstr "票数" +msgid "number of votes" +msgstr "票数" -#~ msgid "current page" -#~ msgstr "当前页" +msgid "current page" +msgstr "当前页" -#~ msgid "next page" -#~ msgstr "下一页" +msgid "next page" +msgstr "下一页" -#~ msgid "page number " -#~ msgstr "第" +msgid "page number " +msgstr "第" -#~ msgid "number - make blank in english" -#~ msgstr "页" +msgid "number - make blank in english" +msgstr "页" -#~ msgid "Change tags" -#~ msgstr "修改问题标签" +msgid "Change tags" +msgstr "修改问题标签" # todo: remove magic numbers from this file -#~ msgid "up to 5 tags, less than 20 characters each" -#~ msgstr "最多5个标签,每个标签长度小于20个字符。" - -#~ msgid "Change now" -#~ msgstr "现在修改" - -#~ msgid "uses tags for the classification of questions" -#~ msgstr "用标签来分类系统的信息" - -#~ msgid "tag editors receive special awards from the community" -#~ msgstr "修改标签的用户将授予特殊的社区奖牌" - -#~ msgid "Why use and modify tags?" -#~ msgstr "为什么我只能修改问题标签?" - -#~ msgid "Found by tag" -#~ msgstr "标签问题" - -#~ msgid "Found by title" -#~ msgstr "查询结果" - -#~ msgid "most recently updated questions" -#~ msgstr "最近被更新的问题" - -#~ msgid "latest questions info" -#~ msgstr "" -#~ "问题按<strong>提问时间</strong>显示排序。新加入的问题将显示在最前面。" - -#~ msgid "" -#~ "\n" -#~ "\t\t\thave total %(q_num)s questions tagged %(tagname)s\n" -#~ "\t\t\t" -#~ msgid_plural "" -#~ "\n" -#~ "\t\t\thave total %(q_num)s questions tagged %(tagname)s\n" -#~ "\t\t\t" -#~ msgstr[0] "" -#~ "\n" -#~ "您正在浏览所有<div class=\"questions-count\">%(q_num)s</div>个标记为<span " -#~ "class=\"tag\">%(tagname)s</span></p>" -#~ msgstr[1] "" -#~ "\n" -#~ "您正在浏览所有<div class=\"questions-count\">%(q_num)s</div>个标记为<span " -#~ "class=\"tag\">%(tagname)s</span></p>" - -#~ msgid "" -#~ "\n" -#~ "\t\t\thave total %(q_num)s questions containing %(searchtitle)s\n" -#~ "\t\t\t" -#~ msgid_plural "" -#~ "\n" -#~ "\t\t\thave total %(q_num)s questions containing %(searchtitle)s\n" -#~ "\t\t\t" -#~ msgstr[0] "" -#~ "\n" -#~ "您正在浏览所有<div class=\"questions-count\">%(q_num)s</div>个标题含有" -#~ "<span class=\"tag\">%(searchtitle)s</span></p>" -#~ msgstr[1] "" -#~ "\n" -#~ "您正在浏览所有<div class=\"questions-count\">%(q_num)s</div>个标题含有" -#~ "<span class=\"tag\">%(searchtitle)s</span></p>" - -#~ msgid "number of questions" -#~ msgstr "个" - -#~ msgid "number of <strong>unanswered</strong> questions" -#~ msgstr "" -#~ "个 <span class=\"darkred\"><strong>没有回答的</strong></span> 问题。" - -#~ msgid "tagged with" -#~ msgstr "标记为" - -#~ msgid "whose title contains" -#~ msgstr "标题含有" - -#~ msgid "number of questions end of sentence" -#~ msgstr "的问题。" - -#~ msgid "Questions are sorted by the <strong>time of last update</strong>." -#~ msgstr "问题按<strong>最后更新时间</strong>显示排序。" - -#~ msgid "Most recently answered ones are shown first." -#~ msgstr "最后被回答或者>更新的问题将显示在最前面。" - -#~ msgid "Questions sorted by <strong>number of responses</strong>." -#~ msgstr "问题按<strong>回复数量</strong>显示排序。" - -#~ msgid "Most answered questions are shown first" -#~ msgstr "回复最多的问题将显示在最前面。" - -#~ msgid "Questions are sorted by the <strong>number of votes</strong>." -#~ msgstr "问题按<strong>投票数量</strong>显示排序。" - -#~ msgid "Most voted questions are shown first" -#~ msgstr "投票最多的问题将显示在最前面。" - -#~ msgid "questions that user selected as his/her favorite" -#~ msgstr "用户收藏的问题" - -#~ msgid "Frequently Asked Questions " -#~ msgstr "常见问题" - -#~ msgid "What kinds of questions can I ask here?" -#~ msgstr "我可以在这里提问什么样的问题?" - -#~ msgid "What questions should I avoid asking?" -#~ msgstr "什么样的问题我不该在这里提问?" - -#~ msgid "" -#~ "Most importanly - questions should be <strong>relevant</strong> to this " -#~ "community." -#~ msgstr "毫无疑问,首先必须是<span class=\"yellowbg\">技术编程问题!</span>" - -#~ msgid "" -#~ "Before asking the question - please make sure to use search to see " -#~ "whether your question has alredy been answered." -#~ msgstr "" -#~ "提问之前,充分利用系统的自动查找、标签和搜索,看看是否已经有一样的问题并有" -#~ "了答案。" - -#~ msgid "What should I avoid in my answers?" -#~ msgstr "什么样的回答是不受欢迎的?" - -#~ msgid "Who moderates this community?" -#~ msgstr "谁是社区的管理员?" - -#~ msgid "" -#~ "Please avoid asking questions that are not relevant to this community, " -#~ "too subjective and argumentative." -#~ msgstr "" -#~ "<span class=\"yellowbg\">与程序员或技术无关的,引起争吵或太过于主观性等违" -#~ "背社区宗旨的内容。</span>本站建立是为了帮助大众程序员解决实际技术问题,我" -#~ "们需要实际的问题!" - -#~ msgid "" -#~ "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." -#~ msgstr "" -#~ "希望用户提供针对提问的技术回答,可以是进一步了解问题实质,给予参考方案,或" -#~ "完全解决问题的回答。我们希望通过问答的形式解决用户的实际问题。因此,<span " -#~ "class=\"yellowbg\">我们不>欢迎在回答中出现不是回答问题的内容,包括针对他人" -#~ "回答的讨论,和其他无意义的浪费网络资源行为</span>。CNProg建议您使用<span " -#~ "class=\"yellowbg\">评论</span>功能来讨论你的意见和想法。" - -#~ msgid "The short answer is: <strong>you</strong>." -#~ msgstr "答案是:<span class=\"yellowbg\">每个用户。</span>" - -#~ msgid "" -#~ "The reputation system allows users earn the authorization to perform a " -#~ "variety of moderation tasks." -#~ msgstr "" -#~ "通过积分运作,<span class=\"yellowbg\">每个用户都有权限创建标签,进行对所" -#~ "有问题、回答的投票、编辑、关闭等操作。</span>" - -#~ msgid "This website is moderated by the users." -#~ msgstr "社区没有严格意义上的管理员身份" - -#~ msgid "How does reputation system work?" -#~ msgstr "什么是社区积分?" - -#~ msgid "" -#~ "Anyone can ask questions and give answers, points are not necessary for " -#~ "that." -#~ msgstr "对于正常使用社区进行提问、回答而言,积分不是必须的。" - -#~ msgid "" -#~ "As we've said before, users help running this site. Point system helps " -#~ "select users who can administer this community." -#~ msgstr "" -#~ "我们一再声明,CNProg由你来运行和维护。如果你想帮助我们来运作CNProg,你需要" -#~ "一定的积分等级。" - -#~ msgid "" -#~ "Reputation points roughly measure how community trusts you. These points " -#~ "are given to you directly by other members of the community." -#~ msgstr "" -#~ "<span class=\"yellowbg\">积分是一种用来粗略衡量社区对你有多信任的数据。</" -#~ "span>积分不是有谁来支付或直接给予你的,而是你通过获得其他用户的支持和信" -#~ "任“赚得”的。" - -#~ msgid "" -#~ "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." -#~ msgstr "" -#~ "举例来说,如果你提了一个非常有帮助的问题或者做了很有用的回答,你将会被其他" -#~ "用户投赞成票。" - -#~ msgid "" -#~ "If on the other hand someone gives a misleading answer, the answer will " -#~ "be voted down and he/she loses some points." -#~ msgstr "" -#~ "相反,你提了不受欢迎的问题,或者误导用户的回答,你将可能被其他用户投反对" -#~ "票。每个赞成" - -#~ msgid "" -#~ "Each vote in favor will generate <strong>10</strong> points, each vote " -#~ "against will subtract <strong>2</strong> points." -#~ msgstr "" -#~ "票会帮你产生<strong>10</strong>个社区积分,每个反对票会相应扣除你" -#~ "<strong>2</strong>个积分。" - -#~ msgid "" -#~ "Through the votes of other people you can accumulate a maximum of " -#~ "<strong>200</strong> points." -#~ msgstr "" -#~ "每天通过别人投赞成票,你最多只能产生<strong>200</strong>个积分,这是上限。" - -#~ msgid "After accumulating certain number of points, you can do more:" -#~ msgstr "当你累计到一定>积分,你可以在社区做更多的事情:" +msgid "up to 5 tags, less than 20 characters each" +msgstr "最多5个标签,每个标签长度小于20个字符。" + +msgid "Change now" +msgstr "现在修改" + +msgid "uses tags for the classification of questions" +msgstr "用标签来分类系统的信息" + +msgid "tag editors receive special awards from the community" +msgstr "修改标签的用户将授予特殊的社区奖牌" + +msgid "Why use and modify tags?" +msgstr "为什么我只能修改问题标签?" + +msgid "Found by tag" +msgstr "标签问题" + +msgid "Found by title" +msgstr "查询结果" + +msgid "most recently updated questions" +msgstr "最近被更新的问题" + +msgid "latest questions info" +msgstr "" +"问题按<strong>提问时间</strong>显示排序。新加入的问题将显示在最前面。" + +msgid "" +"\n" +"\t\t\thave total %(q_num)s questions tagged %(tagname)s\n" +"\t\t\t" +msgid_plural "" +"\n" +"\t\t\thave total %(q_num)s questions tagged %(tagname)s\n" +"\t\t\t" +msgstr[0] "" +"\n" +"您正在浏览所有<div class=\"questions-count\">%(q_num)s</div>个标记为<span " +"class=\"tag\">%(tagname)s</span></p>" +msgstr[1] "" +"\n" +"您正在浏览所有<div class=\"questions-count\">%(q_num)s</div>个标记为<span " +"class=\"tag\">%(tagname)s</span></p>" + +msgid "" +"\n" +"\t\t\thave total %(q_num)s questions containing %(searchtitle)s\n" +"\t\t\t" +msgid_plural "" +"\n" +"\t\t\thave total %(q_num)s questions containing %(searchtitle)s\n" +"\t\t\t" +msgstr[0] "" +"\n" +"您正在浏览所有<div class=\"questions-count\">%(q_num)s</div>个标题含有" +"<span class=\"tag\">%(searchtitle)s</span></p>" +msgstr[1] "" +"\n" +"您正在浏览所有<div class=\"questions-count\">%(q_num)s</div>个标题含有" +"<span class=\"tag\">%(searchtitle)s</span></p>" + +msgid "number of questions" +msgstr "个" + +msgid "number of <strong>unanswered</strong> questions" +msgstr "" +"个 <span class=\"darkred\"><strong>没有回答的</strong></span> 问题。" + +msgid "tagged with" +msgstr "标记为" + +msgid "whose title contains" +msgstr "标题含有" + +msgid "number of questions end of sentence" +msgstr "的问题。" + +msgid "Questions are sorted by the <strong>time of last update</strong>." +msgstr "问题按<strong>最后更新时间</strong>显示排序。" + +msgid "Most recently answered ones are shown first." +msgstr "最后被回答或者>更新的问题将显示在最前面。" + +msgid "Questions sorted by <strong>number of responses</strong>." +msgstr "问题按<strong>回复数量</strong>显示排序。" + +msgid "Most answered questions are shown first" +msgstr "回复最多的问题将显示在最前面。" + +msgid "Questions are sorted by the <strong>number of votes</strong>." +msgstr "问题按<strong>投票数量</strong>显示排序。" + +msgid "Most voted questions are shown first" +msgstr "投票最多的问题将显示在最前面。" + +msgid "questions that user selected as his/her favorite" +msgstr "用户收藏的问题" + +msgid "Frequently Asked Questions " +msgstr "常见问题" + +msgid "What kinds of questions can I ask here?" +msgstr "我可以在这里提问什么样的问题?" + +msgid "What questions should I avoid asking?" +msgstr "什么样的问题我不该在这里提问?" + +msgid "" +"Most importanly - questions should be <strong>relevant</strong> to this " +"community." +msgstr "毫无疑问,首先必须是<span class=\"yellowbg\">技术编程问题!</span>" + +msgid "" +"Before asking the question - please make sure to use search to see " +"whether your question has alredy been answered." +msgstr "" +"提问之前,充分利用系统的自动查找、标签和搜索,看看是否已经有一样的问题并有" +"了答案。" + +msgid "What should I avoid in my answers?" +msgstr "什么样的回答是不受欢迎的?" + +msgid "Who moderates this community?" +msgstr "谁是社区的管理员?" + +msgid "" +"Please avoid asking questions that are not relevant to this community, " +"too subjective and argumentative." +msgstr "" +"<span class=\"yellowbg\">与程序员或技术无关的,引起争吵或太过于主观性等违" +"背社区宗旨的内容。</span>本站建立是为了帮助大众程序员解决实际技术问题,我" +"们需要实际的问题!" + +msgid "" +"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." +msgstr "" +"希望用户提供针对提问的技术回答,可以是进一步了解问题实质,给予参考方案,或" +"完全解决问题的回答。我们希望通过问答的形式解决用户的实际问题。因此,<span " +"class=\"yellowbg\">我们不>欢迎在回答中出现不是回答问题的内容,包括针对他人" +"回答的讨论,和其他无意义的浪费网络资源行为</span>。CNProg建议您使用<span " +"class=\"yellowbg\">评论</span>功能来讨论你的意见和想法。" + +msgid "The short answer is: <strong>you</strong>." +msgstr "答案是:<span class=\"yellowbg\">每个用户。</span>" + +msgid "" +"The reputation system allows users earn the authorization to perform a " +"variety of moderation tasks." +msgstr "" +"通过积分运作,<span class=\"yellowbg\">每个用户都有权限创建标签,进行对所" +"有问题、回答的投票、编辑、关闭等操作。</span>" + +msgid "This website is moderated by the users." +msgstr "社区没有严格意义上的管理员身份" + +msgid "How does reputation system work?" +msgstr "什么是社区积分?" + +msgid "" +"Anyone can ask questions and give answers, points are not necessary for " +"that." +msgstr "对于正常使用社区进行提问、回答而言,积分不是必须的。" + +msgid "" +"As we've said before, users help running this site. Point system helps " +"select users who can administer this community." +msgstr "" +"我们一再声明,CNProg由你来运行和维护。如果你想帮助我们来运作CNProg,你需要" +"一定的积分等级。" + +msgid "" +"Reputation points roughly measure how community trusts you. These points " +"are given to you directly by other members of the community." +msgstr "" +"<span class=\"yellowbg\">积分是一种用来粗略衡量社区对你有多信任的数据。</" +"span>积分不是有谁来支付或直接给予你的,而是你通过获得其他用户的支持和信" +"任“赚得”的。" + +msgid "" +"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." +msgstr "" +"举例来说,如果你提了一个非常有帮助的问题或者做了很有用的回答,你将会被其他" +"用户投赞成票。" + +msgid "" +"If on the other hand someone gives a misleading answer, the answer will " +"be voted down and he/she loses some points." +msgstr "" +"相反,你提了不受欢迎的问题,或者误导用户的回答,你将可能被其他用户投反对" +"票。每个赞成" + +msgid "" +"Each vote in favor will generate <strong>10</strong> points, each vote " +"against will subtract <strong>2</strong> points." +msgstr "" +"票会帮你产生<strong>10</strong>个社区积分,每个反对票会相应扣除你" +"<strong>2</strong>个积分。" + +msgid "" +"Through the votes of other people you can accumulate a maximum of " +"<strong>200</strong> points." +msgstr "" +"每天通过别人投赞成票,你最多只能产生<strong>200</strong>个积分,这是上限。" + +msgid "After accumulating certain number of points, you can do more:" +msgstr "当你累计到一定>积分,你可以在社区做更多的事情:" # todo - check if it's indeed plural -#~ msgid "add comments" -#~ msgstr "添加评论" +msgid "add comments" +msgstr "添加评论" -#~ msgid "retag questions" -#~ msgstr "给任何问题整理标签" +msgid "retag questions" +msgstr "给任何问题整理标签" -#~ msgid "edit community wiki questions" -#~ msgstr "编辑wiki类问题" +msgid "edit community wiki questions" +msgstr "编辑wiki类问题" -#~ msgid "edit any answer" -#~ msgstr "编辑任何问题或答案" +msgid "edit any answer" +msgstr "编辑任何问题或答案" -#~ msgid "reopen any closed questions" -#~ msgstr "打开关闭任何人的问题" +msgid "reopen any closed questions" +msgstr "打开关闭任何人的问题" -#~ msgid "delete any comment" -#~ msgstr "删除任何一个评论" +msgid "delete any comment" +msgstr "删除任何一个评论" -#~ msgid "delete any questions and answers and perform other moderation tasks" -#~ msgstr "删除任何一个问题或答案,及其他管理功能" +msgid "delete any questions and answers and perform other moderation tasks" +msgstr "删除任何一个问题或答案,及其他管理功能" -#~ msgid "To register, do I need to create new password?" -#~ msgstr "我需要注册一个新用户吗?" +msgid "To register, do I need to create new password?" +msgstr "我需要注册一个新用户吗?" -#~ msgid "Why other people can edit my questions/answers?" -#~ msgstr "为什么其他人可以修改我的问题/回答?" +msgid "Why other people can edit my questions/answers?" +msgstr "为什么其他人可以修改我的问题/回答?" -#~ msgid "Still have questions?" -#~ msgstr "还有其他问题?" +msgid "Still have questions?" +msgstr "还有其他问题?" -#~ msgid "Please ask your question, help make our community better!" -#~ msgstr "如果您对社区还有其他疑问,请一起来完善我们的" +msgid "Please ask your question, help make our community better!" +msgstr "如果您对社区还有其他疑问,请一起来完善我们的" -#~ msgid "" -#~ "No, you don't have to. You can login through any service that supports " -#~ "OpenID, e.g. Google, Yahoo, AOL, etc." -#~ msgstr "" -#~ "不需要。社区提供了OpenID的登录支持,你要用Google、Yahoo等任何支持OpenID登" -#~ "录的帐号就可以使用系统。" +msgid "" +"No, you don't have to. You can login through any service that supports " +"OpenID, e.g. Google, Yahoo, AOL, etc." +msgstr "" +"不需要。社区提供了OpenID的登录支持,你要用Google、Yahoo等任何支持OpenID登" +"录的帐号就可以使用系统。" -#~ msgid "Login now!" -#~ msgstr "马上登录" +msgid "Login now!" +msgstr "马上登录" -#~ msgid "" -#~ "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." -#~ msgstr "" -#~ "所以问题和答案都是如Wiki一样可编辑的,我们希望社区能帮助用户沉淀、积累更多" -#~ "有用的知识和经验。" +msgid "" +"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." +msgstr "" +"所以问题和答案都是如Wiki一样可编辑的,我们希望社区能帮助用户沉淀、积累更多" +"有用的知识和经验。" -#~ msgid "If this approach is not for you, we respect your choice." -#~ msgstr "如果您不喜欢这种方式,我们尊重你的选择。" +msgid "If this approach is not for you, we respect your choice." +msgstr "如果您不喜欢这种方式,我们尊重你的选择。" -#~ msgid "answer tips" -#~ msgstr "受欢迎的提问" +msgid "answer tips" +msgstr "受欢迎的提问" -#~ msgid "try to give an answer, rather than engage into a discussion" -#~ msgstr "建议您提的问题是可以被答复的,而不仅仅是可以讨论。" +msgid "try to give an answer, rather than engage into a discussion" +msgstr "建议您提的问题是可以被答复的,而不仅仅是可以讨论。" -#~ msgid "gold badge: the highest honor and is very rare" -#~ msgstr "金牌:十分罕见之最高荣耀" +msgid "gold badge: the highest honor and is very rare" +msgstr "金牌:十分罕见之最高荣耀" -#~ msgid "" -#~ "silver badge: occasionally awarded for the very high quality contributions" -#~ msgstr "银牌:偶尔颁发之优质奖章" +msgid "" +"silver badge: occasionally awarded for the very high quality contributions" +msgstr "银牌:偶尔颁发之优质奖章" -#~ msgid "Gold badge is very rare." -#~ msgstr "金牌是十分罕见的。" +msgid "Gold badge is very rare." +msgstr "金牌是十分罕见的。" -#~ msgid "Gold badge is the highest award in this community." -#~ msgstr "获得金牌意味着你在某个层次上已经达到了顶峰。" +msgid "Gold badge is the highest award in this community." +msgstr "获得金牌意味着你在某个层次上已经达到了顶峰。" -#~ msgid "Obtaining silver badge requires significant patience." -#~ msgstr "银牌需要经过长时间的奋斗才能获得。" +msgid "Obtaining silver badge requires significant patience." +msgstr "银牌需要经过长时间的奋斗才能获得。" -#~ msgid "%s ago" -#~ msgstr "于%s<font class=\"darkred\">关闭</font>" +msgid "%s ago" +msgstr "于%s<font class=\"darkred\">关闭</font>" diff --git a/middleware/__init__.py b/middleware/__init__.py deleted file mode 100644 index e69de29b..00000000 --- a/middleware/__init__.py +++ /dev/null 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
++import 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 "用户名不正确" ++ ++#: 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 "该OpenID %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 "请改正以下错误:" ++ ++#: 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 "请修改您的OpenID地址,请不要忘记这个地址!" ++ ++#: 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 "修改和你帐号绑定的OpenID地址" ++ ++#: 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'技术问答社区,中国程序员,编程技术社区,程序员社区,程序员论坛,程序员wiki,程序员博客'
++APP_DESCRIPTION = u'中国程序员的编程技术问答社区。我们做专业的、可协作编辑的技术问答社区。'
++APP_INTRO = u' <p>CNProg是一个<strong>面向程序员</strong>的可协作编辑的<strong>开放源代码问答社区</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, '&').replace(pr_lt, '<').replace(pr_gt, '>').replace(pr_quot, '"'); } function textToHtml(str) { return str.replace(pr_amp, '&').replace(pr_lt, '<').replace(pr_gt, '>'); } var pr_ltEnt = /</g; var pr_gtEnt = />/g; var pr_aposEnt = /'/g; var pr_quotEnt = /"/g; var pr_ampEnt = /&/g; var pr_nbspEnt = / /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 '); 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, '&').replace(pr_lt, '<').replace(pr_gt, '>').replace(pr_quot, '"'); } function textToHtml(str) { return str.replace(pr_amp, '&').replace(pr_lt, '<').replace(pr_gt, '>'); } var pr_ltEnt = /</g; var pr_gtEnt = />/g; var pr_aposEnt = /'/g; var pr_quotEnt = /"/g; var pr_ampEnt = /&/g; var pr_nbspEnt = / /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 '); 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" />发布我的提问到我的Twitter<br> ++ <input id="cbReply" type="checkbox" />发布我的回答到我的Twitter<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_local.py b/settings_local.py new file mode 100644 index 00000000..a5d13465 --- /dev/null +++ b/settings_local.py @@ -0,0 +1,21 @@ +# 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 --git a/templates/about.html b/templates/about.html index 6638060e..4655a641 100644 --- a/templates/about.html +++ b/templates/about.html @@ -1,71 +1,21 @@ +<!-- template about.html --> {% extends "base_content.html" %} +{% load i18n %} {% load extra_tags %} {% load humanize %} -{% block title %}{% spaceless %}关于本站{% endspaceless %}{% endblock %} +{% block title %}{% spaceless %}{% trans "About" %}{% endspaceless %}{% endblock %} {% block forejs %} {% endblock %} {% block content %} <div class="headNormal"> -关于本站 +{% trans "About" %} </div> <div class="content"> - <p> - CNProg 是<strong>一个面向中国程序员的免费技术问答社区</strong>。它是一个介于论坛、博客、维基和Digg之间的社区系统,基于Python和Django开发。<br> - 创办CNProg的灵感来自于国外知名QA社区<a href="http://www.stackoverflow.com">StackOverflow</a>,但是CNProg不仅仅是一个汉化版的SO。<br> - 我们通过开源社区来维护和更新源代码,你可以访问<strong><a href="http://code.google.com/p/cnprog/">这里</a></strong>获取本站的所有源代码(请注意源代码使用的授权许可)。<br> - </p> - <br> - <p> - <strong>我们不运作社区,由你来运作。</strong>CNProg 是<strong><a href="http://blog.cnprog.com/2009/01/%e7%94%a8%e6%88%b7%e9%a9%b1%e5%8a%a8%e7%9a%84%e6%8a%80%e6%9c%af%e7%a4%be%e5%8c%ba/">一个由用户来驱动的社区</a></strong>。每个用户不仅是管理员,也是社区功能需求的提出者。<br> - 社区内容是协作的,系统越信任你,你就在社区获得更多的管理权限,可以开始编辑问题或回答, - 帮助我们组织问题和答案,帮助需要帮助的广大程序员用户。<br> - 透明、开放、全民管理的运作模式是本网站的特点,我们希望通过CNProg让用户能够更加容易地寻求帮助,找到问题答案,解决实际的技术问题。 - </p> - <p> - 我们关注国内程序员的成长! - </p> - - <br> - <h3 class="subtitle">你们是谁?</h3> - <p> - 我们是一群奋斗在互联网的编程爱好者,和你一样,也是希望自己编写高质量软件的开发人员。 - 我们的团队: - </p> - <table cellspacing="5" cellpadding="3"> - <tr> - <td width="150px"><img src="/content/images/nophoto.png"></td> - <td width="150px"><img src="/content/images/nophoto.png"></td> - <td width="150px"><img src="/content/images/nophoto.png"></td> - <td width="150px"></td> - </tr> - <tr> - <td> </td> - <td> </td> - <td> </td> - <td><a ></a></td> - </tr> - <tr> - <td colspan="4" height="5"></td> - </tr> - <tr> - <td width="150px"><img src="/content/images/nophoto.png"></td> - <td width="150px"><img src="/content/images/nophoto.png"></td> - <td width="150px"></td> - <td width="150px"></td> - </tr> - <tr> - <td> </td> - <td> </td> - <td> </td> - <td> </td> - </tr> - </table> - <p> - 欢迎访问我们的<strong><a href="http://blog.cnprog.com">团队Blog</a></strong>或查看更多介绍的<a href="/faq" class="big">CNProg FAQ</a>。 - </p> + <p>edit file templates/about.html. Below are just suggestions of what can go here</p> + <p>what is your site for?</p> + <p>how does it work? what are roles of members?</p> + <p>is there a place to find out more about this website?</p> </div> {% endblock %} - - - +<!-- end template about.html --> diff --git a/templates/allfiles b/templates/allfiles new file mode 100644 index 00000000..3ca0191e --- /dev/null +++ b/templates/allfiles @@ -0,0 +1,30 @@ +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 --git a/templates/answer_edit_tips.html b/templates/answer_edit_tips.html index 3ab63f70..565c5298 100644 --- a/templates/answer_edit_tips.html +++ b/templates/answer_edit_tips.html @@ -1,54 +1,53 @@ -<!-- template answer_edit_tips.html --> -{% load i18n %} -<div class="boxC"> - <p class="subtitle darkred">{% trans "answer tips" %}</p> - <div> - <ul class="list-item"> - <li> <b>{% trans "please make your answer relevant to this community" %}</b> - </li> - <li> - {% trans "try to give an answer, rather than engage into a discussion" %} - </li> - <li> - {% trans "please try to provide details" %} - </li> - <li> -{% trans "be clear and concise" %} - </li> - </ul> - <a href="/faq/" target="_blank" title="{% trans "see frequently asked questions" %}" style="float:right;position:relative">faq »</a> - <br> - </div> -</div> - -<div class="boxC"> - <p class="subtitle">{% trans "Markdown tips" %}</p> - <ul class="list-item"> - <li> - {% trans "*italic* or __italic__" %} - </li> - <li> -{% trans "**bold** or __bold__" %} - </li> - <li> - <b>{% trans "link" %}</b>:[{% trans "text" %}](http://url.com/ "{% trans "title" %}") - - </li> - +<!-- template answer_edit_tips.html --> +{% load i18n %} +<div class="boxC"> + <p class="subtitle darkred">{% trans "answer tips" %}</p> + <div> + <ul class="list-item"> + <li> <b>{% trans "please make your answer relevant to this community" %}</b> + </li> + <li> + {% trans "try to give an answer, rather than engage into a discussion" %} + </li> + <li> + {% trans "please try to provide details" %} + </li> + <li> + {% trans "be clear and concise" %} + </li> + </ul> + <a href="/faq/" target="_blank" title="{% trans "see frequently asked questions" %}" style="float:right;position:relative">faq »</a> + <br> + </div> +</div> + +<div class="boxC"> + <p class="subtitle">{% trans "Markdown tips" %}</p> + <ul class="list-item"> + <li> + {% trans "*italic* or __italic__" %} + </li> + <li> + {% trans "**bold** or __bold__" %} + </li> + <li> + <b>{% trans "link" %}</b>:[{% trans "text" %}](http://url.com/ "{% trans "title" %}") + + </li> <li> <b>{% trans "image" %}</b>:![alt {% trans "text" %}](/path/img.jpg "{% trans "title" %}") </li> <li> -{% trans "numbered list:" %} - 1. Foo - 2. Bar + {% trans "numbered list:" %} + 1. Foo + 2. Bar </li> <li> -{% trans "basic HTML tags are also supported" %} + {% trans "basic HTML tags are also supported" %} </li> </ul> <a href="http://en.wikipedia.org/wiki/Markdown" target="_blank" style="float:right;position:relative">{% trans "learn more about Markdown" %} »</a> - <br> + <br> </div> -<!-- end template answer_edit_tips.html -->
\ No newline at end of file +<!-- end template answer_edit_tips.html --> diff --git a/templates/authopenid/htmlfiles b/templates/authopenid/htmlfiles new file mode 100644 index 00000000..1b9dccd0 --- /dev/null +++ b/templates/authopenid/htmlfiles @@ -0,0 +1,8 @@ +changeemail.html +changeopenid.html +changepw.html +delete.html +failure.html +sendpw.html +settings.html +signup.html diff --git a/templates/badges.html b/templates/badges.html index ef0a5451..7fd1402a 100644 --- a/templates/badges.html +++ b/templates/badges.html @@ -1,3 +1,4 @@ +<!-- template badges.html --> {% extends "base.html" %} {% load extra_tags %} {% load humanize %} diff --git a/templates/content/style/default.css b/templates/content/style/default.css index 9b561803..0221cc03 100644 --- a/templates/content/style/default.css +++ b/templates/content/style/default.css @@ -164,7 +164,7 @@ h4 {display:block;font-size:90%; font-family:Verdana;color:#ccc;} color:darkred; font-weight:400; font-size:100%; - letter-spacing:1px; + /*letter-spacing:1px;*/ } @@ -198,7 +198,7 @@ h4 {display:block;font-size:90%; font-family:Verdana;color:#ccc;} float: left; font-size: 140%; font-weight:700; - letter-spacing:3px; + /*letter-spacing:3px;*/ margin-top:8px; padding:5px 0 0 3px ; height:20px; @@ -329,7 +329,7 @@ h4 {display:block;font-size:90%; font-family:Verdana;color:#ccc;} font-size:120%; font-weight:bold; width:120px; - letter-spacing:1px; + /*letter-spacing:1px;*/ background-color:#D4D0C8; } .notify @@ -461,7 +461,7 @@ h4 {display:block;font-size:90%; font-family:Verdana;color:#ccc;} } .highlight-box{ - letter-spacing:1px; + /*letter-spacing:1px;*/ color:#735005; } @@ -890,7 +890,7 @@ h4 {display:block;font-size:90%; font-family:Verdana;color:#ccc;} margin-bottom:-10px; width:600px; color:#aaa; - letter-spacing:1px; + /*letter-spacing:1px;*/ } @@ -1750,4 +1750,4 @@ a.comment-user:hover { .error{color:red;} .error-list li{padding:5px;} .login{margin-bottom:10px;} -.fieldset{border:solid 1px #777;margin-top:10px;padding:10px;}
\ No newline at end of file +.fieldset{border:solid 1px #777;margin-top:10px;padding:10px;} diff --git a/templates/content/style/style.css b/templates/content/style/style.css index d0fac81c..165903ba 100644 --- a/templates/content/style/style.css +++ b/templates/content/style/style.css @@ -8,7 +8,7 @@ div{margin:0 auto; padding:0;} h1,h2,h3,h4,h5,h6,ul,li,dl,dt,dd,form,img,p{margin:0; padding:0; border:none; }
input, select {font-family:Trebuchet MS,"segoe ui",Helvetica,"Microsoft YaHei",宋体,Tahoma,Verdana,MingLiu,PMingLiu,Arial,sans-serif;}
p{margin-bottom:4px; font-size:13px; line-height:160%;}
-a {color:#663333; text-decoration:none;}
+a {color:#333333; text-decoration:none;}
a:hover {text-decoration:underline;}
.block{width:960px; height:auto;}
.fleft{float:left;}
@@ -81,27 +81,46 @@ blockquote #CALeft{width:700px; float:left; position:relative;padding-left:5px}
#CARight{width:240px; float:right; padding-right:5px}
#CAFull{float:left;padding:0 5px 0 5px;width:950px;}
-#ground {clear:both;border-top:6px solid #000; padding-top:6px; padding-bottom:50px; text-align:center;background:#777;}
+#ground {width:100%;border-top:1px solid #000; padding-top:6px; padding-bottom:10px; text-align:center;background:#777;}
+/*#licenseLogo {top:10px;right:10px;}*/
/*顶部及导航栏*/
-#top {height:20px; text-align:right; padding:3px;background-color:#eee;}
+#top {height:20px; text-align:right; padding:3px;background-color:#ffffff;}
#header {width:960px;}
-#top a {height:35px; text-align:right;letter-spacing:1px; margin-left:20px;text-decoration:underline; font-size:12px; color:#666;}
+#top a {height:35px; text-align:right;
+ /*letter-spacing:1px; */
+ margin-left:20px;text-decoration:underline; font-size:12px; color:#333333;}
#logo {padding:5px;}
#navBar {float:clear;position:relative;display:block;width:960px;}
-#navBar .nav {margin:20px 0px 0px 16px;letter-spacing:1px; }
-#navBar .nav a {color:#333; background-color:#F9F7ED; padding:0px 12px 3px 12px; height:25px; line-height:30px;margin-left:10px; font-size:15px; font-weight:400; text-decoration:none;display: block;float: left;}
+#navBar .nav {margin:20px 0px 0px 16px;
+ /*letter-spacing:1px; */
+ }
+#navBar .nav a {color:#333; background-color:#F9F7ED;
+ border-bottom: none;
+ border-left: 1px solid #aaaaaa;
+ border-right: 1px solid #aaaaaa;
+ border-top: 1px solid #aaaaaa;
+ padding:0px 12px 3px 12px; height:25px; line-height:30px;margin-left:10px; font-size:15px; font-weight:400; text-decoration:none;display: block;float: left;}
#navBar .nav a:hover {text-decoration:underline}
-#navBar .nav a.on {height:24px;line-height:28px;border:1px solid #B02B2C; background:#B02B2C; color:#FFF; font-weight:600; text-decoration:none}
+#navBar .nav a.on {height:24px;line-height:28px;
+ border-top:1px solid #e66222;
+ border-bottom: 1px solid #d64000;
+ border-right:1px solid #e66222;
+ border-left:1px solid #e66222;
+ /*background:#A31E39; */
+ background:#d64000;
+ color:#FFF; font-weight:600; text-decoration:none}
#navBar .nav a.special {font-size:15px; color:#B02B2C; font-weight:bold; text-decoration:none; }
#navBar .nav a.special:hover {text-decoration:underline;}
#navBar .nav div.focus {float:right; padding-right:0px;}
/*搜索栏*/
-#searchBar {background-color:#B02B2C;padding:5px;}
+#searchBar {background-color:#9db2b1;padding:5px;} /* #B02B2C */
#searchBar .content { }
#searchBar .searchInput {font-size:13px; height:18px; width:400px;}
#searchBar .searchBtn {font-size:14px; height:26px; width:80px;}
-#searchBar .options {padding-top:5px; font-size:100%;color:#EEE;letter-spacing:1px;}
+#searchBar .options {padding-top:5px; font-size:100%;color:#EEE;
+ /*letter-spacing:1px;*/
+ }
#searchBar .options INPUT {margin-left:15px;}
#searchBar .options INPUT:hover {cursor:pointer}
@@ -111,7 +130,9 @@ blockquote #listA .qstA thumb {float:left; }
#listA .qstA H2 {font-size:15px; font-weight:800; margin:8px auto;padding:0px;}
#listA .qstA H2 a {color:#663333; }
-#listA .qstA .stat {font-size:13px;letter-spacing:1px;float:right;}
+#listA .qstA .stat {font-size:13px;
+ /*letter-spacing:1px;*/
+ float:right;}
#listA .qstA .stat span {margin-right:5px;}
#listA .qstA .stat td {min-width:40px;text-align:center;}
#listA .qstA .stat .num {font-family:arial;color:#905213; font-size:20px; font-weight:800;}
@@ -270,7 +291,9 @@ a:hover.medal {color:#333; text-decoration:none; background:url(/content/images .headMedals {float:left; height:23px; line-height:23px; margin:5px 0 0 5px;padding:0px 6px 0px 15px; font-size:15px; font-weight:700; border-bottom:0px solid #777; border-left:0px solid #darkred; background-color:#FFF;background:url(/content/images/dot-list.gif) no-repeat left center;}
.headLogin {float:left; padding:3px; font-size:15px; font-weight:800; background:url(/content/images/ico_login.gif) no-repeat; padding-left:24px;}
.headNormal {text-align:left;padding:3px; font-size:15px; margin-bottom:12px; font-weight:800;border-bottom:1px solid #777;}
-.headUser {text-align:left;padding:5px; font-size:20px; letter-spacing:1px;margin-bottom:12px; font-weight:800;border-bottom:1px solid #777;}
+.headUser {text-align:left;padding:5px; font-size:20px;
+ /*letter-spacing:1px;*/
+ margin-bottom:12px; font-weight:800;border-bottom:1px solid #777;}
/*RSS订阅*/
#feeds {margin:10px 0; }
#feeds a {background:url(/content/images/feed-icon-small.png) no-repeat 0; padding-left:18px; font-weight:700; font-size:13px; }
@@ -330,6 +353,7 @@ a:hover.medal {color:#333; text-decoration:none; background:url(/content/images padding: 15px;
color: White;
background-color: darkred;
+ text-align: center;
}
.vote-notification a
{
@@ -446,9 +470,6 @@ a.comment-user, a.comment-user:hover { a.comment-user:hover {
text-decoration:underline;
}
-.deleted{
- background:#F4E7E7 none repeat scroll 0 0;
-}
/*回答*/
#answers {}
.answer{
@@ -521,6 +542,10 @@ a.comment-user:hover { .answer-img-accept:hover{background:url(/content/images/vote-accepted-on.png)}
+.deleted{
+ background:#F4E7E7 none repeat scroll 0 0;
+}
+
/*标签列表*/
.tagsbox {}
.tagsbox a {color:#000;line-height:30px;margin-right:10px;font-size:100%;background-color:#F9F7ED;padding:3px;}
@@ -616,7 +641,7 @@ span.form-error { font-weight:600;
width:100%;
color:#aaa;
- letter-spacing:1px;
+ /*letter-spacing:1px;*/
text-align:left;
}
@@ -699,7 +724,9 @@ background-color: #97ff97; /*用户资料页面*/
.count {font-family:Arial;font-size:200%;font-weight:700;color:#777}
-.scoreNumber{font-family:Arial;font-size:35px;font-weight:800;color:#777;line-height:40px;letter-spacing:0px}
+.scoreNumber{font-family:Arial;font-size:35px;font-weight:800;color:#777;line-height:40px;
+ /*letter-spacing:0px*/
+ }
.user-details{font-size:13px;}
.user-about{background-color:#EEEEEE;height:200px;line-height:20px; overflow:auto;padding:10px;width:90%;}
.user-edit-link {background:url(/content/images/edit.png) no-repeat; padding-left:20px; font-weight:600;}
@@ -747,13 +774,18 @@ width:950;margin-bottom:10px; font-family:Arial;
}
+.stats div {
+ font-size:11px;
+ text-align:center;
+}
+
.narrow .votes {
background:#EEEEEE none repeat scroll 0 0;
float:left;
- height:38px;
+ height:42px;
margin:0 3px 0 0;
padding:5px;
- width:40px;
+ width:46px;
text-align:center;
-moz-border-radius: 5px;
-khtml-border-radius: 5px;
@@ -771,10 +803,11 @@ width:950;margin-bottom:10px; .narrow .views {
float:left;
- height:38px;
+ height:42px;
margin:0 7px 0 0;
- padding:5px 0 5px 4px;
- width:40px;
+ /*padding:5px 0 5px 4px;*/
+ padding: 5px;
+ width:46px;
text-align:center;
-moz-border-radius: 5px;
-khtml-border-radius: 5px;
@@ -784,10 +817,10 @@ width:950;margin-bottom:10px; .narrow .status {
float:left;
- height:38px;
+ height:42px;
margin:0 3px 0 0;
padding:5px;
- width:40px;
+ width:46px;
text-align:center;
-moz-border-radius: 5px;
-khtml-border-radius: 5px;
@@ -928,7 +961,9 @@ div.started .reputation-score { .blogRss {float:right;margin:0 10px 0 0;width:460px;height:240px;background-color:#EEE; padding:5px;}
.bookQuestions {margin-bottom:10px;}
.bookFeed {float:right;}
-.bookAsk{letter-spacing:1px; float:right;margin:-30px 10px 0 0; padding:3px 5px 3px 5px;}
+.bookAsk{
+ /*letter-spacing:1px; */
+ float:right;margin:-30px 10px 0 0; padding:3px 5px 3px 5px;}
.bookAsk a {font-size:15px; color:#FFF; font-weight:bold; text-decoration:none;background-color:#EC7000;padding:3px 6px 3px 6px; }
.bookAsk a:hover {text-decoration:underline;}
@@ -944,7 +979,9 @@ div.started .reputation-score { .silver, .badge2 {color:#CCCCCC;}
.bronze, .badge3 {color:#CC9933;}
.score {font-weight:800; color:#333;}
-.footerLinks {color:#EEE; font-size:13px; letter-spacing:1px;}
+.footerLinks {color:#EEE; font-size:13px;
+ /* letter-spacing:1px;*/
+ }
.footerLinks a {color:#FFF; font-size:13px;}
.subSearch {margin-bottom:12px; padding:4px;}
a.comment {background:#EEE; color:#993300; padding:4px;}
@@ -959,7 +996,15 @@ ul.bulleta li {background:url(/content/images/bullet_green.gif) no-repeat 0px 2p .message{padding:5px;font-weight:bold;background-color:#eee;margin:10px 0 10px 0;}
.warning{color:red;}
.darkred{color:darkred;}
-.submit{cursor:pointer;letter-spacing:1px;background-color:#D4D0C8;height:40px;border:1px solid #777;width:100px;font-weight:bold;font-size:120%;}
+.submit{
+ cursor:pointer;
+ /*letter-spacing:1px;*/
+ background-color:#D4D0C8;
+ height:40px;
+ border:1px solid #777;
+/* width:100px; */
+ font-weight:bold;
+ font-size:120%;}
.submit:hover{text-decoration:underline;}
.ask-body{padding-right:10px;}
.thousand{color:orange;}
@@ -996,4 +1041,4 @@ ul.bulleta li {background:url(/content/images/bullet_green.gif) no-repeat 0px 2p padding-left: 3px;
padding-right: 3px;
cursor:pointer;
-}
\ No newline at end of file +}
diff --git a/templates/faq.html b/templates/faq.html index e9650c3e..31ee444a 100644 --- a/templates/faq.html +++ b/templates/faq.html @@ -1,47 +1,47 @@ +<!-- template faq.html --> {% extends "base_content.html" %} {% load extra_tags %} {% load humanize %} +{% load i18n %} {% block title %}{% spaceless %}FAQ{% endspaceless %}{% endblock %} {% block forejs %} {% endblock %} {% block content %} <div class="headNormal"> - 常见问题(FAQ) + {% trans "Frequently Asked Questions " %}(FAQ) </div> <div id="main-body" style="width:100%"> - <h3 class="subtitle">我可以在这里提问什么样的问题?</h3> - <p>毫无疑问,首先必须是<span class="yellowbg">技术编程问题!</span> - 提问之前,充分利用系统的自动查找、标签和搜索,看看是否已经有一样的问题并有了答案。<br> - 避免问相同的问题,减少后有问题的朋友的疑惑,以后能够清晰地找到唯一问题和答案。 + <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">什么样的问题我不该在这里提问?</h3> - <p> <span class="yellowbg">与程序员或技术无关的,引起争吵或太过于主观性等违背社区宗旨的内容。</span>本站建立是为了帮助大众程序员解决实际技术问题,我们需要实际的问题! - </p><p> - 同样,在社区建立之初,很多用户可能对社区有各种各样的疑问。我们希望能够通过更多的faq或者文档去解释这些疑问,如果用户没有找到答案,希望你在社区提出此类问题,并引用“faq”或者“cnprog”等相关的标签。毕竟,访问社区的用户,是关心他们要寻找的答案,不是来学习如何使用复杂的社区功能的。 - </p><p> - 如果还没有拜读过Eric S. Raymond的<a href="http://www.catb.org/~esr/faqs/smart-questions.html">《How To Ask Questions The Smart Way》</a>的朋友,推荐先读一下大师的箴言。另外,这里有一<a href="http://www.dianbo.org/9238/stone/tiwendezhihui.htm">中文版本</a>,可以参考浏览。 - </p><p><span class="yellowbg">管理运行社区的是你们,而不是我们。</span></p> + <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">什么样的回答是不受欢迎的?</h3> - <p> CNProg 希望用户提供针对提问的技术回答,可以是进一步了解问题实质,给予参考方案,或完全解决问题的回答。我们希望通过问答的形式解决用户的实际问题。因此,<span class="yellowbg">我们不欢迎在回答中出现不是回答问题的内容,包括针对他人回答的讨论,和其他无意义的浪费网络资源行为</span>。CNProg建议您使用<span class="yellowbg">评论</span>功能来讨论你的意见和想法。 - + <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">谁是社区的管理员?</h3> - <p> 答案是:<span class="yellowbg">每个用户。</span><br> - - 社区没有严格意义上的管理员身份。 - 通过积分运作,<span class="yellowbg">每个用户都有权限创建标签,进行对所有问题、回答的投票、编辑、关闭等操作。</span> + <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">什么是社区积分?</h3> - <p> 对于正常使用社区进行提问、回答而言,积分不是必须的。<br> - 我们一再声明,CNProg由你来运行和维护。如果你想帮助我们来运作CNProg,你需要一定的积分等级。<span class="yellowbg">积分是一种用来粗略衡量社区对你有多信任的数据。</span>积分不是有谁来支付或直接给予你的,而是你通过获得其他用户的支持和信任“赚得”的。 - <br><br> - 举例来说,如果你提了一个非常有帮助的问题或者做了很有用的回答,你将会被其他用户投赞成票。相反,你提了不受欢迎的问题,或者误导用户的回答,你将可能被其他用户投反对票。每个赞成票会帮你产生<strong>10</strong>个社区积分,每个反对票会相应扣除你<strong>2</strong>个积分。每天通过别人投赞成票,你最多只能产生<strong>200</strong>个积分,这是上限。当你累计到一定积分,你可以在社区做更多的事情:<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 "Through the votes of other people you can accumulate a maximum of <strong>200</strong> points." %} + {% trans "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> @@ -49,66 +49,65 @@ </tr> <tr> <td style="text-align:right;padding-right:5px"><strong>15</strong></td> - <td>投赞成票</td> + <td>{% trans "upvote" %}</td> </tr> <tr> <td style="text-align:right;padding-right:5px"><strong>15</strong></td> - <td>标记垃圾帖</td> + <td>{% trans "use tags" %}</td> </tr> <tr> <td style="text-align:right;padding-right:5px"><strong>50</strong></td> - <td>添加评论</td> + <td>{% trans "add comments" %}</td> </tr> <tr> <td style="text-align:right;padding-right:5px"><strong>100</strong></td> - <td>投反对票</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>给任何问题整理标签</td> + <td>{% trans "retag questions" %}</td> </tr> <tr> <td style="text-align:right;padding-right:5px"><strong>750</strong></td> - <td>编辑wiki类问题</td> + <td>{% trans "edit community wiki questions" %}</td> </tr> <tr> <td style="text-align:right;padding-right:5px"><strong>2000</strong></td> - <td>编辑任何问题或答案</td> + <td>{% trans "edit any answer" %}</td> </tr> <tr> <td style="text-align:right;padding-right:5px"><strong>3000</strong></td> - <td>打开关闭任何人的问题</td> + <td>{% trans "open any closed question" %}</td> </tr> <tr> <td style="text-align:right;padding-right:5px"><strong>5000</strong></td> - <td>删除任何一个评论</td> + <td>{% trans "delete any comment" %}</td> </tr> <tr> <td style="text-align:right;padding-right:5px"><strong>10000</strong></td> - <td>删除任何一个问题或答案,及其他管理功能</td> + <td>{% trans "delete any questions and answers and perform other moderation tasks" %}</td> </tr> </table> </p><br> - <h3 class="subtitle">我需要注册一个新用户吗?</h3> - <p> 不需要。社区提供了OpenID的登录支持,你要用Google、Yahoo等任何支持OpenID登录的帐号就可以使用系统。<strong><a href="/account/signin">马上登录</a> »</strong> + <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">为什么其他人可以修改我的问题/回答?</h3> - <p> CNProg 是为了帮助程序员解决更多问题,更加方便的解决问题。所以问题和答案都是如Wiki一样可编辑的,我们希望社区能帮助用户沉淀、积累更多有用的知识和经验。如果您不喜欢这种方式,我们尊重你的选择。 + <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">还有其他问题?</h3> - <p> 如果您对社区还有其他疑问,请一起来完善我们的<a href="/tags/faq" class="big">CNProg FAQ</a>。 + <h3 class="subtitle">{% trans "Still have questions?" %}</h3> + <p>{% trans "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 %} - - - +<!-- end template faq.html --> diff --git a/templates/footer.html b/templates/footer.html index 46649b9f..61e6e6bb 100644 --- a/templates/footer.html +++ b/templates/footer.html @@ -1,28 +1,33 @@ -{% load extra_tags %}
+<!-- template footer.html -->
+{% load extra_tags %}
{% load i18n %}
+<!-- 页面底部开始: -->
<div id="ground">
<div class="footerLinks" >
- <a href="/about">{% trans "About us" %}</a><span class="link-separator"> |</span>
+ <a href="/about">{% trans "about" %}</a><span class="link-separator"> |</span>
<a href="/faq">{% trans "faq" %}</a><span class="link-separator"> |</span>
- <a href="http://blog.cnprog.com">Blog</a><span class="link-separator"> |</span>
- <a href="mailto:team@cnprog.com">{% trans "Contact" %}</a><span class="link-separator"> |</span>
- <a href="/privacy">{% trans "Privacy" %}</a><span class="link-separator"> |</span>
- <a href="http://cnprog.uservoice.com" target="_blank">{% trans "Feedback" %}</a>
+ <a href="{{ blog_url }}">{% trans "blog" %}</a><span class="link-separator"> |</span>
+ <a href="{{ webmaster_email }}">{% trans "contact us" %}</a><span class="link-separator"> |</span>
+ <a href="/privacy">{% trans "privacy policy" %}</a><span class="link-separator"> |</span>
+ <a href="{{ feedback_url }}" target="_blank">{% trans "give feedback" %}</a>
</div>
<p style="margin-top:10px;">
<a href="http://code.google.com/p/cnprog/" target="_blank">
<img src="/content/images/djangomade124x25_grey.gif" border="0" alt="Made with Django." title="Made with Django." >
</a>
+ <!--<div style="font-size:90%;color:#333">{% trans "current revision" %}: R-0120-20090406</div>-->
</p>
- <p style="margin-top:-30px; margin-right:15px;" class="fright"><img src="/content/images/cc-wiki.png" title="Creative Commons: Attribution - Share Alike" alt="cc-wiki" width="50" height="68" /></p>
+ <p id="licenseLogo"><img src="/content/images/cc-wiki.png" title="Creative Commons: Attribution - Share Alike" alt="cc-wiki" width="50" height="68" /></p>
</div>
+ <!-- 页面底部结束: -->
<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
try {
- var pageTracker = _gat._getTracker("UA-248512-5");
+ var pageTracker = _gat._getTracker({{ google_analytics_key }});
pageTracker._trackPageview();
} catch(err) {}
</script>
+<!-- end template footer.html -->
diff --git a/templates/okfiles b/templates/okfiles new file mode 100644 index 00000000..3ca0191e --- /dev/null +++ b/templates/okfiles @@ -0,0 +1,30 @@ +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 --git a/templates/pagesize.html b/templates/pagesize.html index e5e17a24..90003749 100644 --- a/templates/pagesize.html +++ b/templates/pagesize.html @@ -2,7 +2,7 @@ {% load i18n %} {% if is_paginated %} <div class="paginator"> - <span class="text">{% trans "Size per page:" %}</span> + <span class="text">{% trans "posts per page" %}</span> {% ifequal pagesize 10 %} <span class="curr">10</span> {% else %} diff --git a/templates/paginator.html b/templates/paginator.html index ae8329cb..2fba5425 100644 --- a/templates/paginator.html +++ b/templates/paginator.html @@ -1,9 +1,10 @@ +<!-- paginator.html --> {% spaceless %} {% load i18n %} {% if is_paginated %} <div class="paginator"> -{% if has_previous %}<span class="prev"><a href="{{base_url}}page={{ previous }}{{ extend_url }}" title="{% trans 'Previous'%}">« <% trans "Previous" %></a></span>{% endif %} - +{% if has_previous %}<span class="prev"><a href="{{base_url}}page={{ previous }}{{ extend_url }}" title="{% trans "previous" %}"> +« {% trans "previous" %}</a></span>{% endif %} {% if not in_leading_range %} {% for num in pages_outside_trailing_range %} <span class="page"><a href="{{base_url}}page={{ num }}{{ extend_url }}" >{{ num }}</a></span> @@ -15,22 +16,23 @@ {% ifequal num page %} {% ifequal pages 1 %} {% else %} - <span class="curr" title='<% trans "Current page" %>'>{{ num }}</span> + <span class="curr" title="{% trans "current page" %}">{{ num }}</span> {% endifequal %} {% else %} - <span class="page"><a href="{{base_url}}page={{ num }}{{ extend_url }}" title="No.{{ num }}">{{ num }}</a></span> + <span class="page"><a href="{{base_url}}page={{ num }}{{ extend_url }}" title="{% trans "page number " %}{{ num }}{% trans "number - make blank in english" %}">{{ num }}</a></span> {% endifequal %} {% endfor %} {% if not in_trailing_range %} ... {% for num in pages_outside_leading_range reversed %} - <span class="page"><a href="{{base_url}}page={{ num }}{{ extend_url }}" title="No.{{ num }}">{{ num }}</a></span> + <span class="page"><a href="{{base_url}}page={{ num }}{{ extend_url }}" title="{% trans "page number " %}{{ num }}{% trans "number - make blank in english" %}">{{ num }}</a></span> {% endfor %} {% endif %} -{% if has_next %}<span class="next"><a href="{{base_url}}page={{ next }}{{ extend_url }}" title="下一页">下一页 »</a></span>{% endif %} +{% if has_next %}<span class="next"><a href="{{base_url}}page={{ next }}{{ extend_url }}" title="{% trans "next page" %}">{% trans "next page" %} »</a></span>{% endif %} </div> {% endif %} {% endspaceless %} +<!-- end paginator.html --> diff --git a/templates/questions.html b/templates/questions.html index bfc1177c..a531d954 100644 --- a/templates/questions.html +++ b/templates/questions.html @@ -1,9 +1,11 @@ +<!-- questions.html --> {% extends "base.html" %} {% load i18n %} {% load extra_tags %} +{% load i18n %} {% load humanize %} {% load extra_filters %} -{% block title %}{% spaceless %}{% trans "Question list" %}{% endspaceless %}{% endblock %} +{% block title %}{% spaceless %}{% trans "Questions" %}{% endspaceless %}{% endblock %} {% block forejs %} <script type="text/javascript"> $().ready(function(){ @@ -19,12 +21,12 @@ {% endblock %} {% block content %} <div class="tabBar"> - <div class="headQuestions">{% if searchtag %}{% trans "Tagged questions" %}{% else %}{% if searchtitle %}{% trans "Query result" %}{% else %}{% trans "All questions" %}{% endif %}{% endif %}</div> + <div class="headQuestions">{% if searchtag %}{% trans "Found by tags" %}{% else %}{% if searchtitle %}{% trans "Found by title" %}{% else %}{% trans "All questions" %}{% endif %}{% endif %}</div> <div class="tabsA"> - <a id="latest" href="?sort=latest" class="off" title="{% trans 'New questions' %}">{% trans "Newest" %}</a> - <a id="active" href="?sort=active" class="off" title="{% trans 'Newest updated questions' %}">{% trans "Active" %}</a> - <a id="hottest" href="?sort=hottest" class="off" title="{% trans 'Questions with most answers' %}">{% trans "Hottest" %}</a> - <a id="mostvoted" href="?sort=mostvoted" class="off" title="{% trans 'Questions with most votes' %}">{% trans "Best" %}</a> + <a id="latest" href="?sort=latest" class="off" title="{% trans "most recently asked questions" %}">{% trans "newest" %}</a> + <a id="active" href="?sort=active" class="off" title="{% trans "most recently updated questions" %}">{% trans "active" %}</a> + <a id="hottest" href="?sort=hottest" class="off" title="{% trans "hottest questions" %}">{% trans "hottest" %}</a> + <a id="mostvoted" href="?sort=mostvoted" class="off" title="{% trans "most voted questions" %}">{% trans "most voted" %}</a> </div> </div> <div id="listA"> @@ -41,9 +43,9 @@ <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 "Visits" %}</span></td> + <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> @@ -54,7 +56,7 @@ {% ifequal tab_id 'active'%} {% if question.wiki %} - <span class="from wiki">{% trans "Community wiki" %}</span> + <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"> @@ -66,7 +68,7 @@ {% endif %} {% else %} {% if question.wiki %} - <span class="from wiki">{% trans "Community wiki" %}</span> + <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"> @@ -80,7 +82,7 @@ <div class="tags"> {% for tag in question.tagname_list %} - <a href="{% url forum.views.tag tag|urlencode %}" title="{% trans 'Browse questions with tag of '%}" rel="tag">{{ tag }}</a> + <a href="{% url forum.views.tag tag|urlencode %}" title="{% trans "see questions tagged" %}'{{ tag }}'{% trans "using tags" %}" rel="tag">{{ tag }}</a> {% endfor %} </div> </div> @@ -104,28 +106,46 @@ {% block sidebar %} <div class="boxC"> <p> - 您正在浏览所有<br><div class="questions-count">{{ questions_count|intcomma }}</div> - <p>个 - {% if searchtag %} - 标记为 - <span class="tag"> - {{ searchtag }} - </span> - {% endif %} - {% if searchtitle %} - 标题含有 - <strong class="darkred"> - {{ searchtitle }} - </strong> - {% endif %} - 的问题。</p> + {% if searchtag %} + {% blocktrans count questions_count as cnt with questions_count|intcomma as q_num and searchtag as tagname %} + have total {{q_num}} questions tagged {{tagname}} + {% plural %} + have total {{q_num}} questions tagged {{tagname}} + {% endblocktrans %} + {% endif %} + {% if searchtitle %} + {% blocktrans count questions_count as cnt with questions_count|intcomma as q_num %} + have total {{q_num}} questions containing {{searchtitle}} + {% plural %} + have total {{q_num}} questions containing {{searchtitle}} + {% endblocktrans %} + {% endif %} + + {% ifequal tab_id "latest" %} + <p>{% trans "latest questions info" %}</p> + {% endifequal %} + + {% ifequal tab_id "active" %} + <p>{% trans "Questions are sorted by the <strong>time of last update</strong>." %} + {% trans "Most recently answered ones are shown first." %}</p> + {% endifequal %} + + {% ifequal tab_id "hottest" %} + <p>{% trans "Questions sorted by <strong>number of responses</strong>." %} + {% trans "Most answered questions are shown first." %}</p> + {% endifequal %} + + {% ifequal tab_id "mostvoted" %} + <p>{% trans "Questions are sorted by the <strong>number of votes</strong>." %} + {% trans "Most voted questions are shown first." %}</p> + {% endifequal %} </p> </div> <div class="boxC"> <h3 class="subtitle">{% trans "Related tags" %}</h3> <div class="tags"> {% for tag in tags %} - <a rel="tag" href="{% url forum.views.tag tag.name|urlencode %}">{{ tag.name }}</a> + <a rel="tag" title="{% blocktrans with tag.name as tagname %}see questions tagged '{{ tagname }}'{% endblocktrans %}" href="{% url forum.views.tag tag.name|urlencode %}">{{ tag.name }}</a> <span class="tag-number">× {{ tag.used_count|intcomma }}</span> <br> {% endfor %} @@ -134,4 +154,4 @@ </div> {% endblock %} - +<!-- end questions.html --> diff --git a/templates/tags.html b/templates/tags.html index 6131e527..cb499eed 100644 --- a/templates/tags.html +++ b/templates/tags.html @@ -1,3 +1,4 @@ +<!-- tags.html --> {% extends "base_content.html" %} {% load i18n %} {% load extra_tags %} diff --git a/templates/template.list b/templates/template.list new file mode 100644 index 00000000..d4d4ec2d --- /dev/null +++ b/templates/template.list @@ -0,0 +1,18 @@ +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 --git a/templates/tough/faq.html b/templates/tough/faq.html new file mode 100644 index 00000000..9b43a9ca --- /dev/null +++ b/templates/tough/faq.html @@ -0,0 +1,110 @@ +{% 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 --git a/templates/tough/question_retag.html b/templates/tough/question_retag.html new file mode 100644 index 00000000..105428f4 --- /dev/null +++ b/templates/tough/question_retag.html @@ -0,0 +1,107 @@ +{% 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 --git a/templates/tough/unanswered.html b/templates/tough/unanswered.html new file mode 100644 index 00000000..94e778db --- /dev/null +++ b/templates/tough/unanswered.html @@ -0,0 +1,115 @@ +{% 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 --git a/templates/upfiles/1245715031297631.png b/templates/upfiles/1245715031297631.png Binary files differnew file mode 100755 index 00000000..89a6aed4 --- /dev/null +++ b/templates/upfiles/1245715031297631.png diff --git a/templates/upfiles/12457157052552259.png b/templates/upfiles/12457157052552259.png Binary files differnew file mode 100755 index 00000000..89a6aed4 --- /dev/null +++ b/templates/upfiles/12457157052552259.png diff --git a/templates/users.html b/templates/users.html index c3c9f790..701dbaa2 100644 --- a/templates/users.html +++ b/templates/users.html @@ -1,3 +1,4 @@ +<!-- users.html --> {% extends "base_content.html" %} {% load extra_tags %} {% load humanize %} |