def do_update(db): mailinglist = Mailinglist.select_by_address(self.env, mailinglist_emailpart, localpart=True, db=db) if req.args.get('updatepostergroups'): current_statuses = mailinglist.groups() else: current_statuses = mailinglist.individuals() for subname, poster in current_statuses: if req.args.get('updatepostergroups'): updater = partial(mailinglist.update_poster, group=subname) else: updater = partial(mailinglist.update_poster, user=subname) if poster and subname not in sel: updater(poster=False) elif not poster and subname in sel: updater(poster=True)
def get_instance_for_resource(self, resource): if resource.realm != "mailinglist": return None parts = resource.id.split("/") if len(parts) == 0: return None elif len(parts) == 1: from mailinglistplugin.model import Mailinglist return Mailinglist.select_by_address(self.env, parts[0], localpart=True) elif len(parts) == 2: from mailinglistplugin.model import MailinglistConversation return MailinglistConversation(self.env, int(parts[1])) elif len(parts) == 3: if parts[2] == "raw": from mailinglistplugin.model import MailinglistRawMessage return MailinglistRawMessage(self.env, int(parts[2])) else: from mailinglistplugin.model import MailinglistMessage return MailinglistMessage(self.env, int(parts[2]))
def test_add_messages(self): mailinglist = Mailinglist(self.env, emailaddress="LIST1", name="Sample List 1", private=True, postperm="OPEN") mailinglist.insert() mailinglist = Mailinglist(self.env, emailaddress="list2", name="Sample List 2", private=True, postperm="OPEN") mailinglist.insert() for rawmsg in rawmsgs: for listname in ("list1", "list2"): bytes = rawmsg % dict(sender="Jack Sparrow", email="*****@*****.**", list=listname, domain="example.com", subject="Boats", asctime=time.asctime(), id="asdfasdf", body="Need boats.") mailinglist = Mailinglist.select_by_address(self.env, "*****@*****.**" % listname) message = mailinglist.insert_raw_email(bytes) assert len(list(Mailinglist.select(self.env))) == 2 for mailinglist in Mailinglist.select(self.env): for conversation in mailinglist.conversations(): assert conversation.get_first() is not None for message in conversation.messages(): assert message #for attachment in Attachment.select(self.env, 'mailinglistmessage', message.id): # assert attachment mailinglist.delete() assert len(list(Mailinglist.select(self.env))) == 0
def import_project(self, sourcepath, destinationpath, name=None, **kwargs): if name is None: raise KeyError("This importer requires a Trac project to already exist. Use --name to specify its dir name.") env_path = os.path.join(destinationpath, name) mailinglist_name = os.path.basename(sourcepath.rstrip("/")) env = open_environment(env_path) #mailinglist = Mailinglist.select_by_address(env, mailinglist_name, localpart=True) #mailinglist.delete() try: mailinglist = Mailinglist.select_by_address(env, mailinglist_name, localpart=True) except ResourceNotFound: mailinglist = Mailinglist(env, emailaddress=mailinglist_name, name="Imported list", private=True, postperm="MEMBERS", replyto="LIST") mailinglist.insert() mbox = mailbox.Maildir(sourcepath) for mail in mbox: mail.fp.seek(0) mailinglist.insert_raw_email(mail.fp.read())
def read_file(self, mbox_file, metadata=None): mailinglist_name = os.path.basename(mbox_file).rstrip('mbox.gz') if not metadata: metadata = dict(emailaddress=mailinglist_name, name='%s (Imported)' % mailinglist_name, private=True, postperm='MEMBERS', replyto='LIST', date=datetime.utcnow(), individuals=[], groups=[], declines=[]) individuals = metadata.pop('individuals') groups = metadata.pop('groups') declines = metadata.pop('declines') try: mailinglist = Mailinglist.select_by_address(self.env, mailinglist_name, localpart=True) except ResourceNotFound: mailinglist = Mailinglist(self.env, **metadata) try: mailinglist.insert() except Exception, e: self.log.exception(metadata) raise
def do_remove(db): mailinglist = Mailinglist.select_by_address(self.env, mailinglist_emailpart, localpart=True, db=db) for username in sel: mailinglist.unsubscribe(group=username, db=db)
def do_subscribe(db): mailinglist = Mailinglist.select_by_address(self.env, mailinglist_emailpart, localpart=True, db=db) mailinglist.subscribe(group=req.args['groupname'], db=db)
def render_admin_panel(self, req, cat, page, mailinglist_emailpart): req.perm.require('MAILINGLIST_ADMIN') if mailinglist_emailpart: mailinglist = Mailinglist.select_by_address(self.env, mailinglist_emailpart, localpart=True) if req.method == 'POST': if req.args.get('save'): mailinglist.name = req.args.get('name') mailinglist.private = req.args.get('private') == 'PRIVATE' mailinglist.postperm = req.args.get('postperm') mailinglist.replyto = req.args.get('replyto') mailinglist.description = req.args.get('description') if 'TRAC_ADMIN' in req.perm: mailinglist.emailaddress = req.args.get('emailaddress') mailinglist.save_changes() add_notice(req, _('Your changes have been saved.')) req.redirect(req.href.admin(cat, page)) elif req.args.get('cancel'): req.redirect(req.href.admin(cat, page)) elif req.args.get('subscribeuser'): @self.env.with_transaction() def do_subscribe(db): mailinglist = Mailinglist.select_by_address(self.env, mailinglist_emailpart, localpart=True, db=db) mailinglist.subscribe(user=req.args['username'], db=db) add_notice(req, _('The user %s has been subscribed.') % req.args['username']) req.redirect(req.href.admin(cat, page, mailinglist_emailpart)) elif req.args.get('removeusers'): sel = req.args.get('sel') if not sel: raise TracError(_('No users selected')) if not isinstance(sel, list): sel = [sel] @self.env.with_transaction() def do_remove(db): mailinglist = Mailinglist.select_by_address(self.env, mailinglist_emailpart, localpart=True, db=db) for username in sel: mailinglist.unsubscribe(user=username, db=db) add_notice(req, _('The selected users have been unsubscribed.')) req.redirect(req.href.admin(cat, page, mailinglist_emailpart)) elif req.args.get('subscribegroup'): @self.env.with_transaction() def do_subscribe(db): mailinglist = Mailinglist.select_by_address(self.env, mailinglist_emailpart, localpart=True, db=db) mailinglist.subscribe(group=req.args['groupname'], db=db) add_notice(req, _('The group %s has been subscribed.') % req.args['groupname']) req.redirect(req.href.admin(cat, page, mailinglist_emailpart)) elif req.args.get('removegroups'): sel = req.args.get('sel') if not sel: raise TracError(_('No groups selected')) if not isinstance(sel, list): sel = [sel] @self.env.with_transaction() def do_remove(db): mailinglist = Mailinglist.select_by_address(self.env, mailinglist_emailpart, localpart=True, db=db) for username in sel: mailinglist.unsubscribe(group=username, db=db) add_notice(req, _('The selected groups have been unsubscribed.')) req.redirect(req.href.admin(cat, page, mailinglist_emailpart)) elif req.args.get('updatepostergroups') or req.args.get('updateposterusers'): sel = req.args.get('sel') if not sel: sel = [] if not isinstance(sel, list): sel = [sel] @self.env.with_transaction() def do_update(db): mailinglist = Mailinglist.select_by_address(self.env, mailinglist_emailpart, localpart=True, db=db) if req.args.get('updatepostergroups'): current_statuses = mailinglist.groups() else: current_statuses = mailinglist.individuals() for subname, poster in current_statuses: if req.args.get('updatepostergroups'): updater = partial(mailinglist.update_poster, group=subname) else: updater = partial(mailinglist.update_poster, user=subname) if poster and subname not in sel: updater(poster=False) elif not poster and subname in sel: updater(poster=True) add_notice(req, _('Posters have been updated.')) req.redirect(req.href.admin(cat, page, mailinglist_emailpart)) Chrome(self.env).add_wiki_toolbars(req) if self.env.is_component_enabled('simplifiedpermissionsadminplugin.simplifiedpermissions.SimplifiedPermissions'): from simplifiedpermissionsadminplugin.simplifiedpermissions import SimplifiedPermissions # groups is used for subscription, so it should not have subscribed groups in it groups = set(SimplifiedPermissions(self.env).groups) - set([subscribed_group for subscribed_group, group_poster in mailinglist.groups()]) else: groups = None data = {'view': 'detail', 'mailinglist': mailinglist, 'groups': groups, 'email_domain': MailinglistSystem(self.env).email_domain} else: if req.method == 'POST': if req.args.get('add') and req.args.get('emailaddress'): emailaddress = req.args['emailaddress'].lower() try: mailinglist = Mailinglist.select_by_address(self.env, emailaddress, localpart=True) except ResourceNotFound: mailinglist = Mailinglist(self.env, name=req.args['name']) mailinglist.private = req.args.get('private') == 'PRIVATE' mailinglist.postperm = req.args.get('postperm') mailinglist.replyto = req.args.get('replyto') mailinglist.emailaddress = req.args.get('emailaddress') mailinglist.insert() add_notice(req, _('The mailinglist "%(addr)s" has been ' 'added.', addr=mailinglist.addr())) req.redirect(req.href.admin(cat, page)) else: raise TracError(_('Mailinglist with email address %(emailaddress)s already exists.', emailaddress=emailaddress)) # Remove mailinglists elif req.args.get('remove'): req.perm.require('TRAC_ADMIN') sel = req.args.get('sel') if not sel: raise TracError(_('No mailinglist selected')) if not isinstance(sel, list): sel = [sel] @self.env.with_transaction() def do_remove(db): for email in sel: mailinglist = Mailinglist.select_by_address(self.env, email, localpart=True, db=db) mailinglist.delete(db=db) add_notice(req, _('The selected mailinglists have been ' 'removed.')) req.redirect(req.href.admin(cat, page)) mailinglists = Mailinglist.select(self.env) data = {'view': 'list', 'mailinglists': mailinglists, 'email_domain': MailinglistSystem(self.env).email_domain} return ('mailinglist_admin.html', data)
def do_remove(db): for email in sel: mailinglist = Mailinglist.select_by_address(self.env, email, localpart=True, db=db) mailinglist.delete(db=db)
def process_request(self, req): offset = req.args.get("offset",0) page = req.args.get('page', 1) try: offset = int(offset) except: raise TracError(_('Invalid offset used: %(offset)s', offset=offset)) try: page = int(page) except: raise TracError(_('Invalid page used: %(page)s', page=page)) offset = (page - 1) * self.limit add_stylesheet(req, 'mailinglist/css/mailinglist.css') add_javascript(req, 'mailinglist/mailinglist.js') mailinglists = [m for m in Mailinglist.select(self.env) if "MAILINGLIST_VIEW" in req.perm(m.resource)] data = {"mailinglists": mailinglists, "offset": offset, "limit": self.limit} if req.method == 'POST': if 'subscribe' in req.args: subscribe = True unsubscribe = False mailinglist_email = req.args.get('subscribe') elif 'unsubscribe' in req.args: subscribe = False unsubscribe = True mailinglist_email = req.args.get('unsubscribe') else: # at the moment we only post subscription info to # mailing list page - so if there is none in req.args we # can just redirect to mailing list page req.redirect(req.href.mailinglist()) # get mailing list object and check permissions mailinglist = Mailinglist.select_by_address(self.env, mailinglist_email, localpart=True) req.perm(mailinglist.resource).require("MAILINGLIST_VIEW") if subscribe: mailinglist.subscribe(user=req.authname) # subscribe does not return a value to indicate if it # was successful, so we have to explicitly check if mailinglist.is_subscribed(req.authname): add_notice(req, _('You have been subscribed to %s.' % mailinglist.name)) else: add_notice(req, _('Unable to subscribe to %s.' % mailinglist.name)) elif unsubscribe: mailinglist.unsubscribe(user=req.authname) # unsubscribe does not return a value to indicate if it # was successful, so we have to explicitly check if not mailinglist.is_subscribed(req.authname): add_notice(req, _('You have been unsubscribed from %s.' % mailinglist.name)) else: add_notice(req, _('Unable to unsubscribe from %s.' % mailinglist.name)) if req.path_info.endswith('/mailinglist'): # overview mailing list page req.redirect(req.href.mailinglist()) elif 'conversationid' in req.args: # individual mailing list conversation log req.redirect(req.href.mailinglist(mailinglist_email, req.args['conversationid'])) else: # individual mailing list homepage req.redirect(req.href.mailinglist(mailinglist_email)) #for mailinglist in mailinglists: # add_ctxtnav(req, # _("List: %s") % mailinglist.name, # req.href.mailinglist(mailinglist.emailaddress)) if 'messageid' in req.args: message = MailinglistMessage(self.env, req.args['messageid']) # leaks the subject of the email in the error, wonder if # that's a problem... req.perm(message.resource).require("MAILINGLIST_VIEW") if req.args.get('format') == "raw": req.send_header('Content-Disposition', 'attachment') req.send_response(200) content = message.raw.bytes req.send_header('Content-Type', 'application/mbox') req.send_header('Content-Length', len(content)) req.end_headers() if req.method != 'HEAD': req.write(content) return context = Context.from_request(req, message.resource) data['message'] = message data['attachments'] = AttachmentModule(self.env).attachment_data(context) add_link(req, 'up', get_resource_url(self.env, message.conversation.resource, req.href, offset=data['offset']), _("Back to conversation")) prevnext_nav(req, _("Newer message"), _("Older message"), _("Back to conversation")) raw_href = get_resource_url(self.env, message.resource, req.href, format='raw') add_link(req, 'alternate', raw_href, _('mbox'), "application/mbox") if 'MAILINGLIST_ADMIN' in req.perm: add_ctxtnav(req, tag.a(tag.i(class_="fa fa-cog"), ' Manage List', href=req.href.admin('mailinglist', 'lists', message.conversation.mailinglist.emailaddress), title='Manage and subscribe users to the %s mailing list' % message.conversation.mailinglist.name)) return 'mailinglist_message.html', data, None if 'conversationid' in req.args: conversation = MailinglistConversation(self.env, req.args['conversationid']) # also leaks the subject of the first email in the error message req.perm(conversation.resource).require("MAILINGLIST_VIEW") data['conversation'] = conversation data['attachmentselect'] = partial(Attachment.select, self.env) results = Paginator(conversation.messages(), page - 1, self.limit) if results.has_next_page: next_href = get_resource_url(self.env, conversation.resource, req.href, page=page + 1) add_link(req, 'next', next_href, _('Next Page')) if results.has_previous_page: prev_href = get_resource_url(self.env, conversation.resource, req.href, page=page - 1) add_link(req, 'prev', prev_href, _('Previous Page')) shown_pages = results.get_shown_pages() pagedata = [{'href': get_resource_url(self.env, conversation.resource, req.href, page=page), 'class': None, 'string': str(page), 'title': _('Page %(num)d', num=page)} for page in shown_pages] results.shown_pages = pagedata results.current_page = {'href': None, 'class': 'current', 'string': str(results.page + 1), 'title': None} data['paginator'] = results add_link(req, 'up', get_resource_url(self.env, conversation.mailinglist.resource, req.href, offset=data['offset']), _("List of conversations")) prevnext_nav(req, _("Newer conversation"), _("Older conversation"), _("Back to list of conversations")) if 'MAILINGLIST_ADMIN' in req.perm: add_ctxtnav(req, tag.a(tag.i(class_="fa fa-cog"), ' Manage List', href=req.href.admin('mailinglist', 'lists', conversation.mailinglist.emailaddress), title='Manage and subscribe users to the %s mailing list' % conversation.mailinglist.name)) # Check if user is already subscribed to mailing list # and add the appropriate subscribe / unsubscribe ribbon option if conversation.mailinglist.is_subscribed(req.authname): add_ctxtnav(req, tag.form(tag.input(tag.a(tag.i(class_='fa fa-eye-slash'), ' Unsubscribe', title='Unsubscribe from the %s mailing list' % conversation.mailinglist.name, id='subscribe-link'), name='unsubscribe', value=conversation.mailinglist.emailaddress, class_='hidden'), method_='post', action='', id='subscribe-form', class_='hidden')) else: add_ctxtnav(req, tag.form(tag.input(tag.a(tag.i(class_='fa fa-eye'), ' Subscribe', title='Subscribe to the %s mailing list' % conversation.mailinglist.name, id='subscribe-link'), name='subscribe', value=conversation.mailinglist.emailaddress, class_='hidden'), method_='post', action='', id='subscribe-form', class_='hidden')) return 'mailinglist_conversation.html', data, None elif 'listname' in req.args: mailinglist = Mailinglist.select_by_address(self.env, req.args['listname'], localpart=True) # leaks the name of the mailinglist req.perm(mailinglist.resource).require("MAILINGLIST_VIEW") data['mailinglist'] = mailinglist results = Paginator(mailinglist.conversations(), page - 1, self.limit) if results.has_next_page: next_href = get_resource_url(self.env, mailinglist.resource, req.href, page=page + 1) add_link(req, 'next', next_href, _('Next Page')) if results.has_previous_page: prev_href = get_resource_url(self.env, mailinglist.resource, req.href, page=page - 1) add_link(req, 'prev', prev_href, _('Previous Page')) shown_pages = results.get_shown_pages() pagedata = [{'href': get_resource_url(self.env, mailinglist.resource, req.href, page=page), 'class': None, 'string': str(page), 'title': _('Page %(num)d', num=page)} for page in shown_pages] results.shown_pages = pagedata results.current_page = {'href': None, 'class': 'current', 'string': str(results.page + 1), 'title': None} data['paginator'] = results if data['offset'] + data['limit'] < mailinglist.count_conversations(): add_link(req, 'next', get_resource_url(self.env, mailinglist.resource, req.href, offset=data['offset']+data['limit']), _("Older conversations")) if offset > 0: add_link(req, 'prev', get_resource_url(self.env, mailinglist.resource, req.href, offset=data['offset']-data['limit']), _("Newer conversations")) add_link(req, 'up', req.href.mailinglist(), _("List of mailinglists")) prevnext_nav(req, _("Newer conversations"), _("Older conversations"), ("Back to Mailinglists")) if 'MAILINGLIST_ADMIN' in req.perm: add_ctxtnav(req, tag.a(tag.i(class_="fa fa-cog"), ' Manage List', href=req.href.admin('mailinglist', 'lists', mailinglist.emailaddress), title='Manage and subscribe users to the %s mailing list' % mailinglist.name)) # Check if user is already subscribed to mailing list # and add the appropriate subscribe / unsubscribe ribbon option if mailinglist.is_subscribed(req.authname): add_ctxtnav(req, tag.form(tag.input(tag.a(tag.i(class_='fa fa-eye-slash'), ' Unsubscribe', title='Unsubscribe from the %s mailing list' % mailinglist.name, id='subscribe-link'), name='unsubscribe', value=mailinglist.emailaddress, class_='hidden'), method_='post', action='', id='subscribe-form', class_='hidden')) else: add_ctxtnav(req, tag.form(tag.input(tag.a(tag.i(class_='fa fa-eye'), ' Subscribe', title='Subscribe to the %s mailing list' % mailinglist.name, id='subscribe-link'), name='subscribe', value=mailinglist.emailaddress, class_='hidden'), method_='post', action='', id='subscribe-form', class_='hidden')) return 'mailinglist_conversations.html', data, None else: return 'mailinglist_list.html', data, None