def add_or_remove_membership(mship, remove=False): mem_id = mship.getId() team = mship.aq_inner.aq_parent proj_id = team.getId() portal = getToolByName(mship, 'portal_url').getPortalObject() listencontainer = portal.projects[proj_id].lists mlists = [] for mlist in listencontainer.objectValues(spec='OpenMailingList'): if ISyncWithProjectMembership.providedBy(mlist): mlists.append(mlist) if not mlists: # no autosync mailing lists; silently fail return for ml in mlists: memlist = IWriteMembershipList(ml) if remove: memlist.unsubscribe(mem_id) else: memlist.subscribe(mem_id)
def migrate(self): if self.is_updated(): return 'already migrated' # set the appropriate list type based on the previous settings # this may need to mark the appropriate interface on the mailing # list as well if self.context.moderated: self.context.list_type = PostModeratedListTypeDefinition elif self.context.closed: self.context.list_type = MembershipModeratedListTypeDefinition else: self.context.list_type = PublicListTypeDefinition # copy over the membership stuff annot = IAnnotations(self.context) listen_annot = annot.get('listen', {}) old_subscribers = listen_annot.get('subscribers', []) # create the new annotations by using current adapters mem_list = IWriteMembershipList(self.context) for subscriber in old_subscribers: mem_list.subscribe(subscriber) # unsubscribe (but leave as allowed senders) those who don't # receive mail nomail = listen_annot.get('norecvmail', []) for allowed_sender in nomail: mem_list.unsubscribe(allowed_sender) # copy over the moderation messages self.mod_post_pending_list = getAdapter(self.context, IPostPendingList, 'pending_pmod_post') for i in self.context.mqueue.objectIds(): (header, body) = splitMail(self.context.mqueue[i]) post = {'header':header, 'body':body} (user_name, user_email) = parseaddr(header.get('from', '')) self.mod_post_pending_list.add(user_email, user_name=user_name, post=post) # creates list managers from moderators and list owner managers = [] managers.append(self.context.list_owner) for moderator in self.context.moderators: managers.append(moderator) self.context.managers = tuple(managers) convert_manager_emails_to_memberids(self.context) # translate archived vocabulary if self.context.archived == 'not archived': self.context.archived = 2 elif self.context.archived == 'plain text': self.context.archived = 1 elif self.context.archived == 'with attachments': self.context.archived = 0 else: return 'error translating archive option' # annotate the list to say the migration completed self.migration_annot.append('policy_migration') return 'successfully migrated'
def import_subscribers(self, subscribers): """ Imports the list of subscriber email addresses """ slist = IWriteMembershipList(self.context) for subscriber, status in subscribers: if status == "subscribed": slist.subscribe(subscriber, send_notify=False) elif status == "allowed": slist.add_allowed_sender(subscriber, send_notify=False)
def listen_featurelet_installed(proj, event): """need to create a default discussion mailing list and subscribe all project members to the list""" proj_id = proj.getId() proj_title = proj.Title().decode('utf-8') ml_id = '%s-discussion' % proj_id address = '%s%s' % (ml_id, getSuffix()) # need to verify that a mailing list with this name isn't already created portal = getToolByName(proj, 'portal_url').getPortalObject() ll = getUtility(IListLookup, context=portal) if ll.getListForAddress(address) is not None: # XXX we'll just silently fail for now, not sure what else we can do # psm maybe? return # XXX we need a request utility request = proj.REQUEST # invokeFactory depends on the title being set in the request ml_title = u'%s discussion' % (proj_title) request.set('title', ml_title) lists_folder = proj.lists.aq_inner lists_folder.invokeFactory(OpenMailingList.portal_type, ml_id) ml = lists_folder[ml_id] ml.mailto = ml_id ms_tool = getToolByName(proj, 'portal_membership') cur_mem_id = unicode(ms_tool.getAuthenticatedMember().getId()) ml.managers = (cur_mem_id,) ml.setDescription(translate(_(u'discussion_list_desc', u'Discussion list for this ${project_noun}, consisting of all ${project_noun} members.', mapping={'project_noun':project_noun()}), context=request)) # http://www.openplans.org/projects/opencore/lists/opencore-dev/archive/2009/04/1239543233615/forum_view from zope.interface import alsoProvides alsoProvides(ml, ISyncWithProjectMembership) notify(ObjectCreatedEvent(ml)) memlist = IWriteMembershipList(ml) cat = getToolByName(portal, 'portal_catalog') teams = getToolByName(portal, 'portal_teams') try: team = teams[proj_id] except KeyError: # if the team doesn't exist # then nobody is on the project yet # so we only need to subscribe the current user memlist.subscribe(cur_mem_id) return active_states = teams.getDefaultActiveStates() team_path = '/'.join(team.getPhysicalPath()) mships = cat(portal_type='OpenMembership', review_state=active_states, path=team_path) for mship in mships: memlist.subscribe(mship.getId)
def handle_request(self, target=None, fields=None): # Get the tool used to normalize strings putils = getToolByName(self.context, 'plone_utils') result = self.validate_form(creation=True) if not result: return title, workflow, archive, mailto, managers = result private_archives = "private_list" in self.request.form sync_project_membership = "sync_project_membership" in self.request.form # Try to create a mailing list using the mailto address to see if it's going to be valid lists_folder = self.context try: lists_folder.invokeFactory(OpenMailingList.portal_type, mailto) except BadRequest: self.errors['mailto'] = _(u'list_create_duplicate_error', u'The requested list prefix is already taken.') self.add_status_message(_(u'psm_correct_errors_below', u'Please correct the errors indicated below.')) return list = lists_folder._getOb(mailto) list.managers = tuple(managers) self._assign_local_roles_to_managers(list) list.setDescription(unicode(self.request.form.get('description',''), 'utf-8')) old_workflow_type = list.list_type new_workflow_type = workflow_to_mlist_type(workflow) notify(ListTypeChanged(list, old_workflow_type.list_marker, new_workflow_type.list_marker)) list.archived = archive list.private_archives = private_archives if sync_project_membership: alsoProvides(list, ISyncWithProjectMembership) self.template = None #subscribe user to list sub_list = IWriteMembershipList(list) current_user = unicode(self.loggedinmember.getId()) sub_list.subscribe(current_user) s_message_mapping = {'title': title} s_message = _(u'list_created', u'"${title}" has been created.', mapping=s_message_mapping) self.add_status_message(s_message) list.reindexObject() self.redirect(list.absolute_url())
def __init__(self, context, request): super(ModerationView, self).__init__(context, request) self.mem_list = IWriteMembershipList(context) annot = IAnnotations(self.context) self.listen_annot = annot.setdefault(PROJECTNAME, OOBTree()) self.mod_post_pending_list = getAdapter(context, IPostPendingList, 'pending_mod_post') self.pmod_post_pending_list = getAdapter(context, IPostPendingList, 'pending_pmod_post') self.sub_pending_list = getAdapter(context, IMembershipPendingList, 'pending_sub_mod_email')
def __call__(self): sub_action = self.request.get('subscribe_member', None) unsub_action = self.request.get('unsubscribe_member', None) email_action = self.request.get('subscribe_email', None) self.request.set('enable_border', True) self.errors = errors = {} logged_in_mem = self._get_logged_in_user() self.user_logged_in = False if logged_in_mem: self.user_email = lookup_email(logged_in_mem.getId(), self.context) self.user_logged_in = True else: #XXX what should this be? self.user_email = '' self.mem_list = IWriteMembershipList(self.context) # the appropriate sub_policy needs to be instantiated # depending on list type self.sub_policy = getAdapter(self.context, IUserTTWMembershipPolicy) if sub_action: self.subscribe() elif unsub_action: self.unsubscribe() elif email_action: address = self.request.get('email_address', None) if not address: errors['email_address'] = _('An email address is required') elif EMAIL_RE.match(address) is None: errors['email_address'] = _('This email address is invalid') elif self.mem_list.is_subscribed(address): errors['email_address'] = \ _('This email address is already subscribed') else: # everything is OK, send a request mail the # appropriate sub_policy needs to be instantiated # depending on list type sub_policy_for_email = getAdapter(self.context, IUserEmailMembershipPolicy) ret = sub_policy_for_email.enforce({'email':address, 'subject':'subscribe'}) if ret == MEMBERSHIP_ALLOWED: # make user a subscriber self.mem_list.subscribe(address) self.request.set('portal_status_message', 'Email subscribed') elif ret == MEMBERSHIP_DEFERRED: self.request.set('portal_status_message', 'Subscription request sent') else: self.request.set('portal_status_message', 'Bad email address') # Blank the email field to avoid the postback self.request.set('email_address', '') self.request.set('subscribe_email', '') return self.index()
def add_allowed_sender(self, email): IWriteMembershipList(self.context).add_allowed_sender(email)
class MailingListView(BrowserView): """A basic view of a mailing list""" def __call__(self): sub_action = self.request.get('subscribe_member', None) unsub_action = self.request.get('unsubscribe_member', None) email_action = self.request.get('subscribe_email', None) self.request.set('enable_border', True) self.errors = errors = {} logged_in_mem = self._get_logged_in_user() self.user_logged_in = False if logged_in_mem: self.user_email = lookup_email(logged_in_mem.getId(), self.context) self.user_logged_in = True else: #XXX what should this be? self.user_email = '' self.mem_list = IWriteMembershipList(self.context) # the appropriate sub_policy needs to be instantiated # depending on list type self.sub_policy = getAdapter(self.context, IUserTTWMembershipPolicy) if sub_action: self.subscribe() elif unsub_action: self.unsubscribe() elif email_action: address = self.request.get('email_address', None) if not address: errors['email_address'] = _('An email address is required') elif EMAIL_RE.match(address) is None: errors['email_address'] = _('This email address is invalid') elif self.mem_list.is_subscribed(address): errors['email_address'] = \ _('This email address is already subscribed') else: # everything is OK, send a request mail the # appropriate sub_policy needs to be instantiated # depending on list type sub_policy_for_email = getAdapter(self.context, IUserEmailMembershipPolicy) ret = sub_policy_for_email.enforce({'email':address, 'subject':'subscribe'}) if ret == MEMBERSHIP_ALLOWED: # make user a subscriber self.mem_list.subscribe(address) self.request.set('portal_status_message', _(u'list_email_subscribed_status_msg', u'Email subscribed')) elif ret == MEMBERSHIP_DEFERRED: self.request.set('portal_status_message', _(u'list_subscription_request_sent_status_msg', u'Subscription request sent')) else: self.request.set('portal_status_message', _(u'list_bad_email_address_status_msg', u'Bad email address')) # Blank the email field to avoid the postback self.request.set('email_address', '') self.request.set('subscribe_email', '') return self.index() def Title(self): return encode(self.context.title, self.context) def Description(self): return encode(self.context.description, self.context) def address(self): if not self.context.mailto: return u'' return obfct_de(encode(self.context.mailto, self.context)) def archived(self): archived = self.context.archived vocab = archiveOptionsVocabulary(self.context) return vocab.getTerm(archived).token + '. ' def is_archived(self): return self.context._is_archived() def list_managers(self): managers = [] creator = self.context.Creator() for manager in self.context.managers: if manager == creator: managers.append('%s (creator)' % manager) else: managers.append(manager) return managers def list_title(self): return self.context.Title() def list_type(self): list_type = self.context.list_type if list_type is None: return _(u'list_type_not_set', u'List Type not set') return '%s. %s' % (list_type.title, list_type.description) def subscribe_keyword(self): # Mailboxer stores the subject line keyword used for subscribing as # a property return self.context.getValueFor('subscribe') def unsubscribe_keyword(self): # Mailboxer stores the subject line keyword used for unsubscribing as # a property return self.context.getValueFor('unsubscribe') def subscribe(self): req = {'action':'subscribe', 'email':self.user_email} if self.user_logged_in: req['use_logged_in_user'] = True ret = self.sub_policy.enforce(req) if ret == MEMBERSHIP_ALLOWED: self.mem_list.subscribe(self.user_email) self.request.set('portal_status_message', _(u'list_have_been_subscribed_status_msg', u'You have been subscribed')) pass elif ret == MEMBERSHIP_DEFERRED: self.request.set('portal_status_message', _(u'list_subscription_pending_moderation_status_msg', u"Your subscription request is pending moderation by the list manager.")) def unsubscribe(self): self.mem_list.unsubscribe(self.user_email) self.request.set('portal_status_message', _(u'list_have_been_unsubscribed_status_msg', u"You have been unsubscribed")) def _get_logged_in_user(self): mtool = getToolByName(self.context, 'portal_membership') return mtool.getAuthenticatedMember() def isSubscribed(self): if self.user_email: return self.mem_list.is_subscribed(self.user_email) else: return False def isPending(self): annot = IAnnotations(self.context) sub_mod_pending_list = getAdapter(self.context, IMembershipPendingList, 'pending_sub_mod_email') return sub_mod_pending_list.is_pending(self.user_email) def canSubscribe(self): return _checkPermission(SubscribeSelf, self.context) def manager_email(self): if not self.context.manager_email: return u'' return obfct_de(self.context.manager_email)
def __init__(self, context, request): super(ManageMembersView, self).__init__(context, request) self.policy = getAdapter(context, IManagerTTWMembershipPolicy) self.mem_list = IWriteMembershipList(context)
class ManageMembersView(BrowserView): """A basic view of displaying subscribed members and allowed senders """ def __init__(self, context, request): super(ManageMembersView, self).__init__(context, request) self.policy = getAdapter(context, IManagerTTWMembershipPolicy) self.mem_list = IWriteMembershipList(context) def __call__(self): if not self.request.get('save', None): return self.index() d = self.request.form self.errors = '' to_remove = [] subscribed_list = set() wassubscribed_list = set() for name, value in d.items(): if name.lower() == 'save' and value.lower() == 'save changes': continue valuetype, name = name.split('_', 1) if valuetype == 'remove': to_remove.append(name.decode('utf-8')) elif valuetype == 'subscribed': subscribed_list.add(name.decode('utf-8')) elif valuetype == 'wassubscribed': wassubscribed_list.add(name.decode('utf-8')) to_subscribe = subscribed_list - wassubscribed_list to_unsubscribe = wassubscribed_list - subscribed_list self._remove(to_remove) self._subscribe(to_subscribe) self._unsubscribe(to_unsubscribe) psm = "" to_add = d.get('add_email', None).strip() if to_add: subscribed = d.get('add_subscribed', None) if self._add(to_add, subscribed): psm += 'Added: %s. ' % to_add else: psm += 'Bad user or email address: %s. ' % to_add if to_remove: psm += _(u'Removed: %s. ') % ', '.join(to_remove) if to_subscribe: psm += _(u'Subscribed: %s. ') % ', '.join(to_subscribe) if to_unsubscribe: psm += 'Unsubscribed: %s. ' % ', '.join(to_unsubscribe) if psm: context = aq_inner(self.context) plone_utils = getToolByName(context, 'plone_utils') plone_utils.addPortalMessage(psm) # since this means that we've been posted to # we should redirect self.request.response.redirect(self.nextURL()) def nextURL(self): return '%s/%s' % (self.context.absolute_url(), self.__name__) def can_subscribe_others(self): return False def _add(self, user, subscribed, subscribe_directly=False): request = {'action': 'add_allowed_sender', 'email': user} policy_result = self.policy.enforce(request) if policy_result == MEMBERSHIP_ALLOWED: self.mem_list.add_allowed_sender(user) elif policy_result == MEMBERSHIP_DENIED: return False if subscribed: request = {'action': 'subscribe', 'email': user} if subscribe_directly and self.can_subscribe_others(): self.mem_list.subscribe(user) else: result = self.policy.enforce(request) if result == MEMBERSHIP_ALLOWED: self.mem_list.subscribe(user) return True def _remove(self, remove_list): for user in remove_list: if self.mem_list.is_subscribed(user): request = {'action': 'unsubscribe', 'email':user} else: request = {'action': 'remove_allowed_sender', 'email':user} if self.policy.enforce(request) == MEMBERSHIP_ALLOWED: self.mem_list.remove_allowed_sender(user) def _subscribe_user_directly(self, user): return False def _subscribe(self, add_list): can_subscribe_others = self.can_subscribe_others() for user in add_list: if can_subscribe_others and self._subscribe_user_directly(user): self.mem_list.subscribe(user) continue request = {'action': 'subscribe', 'email': user} policy_result = self.policy.enforce(request) if policy_result == MEMBERSHIP_ALLOWED: self.mem_list.subscribe(user) def _unsubscribe(self, remove_list): for user in remove_list: request = {'action': 'unsubscribe', 'email': user} if self.policy.enforce(request) == MEMBERSHIP_ALLOWED: self.mem_list.unsubscribe(user) def Title(self): return _(u'Manage Allowed Senders') def Description(self): return _(u'Manage Allowed Senders') def allowed_senders_data(self): return self.mem_list.allowed_senders_data def is_subscribed(self, user): return self.mem_list.is_subscribed(user) def pending_status(self, user): annot = IAnnotations(self.context) listen_annot = annot.setdefault(PROJECTNAME, OOBTree()) subscribe_pending_list = getAdapter(self.context, IMembershipPendingList, 'pending_sub_email') unsubscribe_pending_list = getAdapter(self.context, IMembershipPendingList, 'pending_unsub_email') sub_mod_pending_list = getAdapter(self.context, IMembershipPendingList, 'pending_sub_mod_email') email_address = is_email(user) and user or lookup_email(user, self.context) inlist = lambda lst: lst.is_pending(email_address) status = lambda msg, lst: msg + lst.get_pending_time(email_address) status_msg = '' if inlist(subscribe_pending_list): status_msg += status('subscription pending user confirmation: ', subscribe_pending_list) if inlist(unsubscribe_pending_list): status_msg += status('unsubscription pending user confirmation: ', unsubscribe_pending_list) if inlist(sub_mod_pending_list): status_msg += status('subscription pending manager moderation: ', sub_mod_pending_list) return status_msg
def migrate(self): if self.is_updated(): return _(u'already migrated') # set the appropriate list type based on the previous settings # this may need to mark the appropriate interface on the mailing # list as well if self.context.moderated: self.context.list_type = PostModeratedListTypeDefinition elif self.context.closed: self.context.list_type = MembershipModeratedListTypeDefinition else: self.context.list_type = PublicListTypeDefinition # copy over the membership stuff annot = IAnnotations(self.context) listen_annot = annot.get('listen', {}) old_subscribers = listen_annot.get('subscribers', []) # create the new annotations by using current adapters mem_list = IWriteMembershipList(self.context) for subscriber in old_subscribers: mem_list.subscribe(subscriber) # unsubscribe (but leave as allowed senders) those who don't # receive mail nomail = listen_annot.get('norecvmail', []) for allowed_sender in nomail: mem_list.unsubscribe(allowed_sender) # copy over the moderation messages self.mod_post_pending_list = getAdapter(self.context, IPostPendingList, 'pending_pmod_post') for i in self.context.mqueue.objectIds(): (header, body) = splitMail(self.context.mqueue[i]) post = {'header': header, 'body': body} (user_name, user_email) = parseaddr(header.get('from', '')) self.mod_post_pending_list.add(user_email, user_name=user_name, post=post) # creates list managers from moderators and list owner managers = [] managers.append(self.context.list_owner) for moderator in self.context.moderators: managers.append(moderator) self.context.managers = tuple(managers) convert_manager_emails_to_memberids(self.context) # translate archived vocabulary if self.context.archived == 'not archived': self.context.archived = 2 elif self.context.archived == 'plain text': self.context.archived = 1 elif self.context.archived == 'with attachments': self.context.archived = 0 else: return _(u'error translating archive option') # annotate the list to say the migration completed self.migration_annot.append('policy_migration') return _(u'successfully migrated')
def __init__(self, context): BaseImportExport.__init__(self, context) self.mem_list = IWriteMembershipList(context)
def __init__(self, context): self.context = context annot = IAnnotations(context) self.listen_annot = annot.setdefault(PROJECTNAME, OOBTree()) self.mail_sender = ISendMail(context) self.mem_list = IWriteMembershipList(context)
def became_allowed_sender(event): """ This function should ensure that all other pending allowed sender lists that the other policy adapters depend on are in sync. set up the phony mailing list and policies >>> from Products.listen.content.tests import DummyAnnotableList >>> from Products.listen.content.tests import DummyMembershipTool >>> from Products.listen.extras.tests import TestMailingList >>> from Products.listen.content.tests import DummyMember >>> from Products.listen.config import POST_DEFERRED, MEMBERSHIP_DEFERRED >>> ml = TestMailingList() >>> from zope.interface import alsoProvides >>> from Products.listen.interfaces import IPublicList >>> alsoProvides(ml, IPublicList) >>> mails_to_list = [] >>> def listMail(post): ... mails_to_list.append(post) >>> ml.listMail = listMail >>> from Products.listen.interfaces import IMailingList >>> dtool = DummyMembershipTool('foo') >>> dtool.result = None >>> ml.portal_membership = dtool >>> from Products.listen.content import WriteMembershipList >>> mlist = WriteMembershipList(ml) >>> from zope.component import getAdapter >>> from zope.component import provideAdapter >>> from Products.listen.interfaces import IEmailPostPolicy >>> from Products.listen.interfaces import IUserEmailMembershipPolicy >>> from Products.listen.content import PublicEmailPostPolicy >>> from Products.listen.content import UserMembershipPolicy >>> postpolicy = getAdapter(ml, IEmailPostPolicy) >>> mempolicy = getAdapter(ml, IUserEmailMembershipPolicy) send a subscribe email to get on the pending list >>> request = dict(email='*****@*****.**', ... subject='subscribe') >>> mempolicy.enforce(request) == MEMBERSHIP_DEFERRED True now submit a post to get on that pending list >>> request = dict(email='*****@*****.**', ... post=dict(header={}, body='there is only zul!')) >>> postpolicy.enforce(request) == POST_DEFERRED True now add the email as an allowed sender >>> mlist.add_allowed_sender('*****@*****.**') make sure he's not on the allowed sender pending list >>> from zope.annotation.interfaces import IAnnotations >>> annot = IAnnotations(ml) >>> listen_annot = annot['listen'] >>> a_s_list = listen_annot['a_s_pending_sub_email'] >>> '*****@*****.**' in a_s_list False verify that the post is no longer pending and has been sent out >>> post_list = listen_annot['pending_mod_post'] >>> '*****@*****.**' in post_list False >>> 'there is only zul!' in mails_to_list[0]['Mail'] True try with a mem-moderated list policy >>> from zope.interface import directlyProvides >>> from Products.listen.interfaces import IMembershipModeratedList >>> directlyProvides(ml, IMembershipModeratedList) >>> postpolicy = getAdapter(ml, IEmailPostPolicy) >>> request = dict(email='*****@*****.**', ... post=dict(header={}, body='there is only zui!')) >>> postpolicy.enforce(request) == POST_DEFERRED True >>> mlist.add_allowed_sender('*****@*****.**') >>> '*****@*****.**' in post_list False >>> 'there is only zui!' in mails_to_list[1]['Mail'] True make someone who is pending subscription moderation an allowed sender and make sure they get automatically subscribed >>> from Products.listen.interfaces import IMembershipPendingList >>> sub_mod_pending_list = getAdapter(ml, IMembershipPendingList, 'pending_sub_mod_email') >>> sub_mod_pending_list.add('*****@*****.**') >>> mlist.add_allowed_sender('*****@*****.**') >>> mlist.is_subscribed('*****@*****.**') True now try subscribing a member who is pending subscription moderation >>> sub_mod_pending_list.add('*****@*****.**') >>> mlist.subscribe('*****@*****.**') >>> mlist.is_subscribed('*****@*****.**') True """ email = event.email context = event.context # clean up pending subscription pend_list = getAdapter(context, IPostPendingList, 'a_s_pending_sub_email') pend_list.remove(email) # if member is waiting for moderation to become a subscriber # then subscribe member sub_pending_list = getAdapter(context, IMembershipPendingList, 'pending_sub_mod_email') if sub_pending_list.is_pending(email): mlist = IWriteMembershipList(context) mail_sender = ISendMail(context) sub_pending_list.remove(email) mlist.subscribe(email) mail_sender.user_welcome(email, email) # clean up pending posts post_mod_list = getAdapter(context, IPostPendingList, 'pending_mod_post') # XXX currently expecting one post, # this is not the case for Post Moderated Lists # send the post for the user to the list posts = post_mod_list.get_posts(email) # uniquify posts post_dict = {} for p in posts: post_dict[p['body']] = p['header'] posts = [dict(header=v, body=k) for k,v in post_dict.iteritems()] send_pending_posts(context, posts) post_mod_list.remove(email)
class MailingListView(BrowserView): """A basic view of a mailing list""" def __call__(self): sub_action = self.request.get('subscribe_member', None) unsub_action = self.request.get('unsubscribe_member', None) email_action = self.request.get('subscribe_email', None) self.request.set('enable_border', True) self.errors = errors = {} logged_in_mem = self._get_logged_in_user() self.user_logged_in = False if logged_in_mem: self.user_email = lookup_email(logged_in_mem.getId(), self.context) self.user_logged_in = True else: #XXX what should this be? self.user_email = '' self.mem_list = IWriteMembershipList(self.context) # the appropriate sub_policy needs to be instantiated # depending on list type self.sub_policy = getAdapter(self.context, IUserTTWMembershipPolicy) if sub_action: self.subscribe() elif unsub_action: self.unsubscribe() elif email_action: address = self.request.get('email_address', None) if not address: errors['email_address'] = _('An email address is required') elif EMAIL_RE.match(address) is None: errors['email_address'] = _('This email address is invalid') elif self.mem_list.is_subscribed(address): errors['email_address'] = \ _('This email address is already subscribed') else: # everything is OK, send a request mail the # appropriate sub_policy needs to be instantiated # depending on list type sub_policy_for_email = getAdapter(self.context, IUserEmailMembershipPolicy) ret = sub_policy_for_email.enforce({'email':address, 'subject':'subscribe'}) if ret == MEMBERSHIP_ALLOWED: # make user a subscriber self.mem_list.subscribe(address) self.request.set('portal_status_message', 'Email subscribed') elif ret == MEMBERSHIP_DEFERRED: self.request.set('portal_status_message', 'Subscription request sent') else: self.request.set('portal_status_message', 'Bad email address') # Blank the email field to avoid the postback self.request.set('email_address', '') self.request.set('subscribe_email', '') return self.index() def Title(self): return encode(self.context.title, self.context) def Description(self): return encode(self.context.description, self.context) def address(self): if not self.context.mailto: return u'' return obfct_de(encode(self.context.mailto, self.context)) def archived(self): archived = self.context.archived vocab = archiveOptionsVocabulary(self.context) return vocab.getTerm(archived).token + '. ' def is_archived(self): return self.context._is_archived() def list_managers(self): managers = [] creator = self.context.Creator() for manager in self.context.managers: if manager == creator: managers.append('%s (creator)' % manager) else: managers.append(manager) return managers def list_title(self): return self.context.Title() def list_type(self): list_type = self.context.list_type if list_type is None: return _(u'List Type not set') return '%s. %s' % (list_type.title, list_type.description) def subscribe_keyword(self): # Mailboxer stores the subject line keyword used for subscribing as # a property return self.context.getValueFor('subscribe') def unsubscribe_keyword(self): # Mailboxer stores the subject line keyword used for unsubscribing as # a property return self.context.getValueFor('unsubscribe') def subscribe(self): req = {'action':'subscribe', 'email':self.user_email} if self.user_logged_in: req['use_logged_in_user'] = True ret = self.sub_policy.enforce(req) if ret == MEMBERSHIP_ALLOWED: self.mem_list.subscribe(self.user_email) self.request.set('portal_status_message', 'You have been subscribed') pass elif ret == MEMBERSHIP_DEFERRED: self.request.set('portal_status_message', 'Your subscription request is pending moderation ' 'by the list manager.') def unsubscribe(self): self.mem_list.unsubscribe(self.user_email) self.request.set('portal_status_message', 'You have been unsubscribed') def _get_logged_in_user(self): mtool = getToolByName(self.context, 'portal_membership') return mtool.getAuthenticatedMember() def isSubscribed(self): if self.user_email: return self.mem_list.is_subscribed(self.user_email) else: return False def isPending(self): annot = IAnnotations(self.context) sub_mod_pending_list = getAdapter(self.context, IMembershipPendingList, 'pending_sub_mod_email') return sub_mod_pending_list.is_pending(self.user_email) def canSubscribe(self): return _checkPermission(SubscribeSelf, self.context) def manager_email(self): if not self.context.manager_email: return u'' return obfct_de(self.context.manager_email)
def __call__(self): sub_action = self.request.get('subscribe_member', None) unsub_action = self.request.get('unsubscribe_member', None) email_action = self.request.get('subscribe_email', None) self.request.set('enable_border', True) self.errors = errors = {} logged_in_mem = self._get_logged_in_user() self.user_logged_in = False if logged_in_mem: self.user_email = lookup_email(logged_in_mem.getId(), self.context) self.user_logged_in = True else: #XXX what should this be? self.user_email = '' self.mem_list = IWriteMembershipList(self.context) # the appropriate sub_policy needs to be instantiated # depending on list type self.sub_policy = getAdapter(self.context, IUserTTWMembershipPolicy) if sub_action: self.subscribe() elif unsub_action: self.unsubscribe() elif email_action: address = self.request.get('email_address', None) if not address: errors['email_address'] = _('An email address is required') elif EMAIL_RE.match(address) is None: errors['email_address'] = _('This email address is invalid') elif self.mem_list.is_subscribed(address): errors['email_address'] = \ _('This email address is already subscribed') else: # everything is OK, send a request mail the # appropriate sub_policy needs to be instantiated # depending on list type sub_policy_for_email = getAdapter(self.context, IUserEmailMembershipPolicy) ret = sub_policy_for_email.enforce({'email':address, 'subject':'subscribe'}) if ret == MEMBERSHIP_ALLOWED: # make user a subscriber self.mem_list.subscribe(address) self.request.set('portal_status_message', _(u'list_email_subscribed_status_msg', u'Email subscribed')) elif ret == MEMBERSHIP_DEFERRED: self.request.set('portal_status_message', _(u'list_subscription_request_sent_status_msg', u'Subscription request sent')) else: self.request.set('portal_status_message', _(u'list_bad_email_address_status_msg', u'Bad email address')) # Blank the email field to avoid the postback self.request.set('email_address', '') self.request.set('subscribe_email', '') return self.index()
class ManageMembersView(BrowserView): """A basic view of displaying subscribed members and allowed senders """ def __init__(self, context, request): super(ManageMembersView, self).__init__(context, request) self.policy = getAdapter(context, IManagerTTWMembershipPolicy) self.mem_list = IWriteMembershipList(context) def __call__(self): if not self.request.get('save', None): return self.index() d = self.request.form self.errors = '' to_remove = [] subscribed_list = set() wassubscribed_list = set() for name, value in d.items(): if name.lower() == 'save' and value.lower() == 'save changes': continue valuetype, name = name.split('_', 1) if valuetype == 'remove': to_remove.append(name.decode('utf-8')) elif valuetype == 'subscribed': subscribed_list.add(name.decode('utf-8')) elif valuetype == 'wassubscribed': wassubscribed_list.add(name.decode('utf-8')) to_subscribe = subscribed_list - wassubscribed_list to_unsubscribe = wassubscribed_list - subscribed_list self._remove(to_remove) self._subscribe(to_subscribe) self._unsubscribe(to_unsubscribe) psm = "" to_add = d.get('add_email', None).strip() if to_add: subscribed = d.get('add_subscribed', None) if self._add(to_add, subscribed): psm += _(u'add_subscribed_portal_msg', u'Added: ${to_add}. ', mapping={'to_add': to_add}) else: psm += _(u'bad_user_email_portal_msg', u'Bad user or email address: ${to_add}. ', mapping={'to_add': to_add}) if to_remove: psm += _(u'removed_portal_msg', u'Removed: ${to_remove}. ', mapping={'to_remove': to_remove}) if to_subscribe: psm += _(u'subscribed_portal_msg', u'Subscribed: ${to_subscribe}. ', mapping={'to_subscribe': to_subscribe}) if to_unsubscribe: psm += _(u'unsubscribed_portal_msg', u'Unsubscribed: ${to_unsubscribe}. ', mapping={'to_unsubscribe': to_unsubscribe}) if psm: context = aq_inner(self.context) plone_utils = getToolByName(context, 'plone_utils') plone_utils.addPortalMessage(psm) # since this means that we've been posted to # we should redirect self.request.response.redirect(self.nextURL()) def nextURL(self): return '%s/%s' % (self.context.absolute_url(), self.__name__) def can_subscribe_others(self): return False def _add(self, user, subscribed, subscribe_directly=False): request = {'action': 'add_allowed_sender', 'email': user} policy_result = self.policy.enforce(request) if policy_result == MEMBERSHIP_ALLOWED: self.mem_list.add_allowed_sender(user) elif policy_result == MEMBERSHIP_DENIED: return False if subscribed: request = {'action': 'subscribe', 'email': user} if subscribe_directly and self.can_subscribe_others(): self.mem_list.subscribe(user) else: result = self.policy.enforce(request) if result == MEMBERSHIP_ALLOWED: self.mem_list.subscribe(user) return True def _remove(self, remove_list): for user in remove_list: if self.mem_list.is_subscribed(user): request = {'action': 'unsubscribe', 'email': user} else: request = {'action': 'remove_allowed_sender', 'email': user} if self.policy.enforce(request) == MEMBERSHIP_ALLOWED: self.mem_list.remove_allowed_sender(user) def _subscribe_user_directly(self, user): return False def _subscribe(self, add_list): can_subscribe_others = self.can_subscribe_others() for user in add_list: if can_subscribe_others and self._subscribe_user_directly(user): self.mem_list.subscribe(user) continue request = {'action': 'subscribe', 'email': user} policy_result = self.policy.enforce(request) if policy_result == MEMBERSHIP_ALLOWED: self.mem_list.subscribe(user) def _unsubscribe(self, remove_list): for user in remove_list: request = {'action': 'unsubscribe', 'email': user} if self.policy.enforce(request) == MEMBERSHIP_ALLOWED: self.mem_list.unsubscribe(user) def Title(self): return _(u'Manage Allowed Senders') def Description(self): return _(u'Manage Allowed Senders') def allowed_senders_data(self): return self.mem_list.allowed_senders_data def is_subscribed(self, user): return self.mem_list.is_subscribed(user) def pending_status(self, user): annot = IAnnotations(self.context) listen_annot = annot.setdefault(PROJECTNAME, OOBTree()) subscribe_pending_list = getAdapter(self.context, IMembershipPendingList, 'pending_sub_email') unsubscribe_pending_list = getAdapter(self.context, IMembershipPendingList, 'pending_unsub_email') sub_mod_pending_list = getAdapter(self.context, IMembershipPendingList, 'pending_sub_mod_email') email_address = is_email(user) and user or lookup_email( user, self.context) inlist = lambda lst: lst.is_pending(email_address) status = lambda msg, lst: msg + lst.get_pending_time(email_address) status_msg = '' if inlist(subscribe_pending_list): status_msg += status( _(u'subscription pending user confirmation: '), subscribe_pending_list) if inlist(unsubscribe_pending_list): status_msg += status( _(u'unsubscription pending user confirmation: '), unsubscribe_pending_list) if inlist(sub_mod_pending_list): status_msg += status( _(u'subscription pending manager moderation: '), sub_mod_pending_list) return status_msg