def replies(request, mlist_fqdn, threadid): """Get JSON encoded lists with the replies and the participants""" chunk_size = 6 # must be an even number, or the even/odd cycle will be broken offset = int(request.GET.get("offset", "1")) mlist = get_object_or_404(MailingList, name=mlist_fqdn) thread = get_object_or_404(Thread, mailinglist__name=mlist_fqdn, thread_id=threadid) # Last view last_view = request.GET.get("last_view") if last_view: try: last_view = datetime.datetime.fromtimestamp(int(last_view), utc) except ValueError: last_view = None context = { 'threadid': thread, 'reply_form': get_posting_form(ReplyForm, request, mlist), 'last_view': last_view, } context["replies"] = _get_thread_replies(request, thread, offset=offset, limit=chunk_size) replies_tpl = loader.get_template('hyperkitty/ajax/replies.html') replies_html = replies_tpl.render(RequestContext(request, context)) response = {"replies_html": replies_html, "more_pending": False, "next_offset": None, } if len(context["replies"]) == chunk_size: response["more_pending"] = True response["next_offset"] = offset + chunk_size return HttpResponse(json.dumps(response), content_type='application/javascript')
def new_message(request, mlist_fqdn): """ Sends a new thread-starting message to the list. """ if not getattr(settings, 'HYPERKITTY_ALLOW_WEB_POSTING', True): return HttpResponse('Posting via Hyperkitty is disabled', content_type="text/plain", status=403) mlist = get_object_or_404(MailingList, name=mlist_fqdn) if request.method == 'POST': form = get_posting_form(PostForm, request, mlist, request.POST) if form.is_valid(): today = datetime.date.today() headers = {} if form.cleaned_data["sender"]: headers["From"] = form.cleaned_data["sender"] try: post_to_list(request, mlist, form.cleaned_data['subject'], form.cleaned_data["message"], headers) except PostingFailed as e: messages.error(request, str(e)) except ModeratedListException as e: return HttpResponse(str(e), content_type="text/plain", status=403) else: messages.success(request, "The message has been sent successfully.") redirect_url = reverse('hk_archives_with_month', kwargs={ "mlist_fqdn": mlist_fqdn, 'year': today.year, 'month': today.month }) return redirect(redirect_url) else: form = get_posting_form(PostForm, request, mlist) context = { "mlist": mlist, "post_form": form, 'months_list': get_months(mlist), } return render(request, "hyperkitty/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) ''' mlist = get_object_or_404(MailingList, name=mlist_fqdn) message = get_object_or_404(Email, mailinglist=mlist, message_id_hash=message_id_hash) if request.user.is_authenticated: message.myvote = message.votes.filter(user=request.user).first() else: message.myvote = None # Export button export = { "url": "%s?message=%s" % (reverse("hk_list_export_mbox", kwargs={ "mlist_fqdn": mlist.name, "filename": "%s-%s" % (mlist.name, message.message_id_hash) }), message.message_id_hash), "message": _("Download"), "title": _("This message in gzipped mbox format"), } context = { 'mlist': mlist, 'message': message, 'message_id_hash': message_id_hash, 'months_list': get_months(mlist), 'month': message.date, 'reply_form': get_posting_form(ReplyForm, request, mlist), 'export': export, 'posting_enabled': getattr(settings, 'HYPERKITTY_ALLOW_WEB_POSTING', True), } return render(request, "hyperkitty/message.html", context)
def replies(request, mlist_fqdn, threadid): """Get JSON encoded lists with the replies and the participants""" # chunk_size must be an even number, or the even/odd cycle will be broken. chunk_size = 6 offset = int(request.GET.get("offset", "0")) mlist = get_object_or_404(MailingList, name=mlist_fqdn) thread = get_object_or_404(Thread, mailinglist__name=mlist_fqdn, thread_id=threadid) # Last view last_view = request.GET.get("last_view") if last_view: try: last_view = datetime.datetime.fromtimestamp(int(last_view), utc) except ValueError: last_view = None context = { 'threadid': thread, 'reply_form': get_posting_form(ReplyForm, request, mlist), 'last_view': last_view, 'posting_enabled': getattr(settings, 'HYPERKITTY_ALLOW_WEB_POSTING', True), } context["replies"] = _get_thread_replies(request, thread, offset=offset, limit=chunk_size) replies_tpl = loader.get_template('hyperkitty/ajax/replies.html') replies_html = replies_tpl.render(context, request) response = { "replies_html": replies_html, "more_pending": False, "next_offset": None, } if len(context["replies"]) == chunk_size: response["more_pending"] = True response["next_offset"] = offset + chunk_size return HttpResponse(json.dumps(response), content_type='application/javascript')
def reply(request, mlist_fqdn, message_id_hash): """Sends a reply to the list.""" if not getattr(settings, 'HYPERKITTY_ALLOW_WEB_POSTING', True): return HttpResponse('Posting via Hyperkitty is disabled', content_type="text/plain", status=403) mlist = get_object_or_404(MailingList, name=mlist_fqdn) form = get_posting_form(ReplyForm, request, mlist, request.POST) if not form.is_valid(): return HttpResponse(form.errors.as_text(), content_type="text/plain", status=400) if form.cleaned_data["newthread"]: subject = form.cleaned_data["subject"] headers = {} else: message = get_object_or_404(Email, mailinglist=mlist, message_id_hash=message_id_hash) subject = reply_subject(message.subject) headers = { "In-Reply-To": "<%s>" % message.message_id, "References": "<%s>" % message.message_id, } if form.cleaned_data["sender"]: headers["From"] = form.cleaned_data["sender"] try: subscribed_now = post_to_list(request, mlist, subject, form.cleaned_data["message"], headers) except PostingFailed as e: return HttpResponse(str(e), content_type="text/plain", status=500) except ModeratedListException as e: return HttpResponse(str(e), content_type="text/plain", status=403) # TODO: if newthread, don't insert the temp mail in the thread, redirect to # the new thread. Should we insert the mail in the DB and flag it as # "temporary", to be confirmed by a later reception from mailman? This # looks complex, because the temp mail should only be visible by its # sender. if form.cleaned_data["newthread"]: html = None else: email_reply = { "sender_name": "%s %s" % (request.user.first_name, request.user.last_name), "sender_address": (form.cleaned_data["sender"] or request.user.email), "content": form.cleaned_data["message"], # no need to increment, level = thread_depth - 1 "level": message.thread_depth, } t = loader.get_template('hyperkitty/ajax/temp_message.html') html = t.render({'email': email_reply}, request) # TODO: make the message below translatable. result = { "result": _("Your reply has been sent and is being processed."), "message_html": html } if subscribed_now: result['result'] += ( _("\n You have been subscribed to {} list.").format(mlist_fqdn)) return HttpResponse(json.dumps(result), content_type="application/javascript")
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)
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)