Esempio n. 1
0
def tags(request, mlist_fqdn, threadid):
    """ Add or remove a tag on a given thread. """
    if not request.user.is_authenticated():
        return HttpResponse('You must be logged in to add a tag',
                            content_type="text/plain",
                            status=403)

    if request.method != 'POST':
        raise SuspiciousOperation
    action = request.POST.get("action")

    if action == "add":
        form = AddTagForm(request.POST)
        if not form.is_valid():
            return HttpResponse("Error adding tag: invalid data",
                                content_type="text/plain",
                                status=500)
        tagname = form.data['tag']
    elif action == "rm":
        tagname = request.POST.get('tag')
    else:
        raise SuspiciousOperation
    try:
        tag = Tag.objects.get(threadid=threadid,
                              list_address=mlist_fqdn,
                              tag=tagname)
        if action == "rm":
            tag.delete()
    except Tag.DoesNotExist:
        if action == "add":
            tag = Tag(list_address=mlist_fqdn,
                      threadid=threadid,
                      tag=tagname,
                      user=request.user)
            tag.save()
        elif action == "rm":
            raise Http404("No such tag: %s" % tagname)

    # Now refresh the tag list
    tags = Tag.objects.filter(threadid=threadid, list_address=mlist_fqdn)
    FakeMList = namedtuple("MailingList", ["name"])
    tpl = loader.get_template('threads/tags.html')
    html = tpl.render(
        RequestContext(
            request, {
                "tags": tags,
                "mlist": FakeMList(name=mlist_fqdn),
                "threadid": threadid,
            }))

    response = {"tags": [t.tag for t in tags], "html": html}
    return HttpResponse(json.dumps(response),
                        mimetype='application/javascript')
Esempio n. 2
0
def tags(request, mlist_fqdn, threadid):
    """ Add or remove one or more tags on a given thread. """
    if not request.user.is_authenticated():
        return HttpResponse('You must be logged in to add a tag',
                            content_type="text/plain",
                            status=403)
    thread = get_object_or_404(Thread,
                               mailinglist__name=mlist_fqdn,
                               thread_id=threadid)

    if request.method != 'POST':
        raise SuspiciousOperation
    action = request.POST.get("action")

    if action == "add":
        form = AddTagForm(request.POST)
        if not form.is_valid():
            return HttpResponse("Error adding tag: invalid data",
                                content_type="text/plain",
                                status=500)
        tagname = form.data['tag']
    elif action == "rm":
        tagname = request.POST.get('tag')
    else:
        raise SuspiciousOperation
    tagnames = [t.strip() for t in re.findall(r"[\w'_ -]+", tagname)]
    for tagname in tagnames:
        if action == "add":
            tag = Tag.objects.get_or_create(name=tagname)[0]
            Tagging.objects.get_or_create(tag=tag,
                                          thread=thread,
                                          user=request.user)
        elif action == "rm":
            try:
                Tagging.objects.get(tag__name=tagname,
                                    thread=thread,
                                    user=request.user).delete()
            except Tagging.DoesNotExist:
                raise Http404("No such tag: %s" % tagname)
            # cleanup
            if not Tagging.objects.filter(tag__name=tagname).exists():
                Tag.objects.filter(name=tagname).delete()

    # Now refresh the tag list
    tpl = loader.get_template('hyperkitty/threads/tags.html')
    html = tpl.render(RequestContext(request, {
        "thread": thread,
    }))

    response = {"tags": [t.name for t in thread.tags.distinct()], "html": html}
    return HttpResponse(json.dumps(response),
                        content_type='application/javascript')
Esempio n. 3
0
def tags(request, mlist_fqdn, threadid):
    """ Add or remove one or more tags on a given thread. """
    if not request.user.is_authenticated():
        return HttpResponse('You must be logged in to add a tag',
                            content_type="text/plain", status=403)

    if request.method != 'POST':
        raise SuspiciousOperation
    action = request.POST.get("action")

    if action == "add":
        form = AddTagForm(request.POST)
        if not form.is_valid():
            return HttpResponse("Error adding tag: invalid data",
                                content_type="text/plain", status=500)
        tagname = form.data['tag']
    elif action == "rm":
        tagname = request.POST.get('tag')
    else:
        raise SuspiciousOperation
    tagnames = [ t.strip() for t in re.findall(r"[\w'_ -]+", tagname) ]
    for tagname in tagnames:
        try:
            tag = Tag.objects.get(threadid=threadid, list_address=mlist_fqdn,
                                  tag=tagname)
        except Tag.DoesNotExist:
            if action == "add":
                tag = Tag(list_address=mlist_fqdn, threadid=threadid,
                          tag=tagname, user=request.user)
                tag.save()
            elif action == "rm":
                raise Http404("No such tag: %s" % tagname)
        else:
            if action == "rm":
                tag.delete()

    # Now refresh the tag list
    tags = Tag.objects.filter(threadid=threadid, list_address=mlist_fqdn)
    FakeMList = namedtuple("MailingList", ["name"])
    tpl = loader.get_template('threads/tags.html')
    html = tpl.render(RequestContext(request, {
            "tags": tags,
            "mlist": FakeMList(name=mlist_fqdn),
            "threadid": threadid,
            }))

    response = {"tags": [ t.tag for t in tags ], "html": html}
    return HttpResponse(json.dumps(response),
                        content_type='application/javascript')
Esempio n. 4
0
def tags(request, mlist_fqdn, threadid):
    """ Add or remove one or more tags on a given thread. """
    if not request.user.is_authenticated():
        return HttpResponse('You must be logged in to add a tag',
                            content_type="text/plain", status=403)
    thread = get_object_or_404(Thread,
        mailinglist__name=mlist_fqdn, thread_id=threadid)

    if request.method != 'POST':
        raise SuspiciousOperation
    action = request.POST.get("action")

    if action == "add":
        form = AddTagForm(request.POST)
        if not form.is_valid():
            return HttpResponse("Error adding tag: invalid data",
                                content_type="text/plain", status=500)
        tagname = form.data['tag']
    elif action == "rm":
        tagname = request.POST.get('tag')
    else:
        raise SuspiciousOperation
    tagnames = [ t.strip() for t in re.findall(r"[\w'_ -]+", tagname) ]
    for tagname in tagnames:
        if action == "add":
            tag = Tag.objects.get_or_create(name=tagname)[0]
            Tagging.objects.get_or_create(
                tag=tag, thread=thread, user=request.user)
        elif action == "rm":
            try:
                Tagging.objects.get(tag__name=tagname, thread=thread,
                                    user=request.user).delete()
            except Tagging.DoesNotExist:
                raise Http404("No such tag: %s" % tagname)
            # cleanup
            if not Tagging.objects.filter(tag__name=tagname).exists():
                Tag.objects.filter(name=tagname).delete()

    # Now refresh the tag list
    tpl = loader.get_template('hyperkitty/threads/tags.html')
    html = tpl.render(RequestContext(request, {
            "thread": thread,
            }))

    response = {"tags": [ t.name for t in thread.tags.distinct() ],
                "html": html}
    return HttpResponse(json.dumps(response),
                        content_type='application/javascript')
Esempio n. 5
0
def thread_index(request, mlist_fqdn, threadid, month=None, year=None):
    ''' Displays all the email for a given thread identifier '''
    # pylint: disable=unused-argument
    mlist = get_object_or_404(MailingList, name=mlist_fqdn)
    thread = get_object_or_404(Thread, mailinglist=mlist, thread_id=threadid)
    starting_email = thread.starting_email

    sort_mode = request.GET.get("sort", "thread")
    if request.user.is_authenticated():
        starting_email.myvote = starting_email.votes.filter(
            user=request.user).first()
    else:
        starting_email.myvote = None

    # Tags
    tag_form = AddTagForm()

    # Favorites
    fav_action = "add"
    if request.user.is_authenticated() and Favorite.objects.filter(
            thread=thread, user=request.user).exists():
        fav_action = "rm"

    # Category
    categories = [ (c.name, c.name.upper())
                   for c in ThreadCategory.objects.all() ] \
                 + [("", "no category")]
    category, category_form = get_category_widget(request, thread.category,
                                                  categories)

    # Extract relative dates
    today = datetime.date.today()
    days_old = today - starting_email.date.date()
    days_inactive = today - thread.date_active.date()

    subject = stripped_subject(mlist, starting_email.subject)

    # Last view
    last_view = None
    if request.user.is_authenticated():
        last_view_obj, created = LastView.objects.get_or_create(
            thread=thread, user=request.user)
        if not created:
            last_view = last_view_obj.view_date
            last_view_obj.save()  # update timestamp
    # get the number of unread messages
    if last_view is None:
        if request.user.is_authenticated():
            unread_count = thread.emails_count
        else:
            unread_count = 0
    else:
        unread_count = thread.emails.filter(date__gt=last_view).count()

    # Flash messages
    flash_messages = []
    flash_msg = request.GET.get("msg")
    if flash_msg:
        flash_msg = {
            "type": FLASH_MESSAGES[flash_msg][0],
            "msg": FLASH_MESSAGES[flash_msg][1]
        }
        flash_messages.append(flash_msg)

    # TODO: eventually move to a middleware ?
    # http://djangosnippets.org/snippets/1865/
    user_agent = request.META.get('HTTP_USER_AGENT', None)
    if user_agent:
        is_bot = robot_detection.is_robot(user_agent)
    else:
        is_bot = True

    context = {
        'mlist': mlist,
        'thread': thread,
        'starting_email': starting_email,
        'subject': subject,
        'addtag_form': tag_form,
        'month': thread.date_active,
        'months_list': get_months(mlist),
        'days_inactive': days_inactive.days,
        'days_old': days_old.days,
        'sort_mode': sort_mode,
        'fav_action': fav_action,
        'reply_form': ReplyForm(),
        'is_bot': is_bot,
        'num_comments': thread.emails_count - 1,
        'last_view': last_view,
        'unread_count': unread_count,
        'category_form': category_form,
        'category': category,
        'flash_messages': flash_messages,
    }

    if is_bot:
        # Don't rely on AJAX to load the replies
        # The limit is a safety measure, don't let a bot kill the DB
        context["replies"] = _get_thread_replies(request, thread, limit=1000)

    return render(request, "hyperkitty/thread.html", context)
Esempio n. 6
0
def thread_index(request, mlist_fqdn, threadid, month=None, year=None):
    ''' Displays all the email for a given thread identifier '''
    store = get_store(request)
    thread = store.get_thread(mlist_fqdn, threadid)
    if not thread:
        raise Http404
    prev_thread, next_thread = store.get_thread_neighbors(mlist_fqdn, threadid)

    sort_mode = request.GET.get("sort", "thread")
    set_message_votes(thread.starting_email, request.user)

    # Tags
    tag_form = AddTagForm()
    try:
        tags = Tag.objects.filter(threadid=threadid, list_address=mlist_fqdn)
    except Tag.DoesNotExist:
        tags = []

    # Favorites
    fav_action = "add"
    if request.user.is_authenticated():
        try:
            Favorite.objects.get(list_address=mlist_fqdn,
                                 threadid=threadid,
                                 user=request.user)
        except Favorite.DoesNotExist:
            pass
        else:
            fav_action = "rm"

    # Category
    category, category_form = get_category_widget(request, thread.category)

    # Extract relative dates
    today = datetime.date.today()
    days_old = today - thread.starting_email.date.date()
    days_inactive = today - thread.last_email.date.date()

    mlist = store.get_list(mlist_fqdn)
    subject = stripped_subject(mlist, thread.starting_email.subject)

    # Last view
    last_view = None
    if request.user.is_authenticated():
        last_view_obj, created = LastView.objects.get_or_create(
            list_address=mlist_fqdn, threadid=threadid, user=request.user)
        if not created:
            last_view = last_view_obj.view_date
            last_view_obj.save()  # update timestamp
    # get the number of unread messages
    if last_view is None:
        if request.user.is_authenticated():
            unread_count = len(thread)
        else:
            unread_count = 0
    else:
        # XXX: Storm-specific
        unread_count = thread.replies_after(last_view).count()

    # Flash messages
    flash_messages = []
    flash_msg = request.GET.get("msg")
    if flash_msg:
        flash_msg = {
            "type": FLASH_MESSAGES[flash_msg][0],
            "msg": FLASH_MESSAGES[flash_msg][1]
        }
        flash_messages.append(flash_msg)

    # TODO: eventually move to a middleware ?
    # http://djangosnippets.org/snippets/1865/
    is_bot = True
    user_agent = request.META.get('HTTP_USER_AGENT', None)
    if user_agent:
        is_bot = robot_detection.is_robot(user_agent)

    context = {
        'mlist': mlist,
        'threadid': threadid,
        'subject': subject,
        'tags': tags,
        'addtag_form': tag_form,
        'month': thread.date_active,
        'first_mail': thread.starting_email,
        'neighbors': (prev_thread, next_thread),
        'months_list': get_months(store, mlist.name),
        'days_inactive': days_inactive.days,
        'days_old': days_old.days,
        'sort_mode': sort_mode,
        'fav_action': fav_action,
        'reply_form': ReplyForm(),
        'is_bot': is_bot,
        'num_comments': len(thread),
        'participants': thread.participants,
        'last_view': last_view,
        'unread_count': unread_count,
        'category_form': category_form,
        'category': category,
        'flash_messages': flash_messages,
    }
    context["participants"].sort(key=lambda x: x[0].lower())

    if is_bot:
        # Don't rely on AJAX to load the replies
        # The limit is a safety measure, don't let a bot kill the DB
        context["replies"] = _get_thread_replies(request, thread, limit=1000)

    return render(request, "thread.html", context)