Exemple #1
0
def index(request, page=1):
    #
    # sort: newest, answer, level, recommend, (unanswerd)
    #
    sort = request.GET.get("sort", "newest")

    #
    # sort_order: fw, rw(reverse order)
    #
    sort_order = request.GET.get("sort_order", "fw")

    #
    # save session for listings
    #
    request.session["page"] = page
    request.session["sort"] = sort
    request.session["sort_order"] = sort_order

    has_message = _has_message(request)

    #
    # if has_message, don't return cached page
    #
    if not has_message:
        cache = cache_get(request, "list.%s.%s.%s" % (sort, sort_order, page))
        if cache:
            return HttpResponse(cache)

    questions = Question.objects.filter(category='Q')

    if sort == "newest":
        if sort_order == "fw":
            order_by = "-register_time"
        else:
            order_by = "register_time"
        questions = questions.order_by(order_by)

    elif sort == "unanswered":
        questions = questions.filter(answers=None).order_by("-modify_time")

    elif sort == "answer":
        questions = questions.annotate(num_answers=Count('answers'))
        if sort_order == "fw":
            questions = questions.order_by('-num_answers', '-modify_time')
        else:
            questions = questions.order_by('num_answers', '-modify_time')

    elif sort == "recommend":
        if sort_order == "fw":
            order_by = True
        else:
            order_by = False
        questions = sorted(questions, key=Question.vote_count, reverse=order_by)

    elif sort == "level":
        if sort_order == "fw":
            order_by = False
        else:
            order_by = True
        questions = sorted(questions, key=Question.getLevel, reverse=order_by)

    else:
        sort = "newest"

    if sort in ["recommend", "level"]:  # sorted list
        total_count = len(questions)
    else:
        total_count = questions.count()

    #
    # pagination of questions
    #
    paginator = Paginator(questions, PER_PAGE)
    try:
        questions = paginator.page(page)
    except PageNotAnInteger:
        questions = paginator.page(1)
    except EmptyPage:
        questions = paginator.page(paginator.num_pages)


    # total answer count
    total_answer_count = Answer.objects.count()

    c = {
        "questions": questions,
        "total_count": total_count,
        "total_answer_count": total_answer_count,
        "per_page": PER_PAGE,
        "sort": sort,
        "sort_order": sort_order,
    }
    update_context(request, c)
    response = my_render(request, 'scode/scode_list.html', c)
    if not has_message:
        #
        # save response to cache
        #
        cache_put(request, "list.%s.%s.%s" % (sort, sort_order, page), response.content)
    return response
Exemple #2
0
def rank(request):
    cache = cache_get(request, "rank")
    if cache: return HttpResponse(cache)

    #
    # rank[profile] = [0,0,0,0,0]
    # 0 - score
    # 1 - question count
    # 2 - answer count
    # 3 - recv recommend count
    # 4 - make recommend count
    # 5 - vote level
    #
    rank = {}
    for q in Question.objects.filter(category='Q'):
        if q.profile not in rank:
            rank[q.profile] = [0,0,0,0,0,0]

        rank[q.profile][0] += 2
        rank[q.profile][1] += 1 # question count ++

        for p in q.recommender.all():
            rank[q.profile][0] += p.belt * 5
            rank[q.profile][3] += 1 # recv recommend count++
            if p not in rank:
                rank[p] = [0,0,0,0,0,0]
            rank[p][0] += 1
            rank[p][4] += 1 # make recommend count ++

        for a in q.answers.all():
            level = int(q.getLevel())
            if a.profile not in rank:
                rank[a.profile] = [0,0,0,0,0,0]

            rank[a.profile][0] += level * 5
            rank[a.profile][2] += 1 # answer count ++

            for p in a.recommender.all():
                rank[a.profile][0] += p.belt * 5
                rank[a.profile][3] += 1 # recv recommend count++
                if p not in rank:
                    rank[p] = [0,0,0,0,0,0]
                rank[p][0] += 1
                rank[p][4] += 1 # make recommend count ++

        for ql in q.level.all():
            if ql.profile not in rank:
                rank[ql.profile] = [0,0,0,0,0,0]
            rank[ql.profile][0] += 3
            rank[ql.profile][5] += 1 # vote count ++

    # exclude staff user from rank
    for step in Profile.objects.filter(user__is_staff=True):
        if step in rank: del rank[step]

    import operator

    sorted_rank = sorted(rank.iteritems(), key=operator.itemgetter(1), reverse=True)

    if len(sorted_rank) >= 100:
        last = sorted_rank[99]
    else:
        if sorted_rank:
            last = sorted_rank[-1]
        else:
            last = None

    sorted_rank = [s for s in sorted_rank if s[1] >= last[1]]
    scores = []
    for profile, score in sorted_rank:
        #logger.debug(score)
        scores.append(score)

    rank_order = get_rank_order(scores)
    c = {"rank": zip(sorted_rank, rank_order)}
    update_context(request, c)
    response = my_render(request, 'scode/scode_rank.html', c)
    cache_put(request, "rank", response.content)
    return response
Exemple #3
0
def view(request, q_id):
    #
    # 페이지 내 정렬 : 추천순, 최신순
    #
    orderby = request.GET.get("orderby", "")

    answer_id = request.GET.get("answer", "")
    has_page = request.POST.get("page", "")
    has_message = _has_message(request)

    #
    # 캐시하지 않는 경우:
    # ----------------------------------------
    # 1. 오류메시지 또는 성공메시지가 있는 경우
    # 2. 답변 정렬이 있는 경우
    # 3. 특정 답변으로 이동요청
    # 4. 답변 페이징이 있는 경우
    #
    if not has_message and not orderby and not answer_id and not has_page:
        cache = cache_get(request, q_id)
        if cache:
            return HttpResponse(cache)

    try:
        question = Question.objects.get(id=q_id)
    except Question.DoesNotExist:
        request.session["error_message"] = u"해당 글을 찾을 수 없습니다."
        return redirect('/')

    #
    # similar_questions: 동일한 태그를 가지고 있는 질문들
    #
    similar_questions = Question.objects.filter(tags__in=question.tags.all(), category='Q').distinct()

    #
    # 페이지 우측에 태그별 갯수를 표시하기 위해서 필요
    #
    tags = []
    tmp = similar_questions.values('tags') \
        .annotate(num_tags=Count('tags')).order_by('-num_tags')
    for t in tmp:
        if t['tags']:
            tag = Tag.objects.get(id=t['tags'])
            tag.count = t['num_tags']
            tags.append(tag)

    if orderby == "time":
        answers = question.answers.all().order_by("-register_time")
    else:
        answers = question.answers.all().annotate(
            recommend_count=Count('recommender')).order_by("-recommend_count", "register_time")


    #
    # answer_id 기 요청된 경우
    # 해당 답변이 있는 페이지를 보여주어야 한다.
    #
    answer_page = 0
    if answer_id:
        index = 0
        for i, _answer in enumerate(answers):
            if _answer.id == int(answer_id):
                index = i
                break
        answer_page = index / PER_PAGE + 1

    #
    # get total_page
    #
    total_count = answers.count()
    page_t = divmod(total_count, PER_PAGE)
    total_page = page_t[0]
    if page_t[1]: total_page += 1

    paginator = Paginator(answers, PER_PAGE)
    try:
        page = int(request.POST.get("page", "1"))

        #
        # 특정 답변이 요청된 경우 그 답변이 있는 페이지를 보여준다.
        #
        if answer_page:
            page = answer_page

        answers = paginator.page(page)
    except PageNotAnInteger:
        answers = paginator.page(1)
    except EmptyPage:
        answers = paginator.page(paginator.num_pages)

    level = question.getLevel()
    level_label = get_level_label(level)

    c = {"question": question,
         "similar_questions": similar_questions,
         "level": level,
         "level_label": level_label,
         "tags": tags,
         "answers": answers,
         "orderby": orderby,
         "total_page": total_page,
         "per_page": PER_PAGE}

    update_context(request, c)
    response = my_render(request, 'scode/scode_view.html', c)
    response["X-XSS-Protection"] = "0"

    #
    # 위 캐시하지 않는 경우를 제외하고 캐시한다.
    #
    if not has_message and not orderby and not answer_id and not has_page:
        cache_put(request, q_id, response.content)
    return response