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