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')
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')
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')
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')
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)
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)