def last_views(request): store = get_store(request) # Last viewed threads try: last_views = LastView.objects.filter(user=request.user ).order_by("view_date") except Favorite.DoesNotExist: last_views = [] last_views = paginate(last_views, request.GET.get('lvpage')) for last_view in last_views: thread = store.get_thread(last_view.list_address, last_view.threadid) last_view.thread = thread if thread is None: last_view.delete() continue if thread.date_active.replace(tzinfo=utc) > last_view.view_date: # small optimization: only query the replies if necessary # XXX: Storm-specific (count method) thread.unread = thread.replies_after(last_view.view_date).count() else: thread.unread = 0 last_views = [ lv for lv in last_views if lv.thread is not None ] return render(request, 'ajax/last_views.html', { "last_views": last_views, })
def arch_month_mbox(request, list_name, year, month_name): store = get_store(request) mlist = get_list_by_name(list_name, store, request) if mlist is None: raise Http404("No archived mailing-list by that name.") month = month_name_to_num(month_name) year = int(year) begin_date = datetime.datetime(year, month, 1) if month != 12: end_month = month + 1 else: end_month = 1 end_date = datetime.datetime(year, end_month, 1) messages = store.get_messages(mlist.name, start=begin_date, end=end_date) messages.reverse() # they are sorted recent first by default mboxfile, mboxfilepath = tempfile.mkstemp(prefix="hyperkitty-", suffix=".mbox.gz") os.close(mboxfile) mbox = mailbox.mbox(mboxfilepath) for message in messages: mbox.add(message.full) mbox.close() content = StringIO() zipped_content = gzip.GzipFile(fileobj=content) with gzip.GzipFile(fileobj=content, mode="wb") as zipped_content: with open(mboxfilepath, "rb") as mboxfile: zipped_content.write(mboxfile.read()) response = HttpResponse(content.getvalue()) content.close() response['Content-Type'] = "application/mbox+gz" response['Content-Disposition'] = 'attachment; filename=%d-%s.txt.gz' \ % (year, month_name) response['Content-Length'] = len(response.content) os.remove(mboxfilepath) return response
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) 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"], attachments=request.FILES.getlist("attachment")) except PostingFailed, e: failure = str(e) else: return redirect(redirect_url)
def reply(request, mlist_fqdn, message_id_hash): """ Sends a reply to the list. TODO: unit tests """ if request.method != 'POST': raise SuspiciousOperation form = ReplyForm(request.POST) if not form.is_valid(): return HttpResponse(form.errors.as_text(), content_type="text/plain", status=400) store = get_store(request) mlist = store.get_list(mlist_fqdn) if form.cleaned_data["newthread"]: subject = form.cleaned_data["subject"] headers = {} else: message = store.get_message_by_hash_from_list(mlist.name, message_id_hash) subject = message.subject if not message.subject.lower().startswith("re:"): subject = "Re: %s" % subject headers = { "In-Reply-To": "<%s>" % message.message_id, "References": "<%s>" % message.message_id, } try: post_to_list(request, mlist, subject, form.cleaned_data["message"], headers, attachments=request.FILES.getlist('attachment')) except PostingFailed, e: return HttpResponse(str(e), content_type="text/plain", status=500)
def vote(request, mlist_fqdn, message_id_hash): """ Add a rating to a given message identified by messageid. """ if request.method != 'POST': raise SuspiciousOperation if not request.user.is_authenticated(): return HttpResponse('You must be logged in to vote', content_type="text/plain", status=403) store = get_store(request) message = store.get_message_by_hash_from_list(mlist_fqdn, message_id_hash) if message is None: raise Http404 value = int(request.POST['vote']) if value not in [-1, 0, 1]: raise SuspiciousOperation # Checks if the user has already voted for a this message. try: v = Rating.objects.get(user=request.user, messageid=message_id_hash, list_address=mlist_fqdn) if v.vote == value: return HttpResponse("You've already cast this vote", content_type="text/plain", status=403) except Rating.DoesNotExist: if value != 0: v = Rating(list_address=mlist_fqdn, messageid=message_id_hash, vote=value) v.user = request.user else: return HttpResponse("There is no vote to cancel", content_type="text/plain", status=500) if value == 0: v.delete() else: v.vote = value v.save() # Extract all the votes for this message to refresh it set_message_votes(message, request.user) t = loader.get_template('messages/like_form.html') html = t.render( RequestContext(request, { "object": message, "message_id_hash": message_id_hash, })) result = { "like": message.likes, "dislike": message.dislikes, "html": html, } return HttpResponse(json.dumps(result), mimetype='application/javascript')
def search(request, page=1): """ Returns messages corresponding to a query """ results_per_page = 10 store = get_store(request) query = request.GET.get("query") mlist_fqdn = request.GET.get("list") sort_mode = request.GET.get('sort') if mlist_fqdn is None: mlist = None else: mlist = store.get_list(mlist_fqdn) if mlist is None: raise Http404("No archived mailing-list by that name.") if not query: return render( request, "search_results.html", { 'mlist': mlist, "query": query or "", 'messages': [], 'total': 0, 'sort_mode': sort_mode, }) try: page_num = int(request.GET.get('page', "1")) except ValueError: page_num = 1 sortedby = None reverse = False if sort_mode == "date-asc": sortedby = "date" elif sort_mode == "date-desc": sortedby = "date" reverse = True query_result = store.search(query, mlist_fqdn, page_num, results_per_page, sortedby=sortedby, reverse=reverse) total = query_result["total"] messages = query_result["results"] for message in messages: set_message_votes(message, request.user) paginator = SearchPaginator(messages, 10, total) messages = paginate(messages, page_num, paginator=paginator) context = { 'mlist': mlist, "query": query, 'messages': messages, 'total': total, 'sort_mode': sort_mode, } return render(request, "search_results.html", context)
def replies(request, mlist_fqdn, threadid): """Get JSON encoded lists with the replies and the participants""" chunk_size = 5 offset = int(request.GET.get("offset", "1")) store = get_store(request) thread = store.get_thread(mlist_fqdn, threadid) mlist = store.get_list(mlist_fqdn) context = { 'mlist': mlist, 'threadid': threadid, 'reply_form': ReplyForm(), } context["replies"] = _get_thread_replies(request, thread, offset=offset, limit=chunk_size) replies_tpl = loader.get_template('threads/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), mimetype='application/javascript')
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)
def replies(request, mlist_fqdn, threadid): """Get JSON encoded lists with the replies and the participants""" chunk_size = 5 offset = int(request.GET.get("offset", "1")) store = get_store(request) thread = store.get_thread(mlist_fqdn, threadid) mlist = store.get_list(mlist_fqdn) context = { 'mlist': mlist, 'threadid': threadid, 'reply_form': ReplyForm(), } context["replies"] = _get_thread_replies(request, thread, offset=offset, limit=chunk_size) replies_tpl = loader.get_template('threads/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), mimetype='application/javascript')
def vote(request, mlist_fqdn, message_id_hash): """ Vote for or against a given message identified by messageid. """ if request.method != 'POST': raise SuspiciousOperation if not request.user.is_authenticated(): return HttpResponse('You must be logged in to vote', content_type="text/plain", status=403) if "user_id" not in request.session: return HttpResponse("Could not find or create your user ID in Mailman", content_type="text/plain", status=500) store = get_store(request) message = store.get_message_by_hash_from_list(mlist_fqdn, message_id_hash) if message is None: raise Http404 value = int(request.POST['vote']) message.vote(value, request.session["user_id"]) # Extract all the votes for this message to refresh it message.myvote = message.get_vote_by_user_id(request.session["user_id"]) t = loader.get_template('messages/like_form.html') html = t.render(RequestContext(request, { "object": message, "message_id_hash": message_id_hash, })) result = { "like": message.likes, "dislike": message.dislikes, "html": html, } return HttpResponse(json.dumps(result), content_type='application/javascript')
def get(self, request, mlist_fqdn, messageid): store = get_store(request) email = store.get_message_by_id_from_list(mlist_fqdn, messageid) if not email: return Response(status=404) else: return Response(EmailSerializer(email).data)
def replies(request, mlist_fqdn, threadid): """Get JSON encoded lists with the replies and the participants""" chunk_size = 5 offset = int(request.GET.get("offset", "1")) store = get_store(request) thread = store.get_thread(mlist_fqdn, threadid) mlist = store.get_list(mlist_fqdn) # 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 = { 'mlist': mlist, 'threadid': threadid, 'reply_form': ReplyForm(), 'last_view': last_view, } context["replies"] = _get_thread_replies(request, thread, offset=offset, limit=chunk_size) replies_tpl = loader.get_template('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 get(self, request, mlist_fqdn, threadid): store = get_store(request) thread = store.get_thread(mlist_fqdn, threadid) if not thread: return Response(status=404) else: return Response(ThreadSerializer(thread).data)
def archives(request, mlist_fqdn, year=None, month=None, day=None): if year is None and month is None: today = datetime.date.today() return redirect(reverse( 'archives_with_month', kwargs={ "mlist_fqdn": mlist_fqdn, 'year': today.year, 'month': today.month})) begin_date, end_date = get_display_dates(year, month, day) store = get_store(request) mlist = store.get_list(mlist_fqdn) threads = store.get_threads(mlist_fqdn, start=begin_date, end=end_date) if day is None: list_title = date_format(begin_date, "F Y") no_results_text = "for this month" else: #list_title = date_format(begin_date, settings.DATE_FORMAT) list_title = formats.date_format(begin_date) # works with i18n no_results_text = "for this day" extra_context = { 'month': begin_date, 'month_num': begin_date.month, "list_title": list_title.capitalize(), "no_results_text": no_results_text, } return _thread_list(request, mlist, threads, extra_context=extra_context)
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 reply(request, mlist_fqdn, message_id_hash): """ Sends a reply to the list. TODO: unit tests """ if request.method != 'POST': raise SuspiciousOperation form = ReplyForm(request.POST) if not form.is_valid(): return HttpResponse(form.errors.as_text(), content_type="text/plain", status=400) store = get_store(request) mlist = store.get_list(mlist_fqdn) if form.cleaned_data["newthread"]: subject = form.cleaned_data["subject"] headers = {} else: message = store.get_message_by_hash_from_list(mlist.name, message_id_hash) subject = message.subject if not message.subject.lower().startswith("re:"): subject = "Re: %s" % subject headers = {"In-Reply-To": "<%s>" % message.message_id, "References": "<%s>" % message.message_id, } try: post_to_list(request, mlist, subject, form.cleaned_data["message"], headers) except PostingFailed, e: return HttpResponse(str(e), content_type="text/plain", status=500)
def user_profile(request, user_email=None): if not request.user.is_authenticated(): return redirect('user_login') store = get_store(request) # try to render the user profile. try: user_profile = request.user.get_profile() except ObjectDoesNotExist: user_profile = UserProfile.objects.create(user=request.user) if request.method == 'POST': form = UserProfileForm(request.POST) if form.is_valid(): request.user.first_name = form.cleaned_data["first_name"] request.user.last_name = form.cleaned_data["last_name"] user_profile.timezone = form.cleaned_data["timezone"] request.user.save() user_profile.save() redirect_url = reverse('user_profile') redirect_url += "?msg=updated-ok" return redirect(redirect_url) else: form = UserProfileForm( initial={ "first_name": request.user.first_name, "last_name": request.user.last_name, "timezone": get_current_timezone(), }) # Favorites try: favorites = Favorite.objects.filter(user=request.user) except Favorite.DoesNotExist: favorites = [] for fav in favorites: thread = store.get_thread(fav.list_address, fav.threadid) fav.thread = thread if thread is None: fav.delete() # thread has gone away? favorites = [f for f in favorites if f.thread is not None] # 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) context = { 'user_profile': user_profile, 'form': form, 'favorites': favorites, 'flash_messages': flash_messages, } return render(request, "user_profile.html", context)
def reattach_suggest(request, mlist_fqdn, threadid): store = get_store(request) mlist = store.get_list(mlist_fqdn) thread = store.get_thread(mlist_fqdn, threadid) default_search_query = stripped_subject( mlist, thread.subject).lower().replace("re:", "") search_query = request.GET.get("q") if not search_query: search_query = default_search_query search_query = search_query.strip() if store.search_index: search_result = store.search(search_query, mlist_fqdn, 1, 50) messages = search_result["results"] else: messages = [] suggested_threads = [] for msg in messages: if msg.thread not in suggested_threads and msg.thread_id != threadid: suggested_threads.append(msg.thread) context = { 'mlist' : mlist, 'suggested_threads': suggested_threads[:10], } return render(request, "ajax/reattach_suggest.html", context)
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) 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"], attachments=request.FILES.getlist("attachment")) except PostingFailed, e: failure = str(e) else: return redirect(redirect_url)
def reattach_suggest(request, mlist_fqdn, threadid): store = get_store(request) mlist = store.get_list(mlist_fqdn) thread = store.get_thread(mlist_fqdn, threadid) default_search_query = stripped_subject(mlist, thread.subject).lower().replace( "re:", "") search_query = request.GET.get("q") if not search_query: search_query = default_search_query search_query = search_query.strip() if store.search_index: search_result = store.search(search_query, mlist_fqdn, 1, 50) messages = search_result["results"] else: messages = [] suggested_threads = [] for msg in messages: if msg.thread not in suggested_threads and msg.thread_id != threadid: suggested_threads.append(msg.thread) context = { 'mlist': mlist, 'suggested_threads': suggested_threads[:10], } return render(request, "ajax/reattach_suggest.html", context)
def get(self, request): store = get_store(request) lists = store.get_lists() if not lists: return Response(status=404) else: return Response(ListSerializer(lists, many=True).data)
def get(self, request, mlist_fqdn, messageid): store = get_store(request) email = store.get_message_by_hash_from_list(mlist_fqdn, messageid) if not email: return Response(status=404) else: email.likes, email.dislikes, _ignore = get_votes(email.message_id_hash) return Response(EmailSerializer(email).data)
def vote(request, mlist_fqdn, message_id_hash): """ Add a rating to a given message identified by messageid. """ if request.method != 'POST': raise SuspiciousOperation if not request.user.is_authenticated(): return HttpResponse('You must be logged in to vote', content_type="text/plain", status=403) store = get_store(request) message = store.get_message_by_hash_from_list(mlist_fqdn, message_id_hash) if message is None: raise Http404 value = int(request.POST['vote']) if value not in [-1, 0, 1]: raise SuspiciousOperation # Checks if the user has already voted for a this message. try: v = Rating.objects.get(user=request.user, messageid=message_id_hash, list_address=mlist_fqdn) if v.vote == value: return HttpResponse("You've already cast this vote", content_type="text/plain", status=403) except Rating.DoesNotExist: if value != 0: v = Rating(list_address=mlist_fqdn, messageid=message_id_hash, vote=value) v.user = request.user else: return HttpResponse("There is no vote to cancel", content_type="text/plain", status=500) if value == 0: v.delete() else: v.vote = value v.save() # Invalidate the cache for the thread and user votes cache.delete("list:%s:thread:%s:votes" % (mlist_fqdn, message.thread_id)) if message.user_id: cache.delete("user:%s:list:%s:votes" % (message.user_id, mlist_fqdn)) # Extract all the votes for this message to refresh it set_message_votes(message, request.user) t = loader.get_template('messages/like_form.html') html = t.render(RequestContext(request, { "object": message, "message_id_hash": message_id_hash, })) result = { "like": message.likes, "dislike": message.dislikes, "html": html, } return HttpResponse(json.dumps(result), content_type='application/javascript')
def index(request): store = get_store(request) lists = store.get_lists() context = { 'view_name': 'all_lists', 'all_lists': lists, } return render(request, "index.html", context)
def user_profile(request, user_email=None): if not request.user.is_authenticated(): return redirect('user_login') store = get_store(request) # try to render the user profile. try: user_profile = request.user.get_profile() except ObjectDoesNotExist: user_profile = UserProfile.objects.create(user=request.user) if request.method == 'POST': form = UserProfileForm(request.POST) if form.is_valid(): request.user.first_name = form.cleaned_data["first_name"] request.user.last_name = form.cleaned_data["last_name"] user_profile.timezone = form.cleaned_data["timezone"] request.user.save() user_profile.save() redirect_url = reverse('user_profile') redirect_url += "?msg=updated-ok" return redirect(redirect_url) else: form = UserProfileForm(initial={ "first_name": request.user.first_name, "last_name": request.user.last_name, "timezone": get_current_timezone(), }) # Favorites try: favorites = Favorite.objects.filter(user=request.user) except Favorite.DoesNotExist: favorites = [] for fav in favorites: thread = store.get_thread(fav.list_address, fav.threadid) fav.thread = thread if thread is None: fav.delete() # thread has gone away? favorites = [ f for f in favorites if f.thread is not None ] # 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) context = { 'user_profile' : user_profile, 'form': form, 'favorites': favorites, 'flash_messages': flash_messages, } return render(request, "user_profile.html", context)
def index(request): store = get_store(request) lists = store.get_lists() context = { 'all_lists': lists, 'search_form': SearchForm(auto_id=False), } return render(request, "index.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) 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)
def get(self, request, mlist_fqdn, messageid): store = get_store(request) email = store.get_message_by_hash_from_list(mlist_fqdn, messageid) if not email: return Response(status=404) else: email.likes, email.dislikes, _ignore = get_votes( email.message_id_hash) return Response(EmailSerializer(email).data)
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)
def summary(request, list_name=None): if list_name is None: return HttpResponseRedirect(reverse('root')) store = get_store(request) mlist = get_list_by_name(list_name, store, request) if mlist is None: raise Http404("No archived mailing-list by that name.") url = reverse('list_overview', kwargs={'mlist_fqdn': mlist.name}) #return HttpResponse(request.build_absolute_uri(url)) return HttpResponseRedirect(url)
def votes(request): store = get_store(request) if "user_id" not in request.session: return HttpResponse("Could not find or create your user ID in Mailman", content_type="text/plain", status=500) user = store.get_user(request.session["user_id"]) votes = paginate(user.votes, request.GET.get('vpage')) return render(request, 'ajax/votes.html', { "votes": votes, })
def public_profile(request, user_id): class FakeMailmanUser(object): display_name = None created_on = None addresses = [] subscription_list_ids = [] store = get_store(request) try: client = mailmanclient.Client('%s/3.0' % settings.MAILMAN_REST_SERVER, settings.MAILMAN_API_USER, settings.MAILMAN_API_PASS) mm_user = client.get_user(user_id) except HTTPError: raise Http404("No user with this ID: %s" % user_id) except mailmanclient.MailmanConnectionError: db_user = store.get_user(user_id) if db_user is None: return HttpResponse("Can't connect to Mailman", content_type="text/plain", status=500) mm_user = FakeMailmanUser() mm_user.display_name = list(db_user.senders)[0].name mm_user.addresses = db_user.addresses fullname = mm_user.display_name if not fullname: fullname = store.get_sender_name(user_id) # Subscriptions subscriptions = get_subscriptions(store, client, mm_user) likes = sum([s["likes"] for s in subscriptions]) dislikes = sum([s["dislikes"] for s in subscriptions]) likestatus = "neutral" if likes - dislikes >= 10: likestatus = "likealot" elif likes - dislikes > 0: likestatus = "like" try: email = unicode(mm_user.addresses[0]) except KeyError: email = None if mm_user.created_on is not None: creation = dateutil.parser.parse(mm_user.created_on) else: creation = None context = { "fullname": fullname, "mm_user": mm_user, "email": email, "creation": creation, "subscriptions": subscriptions, "posts_count": sum([s["posts_count"] for s in subscriptions]), "likes": likes, "dislikes": dislikes, "likestatus": likestatus, } return render(request, "user_public_profile.html", context)
def search(request, page=1): """ Returns messages corresponding to a query """ results_per_page = 10 store = get_store(request) query = request.GET.get("query") mlist_fqdn = request.GET.get("list") sort_mode = request.GET.get('sort') if mlist_fqdn is None: mlist = None else: mlist = store.get_list(mlist_fqdn) if mlist is None: raise Http404("No archived mailing-list by that name.") if not query: return render(request, "search_results.html", { 'mlist' : mlist, "query": query or "", 'messages': [], 'total': 0, 'sort_mode': sort_mode, }) try: page_num = int(request.GET.get('page', "1")) except ValueError: page_num = 1 sortedby = None reverse = False if sort_mode == "date-asc": sortedby = "date" elif sort_mode == "date-desc": sortedby = "date" reverse = True query_result = store.search(query, mlist_fqdn, page_num, results_per_page, sortedby=sortedby, reverse=reverse) total = query_result["total"] messages = query_result["results"] for message in messages: set_message_votes(message, request.user) paginator = SearchPaginator(messages, 10, total) messages = paginate(messages, page_num, paginator=paginator) context = { 'mlist' : mlist, "query": query, 'messages': messages, 'total': total, 'sort_mode': sort_mode, } return render(request, "search_results.html", context)
def index(request): base_url = settings.MAILMAN_API_URL % { 'username': settings.MAILMAN_USER, 'password': settings.MAILMAN_PASS} store = get_store(request) lists = store.get_lists() context = { 'all_lists': lists, 'search_form': SearchForm(auto_id=False), } return render(request, "index.html", context)
def arch_month(request, list_name, year, month_name, summary_type="thread"): store = get_store(request) mlist = get_list_by_name(list_name, store, request) if mlist is None: raise Http404("No archived mailing-list by that name.") url = reverse('archives_with_month', kwargs={ 'mlist_fqdn': mlist.name, 'year': year, 'month': str(month_name_to_num(month_name)).rjust(2, "0"), }) #return HttpResponse(request.build_absolute_uri(url)) return HttpResponseRedirect(url)
def subscriptions(request): store = get_store(request) # get the Mailman user try: mm_client = get_mailman_client() mm_user = mm_client.get_user(request.user.email) except (HTTPError, mailmanclient.MailmanConnectionError): mm_client = mm_user = None # Subscriptions subscriptions = get_subscriptions(store, mm_client, mm_user) return render(request, 'fragments/user_subscriptions.html', { "subscriptions": subscriptions, })
def posts(request, user_id): store = get_store(request) mlist_fqdn = request.GET.get("list") if mlist_fqdn is None: mlist = None return HttpResponse("Not implemented yet", status=500) else: mlist = store.get_list(mlist_fqdn) if mlist is None: raise Http404("No archived mailing-list by that name.") if not is_mlist_authorized(request, mlist): return render(request, "errors/private.html", { "mlist": mlist, }, status=403) # Get the user's full name try: client = mailmanclient.Client('%s/3.0' % settings.MAILMAN_REST_SERVER, settings.MAILMAN_API_USER, settings.MAILMAN_API_PASS) mm_user = client.get_user(user_id) except HTTPError: raise Http404("No user with this ID: %s" % user_id) except mailmanclient.MailmanConnectionError: fullname = None else: fullname = mm_user.display_name if not fullname: fullname = store.get_sender_name(user_id) # Get the messages and paginate them messages = store.get_messages_by_user_id(user_id, mlist_fqdn) try: page_num = int(request.GET.get('page', "1")) except ValueError: page_num = 1 messages = paginate(messages, page_num) for message in messages: message.myvote = message.get_vote_by_user_id( request.session.get("user_id")) context = { 'user_id': user_id, 'mlist' : mlist, 'messages': messages, 'fullname': fullname, } return render(request, "user_posts.html", context)
def message(request, list_name, year, month_name, msg_num): store = get_store(request) mlist = get_list_by_name(list_name, store, request) if mlist is None: raise Http404("No archived mailing-list by that name.") message = store.get_message_by_number(mlist.name, int(msg_num)) if message is None: raise Http404("No such message in this mailing-list.") url = reverse('message_index', kwargs={ 'mlist_fqdn': mlist.name, 'message_id': message.message_id_hash, }) #return HttpResponse(request.build_absolute_uri(url)) return HttpResponseRedirect(url)
def reattach(request, mlist_fqdn, threadid): if not request.user.is_staff: return HttpResponse('You must be a staff member to reattach a thread', content_type="text/plain", status=403) flash_messages = [] store = get_store(request) mlist = store.get_list(mlist_fqdn) thread = store.get_thread(mlist_fqdn, threadid) if request.method == 'POST': parent_tid = request.POST.get("parent") if not parent_tid: parent_tid = request.POST.get("parent-manual") if not parent_tid or not re.match("\w{32}", parent_tid): flash_messages.append({"type": "warning", "msg": "Invalid thread id, it should look " "like OUAASTM6GS4E5TEATD6R2VWMULG44NKJ."}) elif parent_tid == threadid: flash_messages.append({"type": "warning", "msg": "Can't re-attach a thread to " "itself, check your thread ID."}) else: new_thread = store.get_thread(mlist_fqdn, parent_tid) if new_thread is None: flash_messages.append({"type": "warning", "msg": "Unknown thread, check your " "thread ID."}) elif thread.starting_email.date <= new_thread.starting_email.date: flash_messages.append({"type": "error", "msg": "Can't attach an older thread " "to a newer thread."}) else: for msg in thread.emails: store.attach_to_thread(msg, new_thread) store.delete_thread(mlist_fqdn, threadid) return redirect(reverse( 'thread', kwargs={ "mlist_fqdn": mlist_fqdn, 'threadid': parent_tid, })+"?msg=attached-ok") context = { 'mlist' : mlist, 'thread': thread, 'months_list': get_months(store, mlist.name), 'flash_messages': flash_messages, } return render(request, "reattach.html", context)
def subscriptions(request): store = get_store(request) # get the Mailman user try: mm_client = mailmanclient.Client( '%s/3.0' % settings.MAILMAN_REST_SERVER, settings.MAILMAN_API_USER, settings.MAILMAN_API_PASS) mm_user = mm_client.get_user(request.user.email) except (HTTPError, mailmanclient.MailmanConnectionError): mm_client = mm_user = None # Subscriptions subscriptions = get_subscriptions(store, mm_client, mm_user) return render(request, 'fragments/user_subscriptions.html', { "subscriptions": subscriptions, })
def votes(request): store = get_store(request) # Votes try: votes = Rating.objects.filter(user=request.user) except Rating.DoesNotExist: votes = [] votes = paginate(votes, request.GET.get('vpage')) for vote in votes: vote.message = store.get_message_by_hash_from_list( vote.list_address, vote.messageid) if vote.message is None: vote.delete() votes = [v for v in votes if v.message is not None] return render(request, 'ajax/votes.html', { "votes": votes, })
def inner(request, *args, **kwargs): if "mlist_fqdn" in kwargs: mlist_fqdn = kwargs["mlist_fqdn"] else: mlist_fqdn = args[0] try: store = get_store(request) except KeyError: return func(request, *args, **kwargs) # Unittesting? mlist = store.get_list(mlist_fqdn) if mlist is None: raise Http404("No archived mailing-list by that name.") #return HttpResponse(request.session.get("subscribed", "NO KEY"), content_type="text/plain") if not is_mlist_authorized(request, mlist): return render(request, "errors/private.html", { "mlist": mlist, }, status=403) return func(request, *args, **kwargs)
def search_tag(request, mlist_fqdn, tag): '''Returns threads having a particular tag''' store = get_store(request) mlist = store.get_list(mlist_fqdn) try: tags = Tag.objects.filter(tag=tag) except Tag.DoesNotExist: tags = {} threads = [] for t in tags: threads.append(store.get_thread(mlist_fqdn, t.threadid)) extra_context = { "tag": tag, "list_title": "Search results for tag \"%s\"" % tag, "no_results_text": "for this tag", } return _thread_list(request, mlist, threads, extra_context=extra_context)
def list_properties(request): """Get JSON encoded list properties""" store = get_store(request) lists = store.get_lists() client = Client('%s/3.0' % settings.MAILMAN_REST_SERVER, settings.MAILMAN_API_USER, settings.MAILMAN_API_PASS) props = {} for ml in lists: try: mm_list = client.get_list(ml.name) except urllib2.HTTPError: continue props[ml.name] = { "display_name": mm_list.display_name, "description": mm_list.settings["description"], } # Update KittyStore if necessary if ml.display_name != mm_list.display_name: ml.display_name = mm_list.display_name return HttpResponse(json.dumps(props), mimetype='application/javascript')
def index(request): now = datetime.datetime.now() store = get_store(request) lists = [ l for l in store.get_lists() if not settings.FILTER_VHOST or show_mlist(l, request) ] initials = set() for mlist in lists: if mlist.archive_policy != ArchivePolicy.private: mlist.is_private = False mlist.can_view = True else: mlist.is_private = True if is_mlist_authorized(request, mlist): mlist.can_view = True else: mlist.can_view = False if mlist.created_at and \ now - mlist.created_at <= datetime.timedelta(days=30): mlist.is_new = True else: mlist.is_new = False initials.add(mlist.name[0]) # sorting sort_mode = request.GET.get('sort') if sort_mode == "active": lists.sort(key=lambda l: l.recent_threads_count, reverse=True) elif sort_mode == "popular": lists.sort(key=lambda l: l.recent_participants_count, reverse=True) elif sort_mode == "creation": lists.sort(key=lambda l: l.created_at, reverse=True) else: sort_mode = None context = { 'view_name': 'all_lists', 'all_lists': lists, 'initials': sorted(list(initials)), 'sort_mode': sort_mode, } return render(request, "index.html", context)