def update_from_mailman(self): try: client = get_mailman_client() mm_list = client.get_list(self.name) except MailmanConnectionError: return except HTTPError: return # can't update at this time if not mm_list: return def convert_date(value): value = dateutil.parser.parse(value) if value.tzinfo is None: value = value.replace(tzinfo=utc) return value converters = { "created_at": convert_date, "archive_policy": lambda p: ArchivePolicy[p].value, # pylint: disable=unsubscriptable-object } for propname in self.MAILMAN_ATTRIBUTES: try: value = getattr(mm_list, propname) except AttributeError: value = mm_list.settings[propname] if propname in converters: value = converters[propname](value) setattr(self, propname, value) self.save()
def get_mailman_user(self): # Only cache the user_id, not the whole user instance, because # mailmanclient is not pickle-safe cache_key = "User:%s:mailman_user_id" % self.id user_id = cache.get(cache_key) try: mm_client = get_mailman_client() if user_id is None: try: mm_user = mm_client.get_user(self.user.email) except HTTPError as e: if e.code != 404: raise # will be caught down there mm_user = mm_client.create_user(self.user.email, self.user.get_full_name()) # XXX The email is not set as verified, because we don't # know if the registration that was used verified it. logger.info("Created Mailman user for %s (%s)", self.user.username, self.user.email) cache.set(cache_key, mm_user.user_id, None) return mm_user else: return mm_client.get_user(user_id) except (HTTPError, MailmanConnectionError) as e: logger.warning( "Error getting or creating the Mailman user of %s (%s): %s", self.user.username, self.user.email, e ) return None
def public_profile(request, user_id): class FakeMailmanUser(object): display_name = None created_on = None addresses = [] subscription_list_ids = [] user_id = None try: client = get_mailman_client() mm_user = client.get_user(user_id) except HTTPError: raise Http404("No user with this ID: %s" % user_id) except mailmanclient.MailmanConnectionError: #if db_user is None: # return HttpResponse("Can't connect to Mailman", # content_type="text/plain", status=500) mm_user = FakeMailmanUser() mm_user.user_id = user_id #mm_user.addresses = db_user.addresses #XXX: don't list subscriptions, there's a privacy issue here. # # Subscriptions # subscriptions = get_subscriptions(mm_user, db_user) all_votes = Vote.objects.filter(email__sender__mailman_id=user_id) likes = all_votes.filter(value=1).count() dislikes = all_votes.filter(value=-1).count() likestatus = "neutral" if likes - dislikes >= 10: likestatus = "likealot" elif likes - dislikes > 0: likestatus = "like" # This is only used for the Gravatar. No email display on the public # profile, we have enough spam as it is, thank you very much. try: email = unicode(mm_user.addresses[0]) except (KeyError, IndexError): email = None fullname = mm_user.display_name if not fullname: fullname = Sender.objects.filter(mailman_id=user_id).exclude(name="" ).values_list("name", flat=True).first() if mm_user.created_on is not None: creation = dateutil.parser.parse(mm_user.created_on) else: creation = None posts_count = Email.objects.filter(sender__mailman_id=user_id).count() is_user = request.user.is_authenticated() and bool( set([str(a) for a in mm_user.addresses]) & set(request.user.hyperkitty_profile.addresses)) context = { "fullname": fullname, "creation": creation, "posts_count": posts_count, "likes": likes, "dislikes": dislikes, "likestatus": likestatus, "email": email, "is_user": is_user, } return render(request, "hyperkitty/user_public_profile.html", context)
def set_mailman_id(self): try: client = get_mailman_client() mm_user = client.get_user(self.address) except HTTPError as e: raise MailmanConnectionError(e) # normalize all possible error types self.mailman_id = mm_user.user_id self.save()
def public_profile(request, user_id): class FakeMailmanUser(object): display_name = None created_on = None addresses = [] subscription_list_ids = [] user_id = None try: client = get_mailman_client() mm_user = client.get_user(user_id) except HTTPError: raise Http404("No user with this ID: %s" % user_id) except mailmanclient.MailmanConnectionError: #if db_user is None: # return HttpResponse("Can't connect to Mailman", # content_type="text/plain", status=500) mm_user = FakeMailmanUser() mm_user.user_id = user_id #mm_user.addresses = db_user.addresses #XXX: don't list subscriptions, there's a privacy issue here. # # Subscriptions # subscriptions = get_subscriptions(mm_user, db_user) all_votes = Vote.objects.filter(email__sender__mailman_id=user_id) likes = all_votes.filter(value=1).count() dislikes = all_votes.filter(value=-1).count() likestatus = "neutral" if likes - dislikes >= 10: likestatus = "likealot" elif likes - dislikes > 0: likestatus = "like" # This is only used for the Gravatar. No email display on the public # profile, we have enough spam as it is, thank you very much. try: email = unicode(mm_user.addresses[0]) except (KeyError, IndexError): email = None fullname = mm_user.display_name if not fullname: fullname = Sender.objects.filter(mailman_id=user_id).exclude( name="").values_list("name", flat=True).first() if mm_user.created_on is not None: creation = dateutil.parser.parse(mm_user.created_on) else: creation = None posts_count = Email.objects.filter(sender__mailman_id=user_id).count() context = { "fullname": fullname, "creation": creation, "posts_count": posts_count, "likes": likes, "dislikes": dislikes, "likestatus": likestatus, "email": email, } return render(request, "hyperkitty/user_public_profile.html", context)
def public_profile(request, user_id): class FakeMailmanUser(object): display_name = None created_on = None addresses = [] subscription_list_ids = [] user_id = None store = get_store(request) try: client = get_mailman_client() 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) # fallback to kittystore if possible 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 _get_value(): mm_user = self.get_mailman_user() if mm_user is None: return [] mm_client = get_mailman_client() subscriptions = {} for member in mm_user.subscriptions: mlist_name = mm_client.get_list(member.list_id).fqdn_listname ## de-duplicate subscriptions #if mlist_name in [ s["list_name"] for s in sub_names ]: # continue subscriptions[mlist_name] = member.address return subscriptions
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 _get_value(): mm_user = self.get_mailman_user() if mm_user is None: return [] mm_client = get_mailman_client() sub_names = set() for mlist_id in mm_user.subscription_list_ids: mlist_name = mm_client.get_list(mlist_id).fqdn_listname ## de-duplicate subscriptions #if mlist_name in [ s["list_name"] for s in sub_names ]: # continue sub_names.add(mlist_name) return list(sorted(sub_names))
def get_mailman_user(self): # Only cache the user_id, not the whole user instance, because # mailmanclient is not pickle-safe cache_key = "User:%s:mailman_user_id" % self.id user_id = cache.get(cache_key) try: mm_client = get_mailman_client() if user_id is None: mm_user = mm_client.get_user(self.user.email) cache.set(cache_key, mm_user.user_id, None) return mm_user else: return mm_client.get_user(user_id) except (HTTPError, MailmanConnectionError): return None
def set_mailman_id(self): try: client = get_mailman_client() mm_user = client.get_user(self.address) except HTTPError as e: if e.code == 404: return # User not found in Mailman raise MailmanConnectionError(e) # normalize all possible error types except ValueError as e: # This smells like a badly formatted email address (saw it in the wild) logger.warning( "Invalid response when getting user %s from Mailman", self.address) return # Ignore it self.mailman_id = mm_user.user_id self.save()
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 = get_mailman_client() 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 process_view(self, request, view_func, view_args, view_kwargs): if not request.user.is_authenticated(): return if not request.user.email: return # Can this really happen? if "subscribed" in request.session and "user_id" in request.session: return # Already set client = get_mailman_client() try: user = client.get_user(request.user.email) except MailmanConnectionError: return except HTTPError, err: if err.code == 404: user = client.create_user(request.user.email, "") else: return
def update_from_mailman(self): try: client = get_mailman_client() mm_list = client.get_list(self.name) except MailmanConnectionError: return except HTTPError: return # can't update at this time if not mm_list: return converters = { "created_at": dateutil.parser.parse, "archive_policy": lambda p: ArchivePolicy[p].value, } for propname in self.MAILMAN_ATTRIBUTES: try: value = getattr(mm_list, propname) except AttributeError: value = mm_list.settings[propname] if propname in converters: value = converters[propname](value) setattr(self, propname, value) self.save()
def user_profile(request): 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.userprofile except ObjectDoesNotExist: user_profile = UserProfile.objects.create(user=request.user) # 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 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() # Now update the display name in Mailman if mm_user is not None: mm_user.display_name = "%s %s" % ( request.user.first_name, request.user.last_name) mm_user.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 ] # Emails emails = [] if mm_user is not None: for addr in mm_user.addresses: addr = unicode(addr) if addr != request.user.email: emails.append(addr) # 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) # Extract the gravatar_url used by django_gravatar2. The site # administrator could alternatively set this to http://cdn.libravatar.org/ gravatar_url = getattr(settings, 'GRAVATAR_URL', 'http://www.gravatar.com') gravatar_shortname = '.'.join(gravatar_url.split('.')[-2:]).strip('/') context = { 'user_profile' : user_profile, 'form': form, 'emails': emails, 'favorites': favorites, 'flash_messages': flash_messages, 'gravatar_url': gravatar_url, 'gravatar_shortname': gravatar_shortname, } return render(request, "user_profile.html", context)