Exemplo n.º 1
0
def _thread_list(request, mlist, threads, template_name='hyperkitty/thread_list.html', extra_context=None):
    categories = [ (c.name, c.name.upper())
                   for c in ThreadCategory.objects.all() ] \
                 + [("", "no category")]
    threads = paginate(threads, request.GET.get('page'))
    for thread in threads:
        # Favorites
        thread.favorite = False
        if request.user.is_authenticated():
            try:
                Favorite.objects.get(thread=thread, user=request.user)
            except Favorite.DoesNotExist:
                pass
            else:
                thread.favorite = True
        # Category
        thread.category_hk, thread.category_form = \
            get_category_widget(request, thread.category, categories)

    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)

    context = {
        'mlist' : mlist,
        'threads': threads,
        'months_list': get_months(mlist),
        'flash_messages': flash_messages,
    }
    if extra_context is not None:
        context.update(extra_context)
    return render(request, template_name, context)
Exemplo n.º 2
0
def set_category(request, mlist_fqdn, threadid):
    """ Set the category for 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

    store = get_store(request)
    category, category_form = get_category_widget(request)
    thread = store.get_thread(mlist_fqdn, threadid)
    if not category and thread.category:
        thread.category = None
        store.commit()
    elif category and category.name != thread.category:
        thread.category = category.name
        store.commit()

    # Now refresh the category widget
    FakeMList = namedtuple("MailingList", ["name"])
    context = {
        "category_form": category_form,
        "mlist": FakeMList(name=mlist_fqdn),
        "threadid": threadid,
        "category": category,
    }
    return render(request, "threads/category.html", context)
Exemplo n.º 3
0
def _thread_list(request, mlist, threads, template_name='hyperkitty/thread_list.html', extra_context=None):
    threads = paginate(threads, request.GET.get('page'),
                       results_per_page=request.GET.get('count'))
    for thread in threads:
        # Favorites
        thread.favorite = False
        if request.user.is_authenticated():
            try:
                Favorite.objects.get(thread=thread, user=request.user)
            except Favorite.DoesNotExist:
                pass
            else:
                thread.favorite = True
        # Category
        thread.category_hk, thread.category_form = \
            get_category_widget(request, thread.category)

    context = {
        'mlist' : mlist,
        'threads': threads,
        'months_list': get_months(mlist),
    }
    if extra_context is not None:
        context.update(extra_context)
    return render(request, template_name, context)
Exemplo n.º 4
0
def set_category(request, mlist_fqdn, threadid):
    """ Set the category for 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

    thread = get_object_or_404(Thread,
                               mailinglist__name=mlist_fqdn,
                               thread_id=threadid)
    category, category_form = get_category_widget(request)
    if not category and thread.category:
        thread.category = None
        thread.save()
    elif category and category.name != thread.category:
        thread.category = category
        thread.save()

    # Now refresh the category widget
    context = {
        "category_form": category_form,
        "thread": thread,
        "category": category,
    }
    return render(request, "hyperkitty/threads/category.html", context)
Exemplo n.º 5
0
def set_category(request, mlist_fqdn, threadid):
    """ Set the category for 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

    store = get_store(request)
    category, category_form = get_category_widget(request)
    thread = store.get_thread(mlist_fqdn, threadid)
    if not category and thread.category:
        thread.category = None
        store.commit()
    elif category and category.name != thread.category:
        thread.category = category.name
        store.commit()

    # Now refresh the category widget
    FakeMList = namedtuple("MailingList", ["name"])
    context = {
            "category_form": category_form,
            "mlist": FakeMList(name=mlist_fqdn),
            "threadid": threadid,
            "category": category,
            }
    return render(request, "threads/category.html", context)
Exemplo n.º 6
0
def set_category(request, mlist_fqdn, threadid):
    """ Set the category for 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

    thread = get_object_or_404(Thread,
        mailinglist__name=mlist_fqdn, thread_id=threadid)
    category, category_form = get_category_widget(request)
    if not category and thread.category:
        thread.category = None
        thread.save()
    elif category and category.name != thread.category:
        thread.category = category
        thread.save()

    # Now refresh the category widget
    context = {
            "category_form": category_form,
            "thread": thread,
            "category": category,
            }
    return render(request, "hyperkitty/threads/category.html", context)
Exemplo n.º 7
0
def _thread_list(request,
                 mlist,
                 threads,
                 template_name='hyperkitty/thread_list.html',
                 extra_context=None):
    threads = paginate(threads, request.GET.get('page'),
                       request.GET.get('count'))
    for thread in threads:
        # Favorites
        thread.favorite = False
        if request.user.is_authenticated:
            try:
                Favorite.objects.get(thread=thread, user=request.user)
            except Favorite.DoesNotExist:
                pass
            else:
                thread.favorite = True
        # Category
        thread.category_hk, thread.category_form = \
            get_category_widget(request, thread.category)

    context = {
        'mlist': mlist,
        'threads': threads,
        'months_list': get_months(mlist),
    }
    if extra_context is not None:
        context.update(extra_context)
    return render(request, template_name, context)
Exemplo n.º 8
0
def _thread_list(request, mlist, threads, template_name='thread_list.html', extra_context={}):
    if mlist is None:
        raise Http404("No archived mailing-list by that name.")
    store = get_store(request)

    threads = paginate(threads, request.GET.get('page'))

    participants = set()
    for thread in threads:
        if "participants" not in extra_context:
            participants.update(thread.participants)

        # Votes
        set_thread_votes(thread)

        # Favorites
        thread.favorite = False
        if request.user.is_authenticated():
            try:
                Favorite.objects.get(list_address=mlist.name,
                                     threadid=thread.thread_id,
                                     user=request.user)
            except Favorite.DoesNotExist:
                pass
            else:
                thread.favorite = True

        # Tags
        try:
            thread.tags = Tag.objects.filter(threadid=thread.thread_id,
                                             list_address=mlist.name)
        except Tag.DoesNotExist:
            thread.tags = []

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

        # Unread status
        thread.unread = is_thread_unread(request, mlist.name, thread)

    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)

    context = {
        'mlist' : mlist,
        'threads': threads,
        'participants': len(participants),
        'months_list': get_months(store, mlist.name),
        'flash_messages': flash_messages,
    }
    context.update(extra_context)
    return render(request, template_name, context)
Exemplo n.º 9
0
def _thread_list(request, mlist, threads, template_name='thread_list.html', extra_context={}):
    if mlist is None:
        raise Http404("No archived mailing-list by that name.")
    store = get_store(request)

    participants = set()
    for thread in threads:
        participants.update(thread.participants)

        # Votes
        set_thread_votes(thread, request.user)

        # Favorites
        thread.favorite = False
        if request.user.is_authenticated():
            try:
                Favorite.objects.get(list_address=mlist.name,
                                     threadid=thread.thread_id,
                                     user=request.user)
            except Favorite.DoesNotExist:
                pass
            else:
                thread.favorite = True

        # Tags
        try:
            thread.tags = Tag.objects.filter(threadid=thread.thread_id,
                                             list_address=mlist.name)
        except Tag.DoesNotExist:
            thread.tags = []

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

        # Unread status
        thread.unread = is_thread_unread(request, mlist.name, thread)

    threads = paginate(threads, request.GET.get('page'))

    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)

    context = {
        'mlist' : mlist,
        'threads': threads,
        'participants': len(participants),
        'months_list': get_months(store, mlist.name),
        'flash_messages': flash_messages,
    }
    context.update(extra_context)
    return render(request, template_name, context)
Exemplo n.º 10
0
def _thread_list(request,
                 mlist,
                 threads,
                 template_name='hyperkitty/thread_list.html',
                 extra_context=None):
    categories = [ (c.name, c.name.upper())
                   for c in ThreadCategory.objects.all() ] \
                 + [("", "no category")]
    threads = paginate(threads,
                       request.GET.get('page'),
                       results_per_page=request.GET.get('count'))
    for thread in threads:
        # Favorites
        thread.favorite = False
        if request.user.is_authenticated():
            try:
                Favorite.objects.get(thread=thread, user=request.user)
            except Favorite.DoesNotExist:
                pass
            else:
                thread.favorite = True
        # Category
        thread.category_hk, thread.category_form = \
            get_category_widget(request, thread.category, categories)

    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)

    context = {
        'mlist': mlist,
        'threads': threads,
        'months_list': get_months(mlist),
        'flash_messages': flash_messages,
        'per_page_options': [10, 50, 100, 200],
    }
    if extra_context is not None:
        context.update(extra_context)
    return render(request, template_name, context)
Exemplo n.º 11
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
    category, category_form = get_category_widget(request, thread.category)

    # 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()

    # 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

    # Export button
    export = {
        "url": "%s?thread=%s" % (
            reverse("hk_list_export_mbox", kwargs={
                    "mlist_fqdn": mlist.name,
                    "filename": "%s-%s" % (mlist.name, thread.thread_id)}),
            thread.thread_id),
        "message": _("Download"),
        "title": _("This thread in gzipped mbox format"),
    }

    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': get_posting_form(ReplyForm, request, mlist),
        'is_bot': is_bot,
        'num_comments': thread.emails_count - 1,
        'last_view': last_view,
        'unread_count': unread_count,
        'category_form': category_form,
        'category': category,
        'export': export,
    }

    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)
Exemplo n.º 12
0
def overview(request, mlist_fqdn=None):
    if not mlist_fqdn:
        return redirect('/')

    # Get stats for last 30 days
    today = datetime.datetime.utcnow()
    #today -= datetime.timedelta(days=365) #debug
    # the upper boundary is excluded in the search, add one day
    end_date = today + datetime.timedelta(days=1)
    begin_date = end_date - datetime.timedelta(days=32)

    store = get_store(request)
    mlist = store.get_list(mlist_fqdn)
    if mlist is None:
        raise Http404("No archived mailing-list by that name.")
    threads_result = store.get_threads(
            list_name=mlist.name, start=begin_date, end=end_date)

    threads = []
    participants = set()
    for thread_obj in threads_result:
        # Votes
        set_thread_votes(thread_obj, request.user)
        thread = Thread(thread_obj.thread_id, thread_obj.subject,
                        thread_obj.participants, len(thread_obj),
                        thread_obj.date_active.replace(tzinfo=utc),
                        thread_obj.likes, thread_obj.dislikes,
                        thread_obj.likestatus,
                        get_category_widget(None, thread_obj.category)[0],
                        is_thread_unread(request, mlist.name, thread_obj),
                        )
        # Statistics on how many participants and threads this month
        participants.update(thread.participants)
        threads.append(thread)

    # top threads are the one with the most answers
    top_threads = sorted(threads, key=lambda t: t.length, reverse=True)

    # active threads are the ones that have the most recent posting
    active_threads = sorted(threads, key=lambda t: t.date_active, reverse=True)

    # top authors are the ones that have the most kudos.  How do we determine
    # that?  Most likes for their post?
    if settings.USE_MOCKUPS:
        authors = generate_top_author()
        authors = sorted(authors, key=lambda author: author.kudos)
        authors.reverse()
    else:
        authors = []

    # Top posters
    top_posters = []
    for poster in store.get_top_participants(list_name=mlist.name,
                start=begin_date, end=end_date, limit=5):
        top_posters.append({"name": poster[0], "email": poster[1],
                            "count": poster[2]})

    # Popular threads
    pop_threads = sorted([ t for t in threads if t.likes - t.dislikes > 0 ],
                         key=lambda t: t.likes - t.dislikes,
                         reverse=True)

    # Threads by category
    threads_by_category = {}
    for thread in active_threads:
        if not thread.category:
            continue
        # don't use defaultdict, use .setdefault():
        # http://stackoverflow.com/questions/4764110/django-template-cant-loop-defaultdict
        if len(threads_by_category.setdefault(thread.category, [])) >= 5:
            continue
        threads_by_category[thread.category].append(thread)

    # List activity
    # Use get_messages and not get_threads to count the emails, because
    # recently active threads include messages from before the start date
    emails_in_month = store.get_messages(list_name=mlist.name,
                                         start=begin_date, end=end_date)
    # graph
    dates = defaultdict(lambda: 0) # no activity by default
    # populate with all days before adding data.
    for single_date in daterange(begin_date, end_date):
        dates[single_date.strftime("%Y-%m-%d")] = 0

    for email in emails_in_month:
        date_str = email.date.strftime("%Y-%m-%d")
        dates[date_str] = dates[date_str] + 1
    days = dates.keys()
    days.sort()
    evolution = [dates[d] for d in days]
    if not evolution:
        evolution.append(0)
    archives_baseurl = reverse("archives_latest",
                               kwargs={'mlist_fqdn': mlist.name})
    archives_baseurl = archives_baseurl.rpartition("/")[0]

    context = {
        'view_name': 'overview',
        'mlist' : mlist,
        'top_threads': top_threads[:5],
        'most_active_threads': active_threads[:5],
        'top_author': authors,
        'top_posters': top_posters,
        'pop_threads': pop_threads[:5],
        'threads_by_category': threads_by_category,
        'months_list': get_months(store, mlist.name),
        'evolution': evolution,
        'days': days,
        'archives_baseurl': archives_baseurl,
        'num_threads': len(threads),
        'num_participants': len(participants),
    }
    return render(request, "overview.html", context)
Exemplo n.º 13
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)
Exemplo n.º 14
0
def overview(request, mlist_fqdn=None):
    if not mlist_fqdn:
        return redirect('/')
    mlist = get_object_or_404(MailingList, name=mlist_fqdn)
    threads = []
    for thread_obj in mlist.recent_threads:
        thread_obj.category_widget = get_category_widget(
            None, thread_obj.category)[0]
        threads.append(thread_obj)

    # top threads are the one with the most answers
    top_threads = sorted(threads, key=lambda t: t.emails_count, reverse=True)

    # active threads are the ones that have the most recent posting
    active_threads = sorted(threads, key=lambda t: t.date_active, reverse=True)

    # top authors are the ones that have the most kudos.  How do we determine
    # that?  Most likes for their post?
    if settings.USE_MOCKUPS:
        authors = generate_top_author()
        authors = sorted(authors, key=lambda author: author.kudos)
        authors.reverse()
    else:
        authors = []

    # Popular threads
    pop_threads = []
    for t in threads:
        votes = t.get_votes()
        if votes["likes"] - votes["dislikes"] > 0:
            pop_threads.append(t)

    def _get_thread_vote_result(t):
        votes = t.get_votes()
        return votes["likes"] - votes["dislikes"]

    pop_threads.sort(key=_get_thread_vote_result, reverse=True)

    # Threads by category
    threads_by_category = {}
    for thread in active_threads:
        if not thread.category:
            continue
        # don't use defaultdict, use .setdefault():
        # http://stackoverflow.com/questions/4764110/django-template-cant-loop-defaultdict
        if len(threads_by_category.setdefault(thread.category, [])) >= 5:
            continue
        threads_by_category[thread.category].append(thread)

    # Personalized discussion groups: flagged/favorited threads and threads by user
    if request.user.is_authenticated():
        favorites = [
            f.thread
            for f in Favorite.objects.filter(thread__mailinglist=mlist,
                                             user=request.user)
        ]
        mm_user_id = request.user.hyperkitty_profile.get_mailman_user_id()
        threads_posted_to = []
        if mm_user_id is not None:
            for thread in threads:
                senders = set(
                    [e.sender.mailman_id for e in thread.emails.all()])
                if mm_user_id in senders:
                    threads_posted_to.append(thread)
    else:
        favorites = []
        threads_posted_to = []

    # Empty messages # TODO: translate this
    empty_messages = {
        "flagged": 'You have not flagged any discussions (yet).',
        "posted": 'You have not posted to this list (yet).',
        "active": 'No discussions this month (yet).',
        "popular": 'No vote has been cast this month (yet).',
    }

    context = {
        'view_name': 'overview',
        'mlist': mlist,
        'top_threads': top_threads[:20],
        'most_active_threads': active_threads[:20],
        'top_author': authors,
        'pop_threads': pop_threads[:20],
        'threads_by_category': threads_by_category,
        'months_list': get_months(mlist),
        'flagged_threads': favorites,
        'threads_posted_to': threads_posted_to,
        'empty_messages': empty_messages,
    }
    return render(request, "hyperkitty/overview.html", context)
Exemplo n.º 15
0
def overview(request, mlist_fqdn=None):
    if not mlist_fqdn:
        return redirect('/')

    store = get_store(request)
    mlist = store.get_list(mlist_fqdn)
    if mlist is None:
        raise Http404("No archived mailing-list by that name.")
    begin_date, end_date = mlist.get_recent_dates()
    threads_result = store.get_threads(
            list_name=mlist.name, start=begin_date, end=end_date)

    threads = []
    for thread_obj in threads_result:
        # Votes
        set_thread_votes(thread_obj)
        thread_obj.category_widget = get_category_widget(
                None, thread_obj.category)[0]
        thread_obj.unread = is_thread_unread(request, mlist.name, thread_obj)
        threads.append(thread_obj)

    # top threads are the one with the most answers
    top_threads = sorted(threads, key=lambda t: len(t), reverse=True)

    # active threads are the ones that have the most recent posting
    active_threads = sorted(threads, key=lambda t: t.date_active, reverse=True)

    # top authors are the ones that have the most kudos.  How do we determine
    # that?  Most likes for their post?
    if settings.USE_MOCKUPS:
        authors = generate_top_author()
        authors = sorted(authors, key=lambda author: author.kudos)
        authors.reverse()
    else:
        authors = []

    # Top posters
    top_posters = []
    for poster in store.get_top_participants(list_name=mlist.name,
                start=begin_date, end=end_date, limit=5):
        top_posters.append({"name": poster[0], "email": poster[1],
                            "count": poster[2]})

    # Popular threads
    pop_threads = sorted([ t for t in threads if t.likes - t.dislikes > 0 ],
                         key=lambda t: t.likes - t.dislikes,
                         reverse=True)

    # Threads by category
    threads_by_category = {}
    for thread in active_threads:
        if not thread.category:
            continue
        # don't use defaultdict, use .setdefault():
        # http://stackoverflow.com/questions/4764110/django-template-cant-loop-defaultdict
        if len(threads_by_category.setdefault(thread.category, [])) >= 5:
            continue
        threads_by_category[thread.category].append(thread)

    context = {
        'view_name': 'overview',
        'mlist' : mlist,
        'top_threads': top_threads[:5],
        'most_active_threads': active_threads[:5],
        'top_author': authors,
        'top_posters': top_posters,
        'pop_threads': pop_threads[:5],
        'threads_by_category': threads_by_category,
        'months_list': get_months(store, mlist.name),
    }
    return render(request, "overview.html", context)
Exemplo n.º 16
0
def thread_index(request, mlist_fqdn, threadid, month=None, year=None):
    ''' Displays all the email for a given thread identifier '''
    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
    category, category_form = get_category_widget(request, thread.category)

    # 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()

    # 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

    # Export button
    export = {
        "url":
        "%s?thread=%s" %
        (reverse("hk_list_export_mbox",
                 kwargs={
                     "mlist_fqdn": mlist.name,
                     "filename": "%s-%s" % (mlist.name, thread.thread_id)
                 }), thread.thread_id),
        "message":
        _("Download"),
        "title":
        _("This thread in gzipped mbox format"),
    }

    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': get_posting_form(ReplyForm, request, mlist),
        'is_bot': is_bot,
        'num_comments': thread.emails_count - 1,
        'last_view': last_view,
        'unread_count': unread_count,
        'category_form': category_form,
        'category': category,
        'export': export,
    }

    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)
Exemplo n.º 17
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)
Exemplo n.º 18
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)
Exemplo n.º 19
0
def overview(request, mlist_fqdn=None):
    if not mlist_fqdn:
        return redirect('/')
    mlist = get_object_or_404(MailingList, name=mlist_fqdn)
    threads = []
    for thread_obj in mlist.recent_threads:
        thread_obj.category_widget = get_category_widget(
                None, thread_obj.category)[0]
        threads.append(thread_obj)

    # top threads are the one with the most answers
    top_threads = sorted(threads, key=lambda t: t.emails_count, reverse=True)

    # active threads are the ones that have the most recent posting
    active_threads = sorted(threads, key=lambda t: t.date_active, reverse=True)

    # top authors are the ones that have the most kudos.  How do we determine
    # that?  Most likes for their post?
    if settings.USE_MOCKUPS:
        authors = generate_top_author()
        authors = sorted(authors, key=lambda author: author.kudos)
        authors.reverse()
    else:
        authors = []

    # Popular threads
    pop_threads = []
    for t in threads:
        votes = t.get_votes()
        if votes["likes"] - votes["dislikes"] > 0:
            pop_threads.append(t)
    def _get_thread_vote_result(t):
        votes = t.get_votes()
        return votes["likes"] - votes["dislikes"]
    pop_threads.sort(key=_get_thread_vote_result, reverse=True)

    # Threads by category
    threads_by_category = {}
    for thread in active_threads:
        if not thread.category:
            continue
        # don't use defaultdict, use .setdefault():
        # http://stackoverflow.com/questions/4764110/django-template-cant-loop-defaultdict
        if len(threads_by_category.setdefault(thread.category, [])) >= 5:
            continue
        threads_by_category[thread.category].append(thread)

    # Personalized discussion groups: flagged/favorited threads and threads by user
    if request.user.is_authenticated():
        favorites = [ f.thread for f in Favorite.objects.filter(
            thread__mailinglist=mlist, user=request.user) ]
        mm_user_id = request.user.hyperkitty_profile.get_mailman_user_id()
        threads_posted_to = []
        if mm_user_id is not None:
            for thread in threads:
                senders = set([e.sender.mailman_id for e in thread.emails.all()])
                if mm_user_id in senders:
                    threads_posted_to.append(thread)
    else:
        favorites = []
        threads_posted_to = []

    # Empty messages # TODO: translate this
    empty_messages = {
        "flagged": 'You have not flagged any discussions (yet).',
        "posted": 'You have not posted to this list (yet).',
        "active": 'No discussions this month (yet).',
        "popular": 'No vote has been cast this month (yet).',
    }

    context = {
        'view_name': 'overview',
        'mlist' : mlist,
        'top_threads': top_threads[:20],
        'most_active_threads': active_threads[:20],
        'top_author': authors,
        'pop_threads': pop_threads[:20],
        'threads_by_category': threads_by_category,
        'months_list': get_months(mlist),
        'flagged_threads': favorites,
        'threads_posted_to': threads_posted_to,
        'empty_messages': empty_messages,
    }
    return render(request, "hyperkitty/overview.html", context)
Exemplo n.º 20
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)
Exemplo n.º 21
0
def overview(request, mlist_fqdn=None):
    if not mlist_fqdn:
        return redirect('/')

    # Get stats for last 30 days
    today = datetime.datetime.utcnow()
    #today -= datetime.timedelta(days=365) #debug
    # the upper boundary is excluded in the search, add one day
    end_date = today + datetime.timedelta(days=1)
    begin_date = end_date - datetime.timedelta(days=32)

    store = get_store(request)
    mlist = store.get_list(mlist_fqdn)
    if mlist is None:
        raise Http404("No archived mailing-list by that name.")
    threads_result = store.get_threads(
            list_name=mlist.name, start=begin_date, end=end_date)

    threads = []
    participants = set()
    for thread_obj in threads_result:
        # Votes
        set_thread_votes(thread_obj, request.user)
        thread = Thread(thread_obj.thread_id, thread_obj.subject,
                        thread_obj.participants, len(thread_obj),
                        thread_obj.date_active.replace(tzinfo=utc),
                        thread_obj.likes, thread_obj.dislikes,
                        thread_obj.likestatus,
                        get_category_widget(None, thread_obj.category)[0],
                        is_thread_unread(request, mlist.name, thread_obj),
                        )
        # Statistics on how many participants and threads this month
        participants.update(thread.participants)
        threads.append(thread)

    # top threads are the one with the most answers
    top_threads = sorted(threads, key=lambda t: t.length, reverse=True)

    # active threads are the ones that have the most recent posting
    active_threads = sorted(threads, key=lambda t: t.date_active, reverse=True)

    # top authors are the ones that have the most kudos.  How do we determine
    # that?  Most likes for their post?
    if settings.USE_MOCKUPS:
        authors = generate_top_author()
        authors = sorted(authors, key=lambda author: author.kudos)
        authors.reverse()
    else:
        authors = []

    # Top posters
    top_posters = []
    for poster in store.get_top_participants(list_name=mlist.name,
                start=begin_date, end=end_date, limit=5):
        top_posters.append({"name": poster[0], "email": poster[1],
                            "count": poster[2]})

    # Popular threads
    pop_threads = sorted([ t for t in threads if t.likes - t.dislikes > 0 ],
                         key=lambda t: t.likes - t.dislikes,
                         reverse=True)

    # Threads by category
    threads_by_category = {}
    for thread in active_threads:
        if not thread.category:
            continue
        # don't use defaultdict, use .setdefault():
        # http://stackoverflow.com/questions/4764110/django-template-cant-loop-defaultdict
        if len(threads_by_category.setdefault(thread.category, [])) >= 5:
            continue
        threads_by_category[thread.category].append(thread)

    # List activity
    # Use get_messages and not get_threads to count the emails, because
    # recently active threads include messages from before the start date
    emails_in_month = store.get_messages(list_name=mlist.name,
                                         start=begin_date, end=end_date)
    # graph
    dates = defaultdict(lambda: 0) # no activity by default
    # populate with all days before adding data.
    for single_date in daterange(begin_date, end_date):
        dates[single_date.strftime("%Y-%m-%d")] = 0

    for email in emails_in_month:
        date_str = email.date.strftime("%Y-%m-%d")
        dates[date_str] = dates[date_str] + 1
    days = dates.keys()
    days.sort()
    evolution = [dates[d] for d in days]
    if not evolution:
        evolution.append(0)
    archives_baseurl = reverse("archives_latest",
                               kwargs={'mlist_fqdn': mlist.name})
    archives_baseurl = archives_baseurl.rpartition("/")[0]

    context = {
        'view_name': 'overview',
        'mlist' : mlist,
        'top_threads': top_threads[:5],
        'most_active_threads': active_threads[:5],
        'top_author': authors,
        'top_posters': top_posters,
        'pop_threads': pop_threads[:5],
        'threads_by_category': threads_by_category,
        'months_list': get_months(store, mlist.name),
        'evolution': evolution,
        'days': days,
        'archives_baseurl': archives_baseurl,
        'num_threads': len(threads),
        'num_participants': len(participants),
    }
    return render(request, "overview.html", context)
Exemplo n.º 22
0
def overview(request, mlist_fqdn=None):
    if not mlist_fqdn:
        return redirect('/')

    store = get_store(request)
    mlist = store.get_list(mlist_fqdn)
    if mlist is None:
        raise Http404("No archived mailing-list by that name.")
    begin_date, end_date = mlist.get_recent_dates()
    threads_result = store.get_threads(
            list_name=mlist.name, start=begin_date, end=end_date)

    threads = []
    for thread_obj in threads_result:
        thread_obj.category_widget = get_category_widget(
                None, thread_obj.category)[0]
        thread_obj.unread = is_thread_unread(request, mlist.name, thread_obj)
        threads.append(thread_obj)

    # top threads are the one with the most answers
    top_threads = sorted(threads, key=lambda t: len(t), reverse=True)

    # active threads are the ones that have the most recent posting
    active_threads = sorted(threads, key=lambda t: t.date_active, reverse=True)

    # top authors are the ones that have the most kudos.  How do we determine
    # that?  Most likes for their post?
    if settings.USE_MOCKUPS:
        authors = generate_top_author()
        authors = sorted(authors, key=lambda author: author.kudos)
        authors.reverse()
    else:
        authors = []

    # Top posters
    top_posters = []
    for poster in store.get_top_participants(list_name=mlist.name,
                start=begin_date, end=end_date, limit=5):
        top_posters.append({"name": poster[0], "email": poster[1],
                            "count": poster[2]})

    # Popular threads
    pop_threads = sorted([ t for t in threads if t.likes - t.dislikes > 0 ],
                         key=lambda t: t.likes - t.dislikes,
                         reverse=True)

    # Threads by category
    threads_by_category = {}
    for thread in active_threads:
        if not thread.category:
            continue
        # don't use defaultdict, use .setdefault():
        # http://stackoverflow.com/questions/4764110/django-template-cant-loop-defaultdict
        if len(threads_by_category.setdefault(thread.category, [])) >= 5:
            continue
        threads_by_category[thread.category].append(thread)

    context = {
        'view_name': 'overview',
        'mlist' : mlist,
        'top_threads': top_threads[:5],
        'most_active_threads': active_threads[:5],
        'top_author': authors,
        'top_posters': top_posters,
        'pop_threads': pop_threads[:5],
        'threads_by_category': threads_by_category,
        'months_list': get_months(store, mlist.name),
    }
    return render(request, "overview.html", context)