def new_message(request, mlist_fqdn): """ Sends a new thread-starting message to the list. TODO: unit tests """ store = get_store(request) mlist = store.get_list(mlist_fqdn) if request.method == 'POST': form = PostForm(request.POST) if form.is_valid(): _send_email(request, mlist, form.cleaned_data['subject'], form.cleaned_data["message"]) today = datetime.date.today() redirect_url = reverse( 'archives_with_month', kwargs={ "mlist_fqdn": mlist_fqdn, 'year': today.year, 'month': today.month}) redirect_url += "?msg=sent-ok" return redirect(redirect_url) else: form = PostForm() context = { "mlist": mlist, "post_form": form, 'months_list': get_months(store, mlist.name), } return render(request, "message_new.html", context)
def index(request, mlist_fqdn, message_id_hash): ''' Displays a single message identified by its message_id_hash (derived from message_id) ''' search_form = SearchForm(auto_id=False) store = get_store(request) message = store.get_message_by_hash_from_list(mlist_fqdn, message_id_hash) if message is None: raise Http404 message.sender_email = message.sender_email.strip() set_message_votes(message, request.user) mlist = store.get_list(mlist_fqdn) context = { 'mlist' : mlist, 'message': message, 'message_id_hash' : message_id_hash, 'months_list': get_months(store, mlist.name), 'reply_form': ReplyForm(), } return render(request, "message.html", context)
def index(request, mlist_fqdn, message_id_hash): ''' Displays a single message identified by its message_id_hash (derived from message_id) ''' search_form = SearchForm(auto_id=False) store = get_store(request) message = store.get_message_by_hash_from_list(mlist_fqdn, message_id_hash) if message is None: raise Http404 message.sender_email = message.sender_email.strip() set_message_votes(message, request.user) mlist = store.get_list(mlist_fqdn) context = { 'mlist': mlist, 'message': message, 'message_id_hash': message_id_hash, 'months_list': get_months(store, mlist.name), 'reply_form': ReplyForm(), } return render(request, "message.html", context)
""" store = get_store(request) mlist = store.get_list(mlist_fqdn) failure = None if request.method == 'POST': form = PostForm(request.POST) if form.is_valid(): today = datetime.date.today() redirect_url = reverse( 'archives_with_month', kwargs={ "mlist_fqdn": mlist_fqdn, 'year': today.year, 'month': today.month}) redirect_url += "?msg=sent-ok" try: post_to_list(request, mlist, form.cleaned_data['subject'], form.cleaned_data["message"]) except PostingFailed, e: failure = str(e) else: return redirect(redirect_url) else: form = PostForm() context = { "mlist": mlist, "post_form": form, "failure": failure, 'months_list': get_months(store, mlist.name), } return render(request, "message_new.html", context)
store = get_store(request) mlist = store.get_list(mlist_fqdn) failure = None if request.method == 'POST': form = PostForm(request.POST) if form.is_valid(): today = datetime.date.today() redirect_url = reverse('archives_with_month', kwargs={ "mlist_fqdn": mlist_fqdn, 'year': today.year, 'month': today.month }) redirect_url += "?msg=sent-ok" try: post_to_list(request, mlist, form.cleaned_data['subject'], form.cleaned_data["message"]) except PostingFailed, e: failure = str(e) else: return redirect(redirect_url) else: form = PostForm() context = { "mlist": mlist, "post_form": form, "failure": failure, 'months_list': get_months(store, mlist.name), } return render(request, "message_new.html", context)
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) search_form = SearchForm(auto_id=False) participants = set() for thread in threads: participants.update(thread.participants) # Votes totalvotes = 0 totallikes = 0 totaldislikes = 0 for message_id_hash in thread.email_id_hashes: likes, dislikes, myvote = get_votes(message_id_hash, request.user) totallikes = totallikes + likes totalvotes = totalvotes + likes + dislikes totaldislikes = totaldislikes + dislikes if message_id_hash == thread.thread_id: # Starting email: same id as the thread_id thread.myvote = myvote try: thread.likes = totallikes / totalvotes except ZeroDivisionError: thread.likes = 0 try: thread.dislikes = totaldislikes / totalvotes except ZeroDivisionError: thread.dislikes = 0 thread.likestatus = "neutral" if thread.likes - thread.dislikes >= 10: thread.likestatus = "likealot" elif thread.likes - thread.dislikes > 0: thread.likestatus = "like" #elif thread.likes - thread.dislikes < 0: # thread.likestatus = "dislike" # 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 = [] all_threads = threads paginator = Paginator(threads, 10) page_num = request.GET.get('page') try: threads = paginator.page(page_num) except PageNotAnInteger: # If page is not an integer, deliver first page. threads = paginator.page(1) except EmptyPage: # If page is out of range (e.g. 9999), deliver last page of results. threads = paginator.page(paginator.num_pages) 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, 'current_page': page_num, 'search_form': search_form, '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)
def thread_index(request, mlist_fqdn, threadid, month=None, year=None): ''' Displays all the email for a given thread identifier ''' search_form = SearchForm(auto_id=False) 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) from_url = reverse("thread", kwargs={"mlist_fqdn":mlist_fqdn, "threadid":threadid}) # Tags tag_form = AddTagForm(initial={'from_url' : from_url}) 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" # 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) # 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, 'search_form': search_form, '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, 'participants': thread.participants, } context["participants"].sort(key=lambda x: x[0].lower()) if is_bot: # Don't rely on AJAX to load the replies context["replies"] = _get_thread_replies(request, thread) return render(request, "thread.html", context)
def overview(request, mlist_fqdn=None): if not mlist_fqdn: return redirect('/') search_form = SearchForm(auto_id=False) # Get stats for last 30 days today = datetime.datetime.utcnow() # 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) threads_result = store.get_threads(list_name=mlist.name, start=begin_date, end=end_date) threads = [] Thread = namedtuple('Thread', ["thread_id", "subject", "participants", "length", "date_active"]) participants = set() for thread_obj in threads_result: thread = Thread(thread_obj.thread_id, thread_obj.subject, thread_obj.participants, len(thread_obj), thread_obj.date_active) # 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 = [] # 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) 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] # threads per category is the top thread titles in each category if settings.USE_MOCKUPS: threads_per_category = generate_thread_per_category() else: threads_per_category = {} context = { 'mlist' : mlist, 'search_form': search_form, 'top_threads': top_threads[:5], 'most_active_threads': active_threads[:5], 'top_author': authors, 'threads_per_category': threads_per_category, 'months_list': get_months(store, mlist.name), 'evolution': evolution, 'days': days, 'archives_baseurl': archives_baseurl, } return render(request, "recent_activities.html", context)
def thread_index(request, mlist_fqdn, threadid, month=None, year=None): ''' Displays all the email for a given thread identifier ''' search_form = SearchForm(auto_id=False) 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) from_url = reverse("thread", kwargs={ "mlist_fqdn": mlist_fqdn, "threadid": threadid }) # Tags tag_form = AddTagForm(initial={'from_url': from_url}) 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" # 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) # 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, 'search_form': search_form, '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, 'participants': thread.participants, } context["participants"].sort(key=lambda x: x[0].lower()) if is_bot: # Don't rely on AJAX to load the replies context["replies"] = _get_thread_replies(request, thread) return render(request, "thread.html", context)
def thread_index(request, mlist_fqdn, threadid, month=None, year=None): ''' Displays all the email for a given thread identifier ''' search_form = SearchForm(auto_id=False) 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) if "sort" in request.GET and request.GET["sort"] == "date": sort_mode = "date" emails = thread.emails else: sort_mode = "thread" emails = thread.emails_by_reply participants = {} for email in emails: # Extract all the votes for this message set_message_votes(email, request.user) # Statistics on how many participants and messages this month participants[email.sender_name] = email.sender_email if sort_mode == "thread": email.level = email.thread_depth - 1 # replies start ragged left if email.level > 5: email.level = 5 from_url = reverse("thread", kwargs={"mlist_fqdn":mlist_fqdn, "threadid":threadid}) # Tags tag_form = AddTagForm(initial={'from_url' : from_url}) 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" # 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) context = { 'mlist' : mlist, 'threadid' : threadid, 'subject': subject, 'tags' : tags, 'search_form': search_form, 'addtag_form': tag_form, 'month': thread.date_active, 'participants': participants, 'first_mail': thread.starting_email, 'replies': list(emails)[1:], '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(), } return render(request, "thread.html", context)
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) search_form = SearchForm(auto_id=False) participants = set() for thread in threads: participants.update(thread.participants) # Votes totalvotes = 0 totallikes = 0 totaldislikes = 0 for message_id_hash in thread.email_id_hashes: likes, dislikes, myvote = get_votes(message_id_hash, request.user) totallikes = totallikes + likes totalvotes = totalvotes + likes + dislikes totaldislikes = totaldislikes + dislikes if message_id_hash == thread.thread_id: # Starting email: same id as the thread_id thread.myvote = myvote try: thread.likes = totallikes / totalvotes except ZeroDivisionError: thread.likes = 0 try: thread.dislikes = totaldislikes / totalvotes except ZeroDivisionError: thread.dislikes = 0 thread.likestatus = "neutral" if thread.likes - thread.dislikes >= 10: thread.likestatus = "likealot" elif thread.likes - thread.dislikes > 0: thread.likestatus = "like" #elif thread.likes - thread.dislikes < 0: # thread.likestatus = "dislike" # 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 = [] all_threads = threads paginator = Paginator(threads, 10) page_num = request.GET.get('page') try: threads = paginator.page(page_num) except PageNotAnInteger: # If page is not an integer, deliver first page. threads = paginator.page(1) except EmptyPage: # If page is out of range (e.g. 9999), deliver last page of results. threads = paginator.page(paginator.num_pages) 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, 'current_page': page_num, 'search_form': search_form, '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)
def overview(request, mlist_fqdn=None): if not mlist_fqdn: return redirect('/') search_form = SearchForm(auto_id=False) # Get stats for last 30 days today = datetime.datetime.utcnow() # 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) threads_result = store.get_threads(list_name=mlist.name, start=begin_date, end=end_date) threads = [] Thread = namedtuple( 'Thread', ["thread_id", "subject", "participants", "length", "date_active"]) participants = set() for thread_obj in threads_result: thread = Thread(thread_obj.thread_id, thread_obj.subject, thread_obj.participants, len(thread_obj), thread_obj.date_active) # 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 = [] # 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) 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] # threads per category is the top thread titles in each category if settings.USE_MOCKUPS: threads_per_category = generate_thread_per_category() else: threads_per_category = {} context = { 'mlist': mlist, 'search_form': search_form, 'top_threads': top_threads[:5], 'most_active_threads': active_threads[:5], 'top_author': authors, 'threads_per_category': threads_per_category, 'months_list': get_months(store, mlist.name), 'evolution': evolution, 'days': days, 'archives_baseurl': archives_baseurl, } return render(request, "recent_activities.html", context)