def test_link_to_send_message_form(self):
     User.by_username('test-admin').set_pref('email_address',
                                             '*****@*****.**')
     User.by_username('test-user').set_pref('email_address',
                                            '*****@*****.**')
     r = self.app.get('/u/test-user/profile', status=200)
     assert r.html.find('a', dict(href='send_message'))
Exemple #2
0
 def test_link_to_send_message_form(self):
     User.by_username('test-admin').set_pref('email_address',
                                             '*****@*****.**')
     User.by_username('test-user').set_pref('email_address',
                                            '*****@*****.**')
     r = self.app.get('/u/test-user/profile',
                      status=200)
     assert r.html.find('a', dict(href='send_message'))
 def test_disable_user_messages(self):
     User.by_username('test-admin').set_pref('email_address', '*****@*****.**')
     test_user = User.by_username('test-user')
     test_user.set_pref('email_address', '*****@*****.**')
     test_user.set_pref('disable_user_messages', True)
     r = self.app.get('/u/test-user/profile')
     assert '<a href="send_message">Send me a message</a>' not in r
     r = self.app.get('/u/test-user/profile/send_message', status=302)
     assert 'This user has disabled direct email messages' in self.webflash(r)
Exemple #4
0
    def test_user_messages_sender_disabled(self):
        admin_user = User.by_username('test-admin')
        admin_user.set_pref('email_address', '*****@*****.**')
        admin_user.set_pref('disable_user_messages', True)

        test_user = User.by_username('test-user')
        test_user.set_pref('email_address', '*****@*****.**')

        r = self.app.get('/u/test-user/profile/send_message', status=200)
        assert 'you currently have user messages disabled' in r
Exemple #5
0
    def test_user_messages_sender_disabled(self):
        admin_user = User.by_username('test-admin')
        admin_user.set_pref('email_address', '*****@*****.**')
        admin_user.set_pref('disable_user_messages', True)

        test_user = User.by_username('test-user')
        test_user.set_pref('email_address', '*****@*****.**')

        r = self.app.get('/u/test-user/profile/send_message', status=200)
        assert 'you currently have user messages disabled' in r
Exemple #6
0
 def test_disable_user_messages(self):
     User.by_username('test-admin').set_pref('email_address',
                                             '*****@*****.**')
     test_user = User.by_username('test-user')
     test_user.set_pref('email_address', '*****@*****.**')
     test_user.set_pref('disable_user_messages', True)
     r = self.app.get('/u/test-user/profile')
     assert '<a href="send_message">Send me a message</a>' not in r
     r = self.app.get('/u/test-user/profile/send_message', status=302)
     assert 'This user has disabled direct email messages' in self.webflash(
         r)
    def test_link_to_send_message_form(self):
        User.by_username('test-admin').set_pref('email_address', '*****@*****.**')
        User.by_username('test-user').set_pref('email_address', '*****@*****.**')
        r = self.app.get('/u/test-user/profile',
                         status=200)
        assert '<a href="send_message">Send me a message</a>' in r

        r = self.app.get('/u/test-user/profile',
                     extra_environ={'username': '******'},
                     status=200)

        assert '<a href="send_message">Send me a message</a>' not in r
    def test_ticket_move_with_users_not_in_project(self):
        app1 = c.project.app_instance('bugs')
        app2 = c.project.app_instance('bugs2')
        app1.globals.custom_fields.extend([
            {'name': '_user_field', 'type': 'user', 'label': 'User field'},
            {'name': '_user_field_2', 'type': 'user', 'label': 'User field 2'}])
        app2.globals.custom_fields.extend([
            {'name': '_user_field', 'type': 'user', 'label': 'User field'},
            {'name': '_user_field_2', 'type': 'user', 'label': 'User field 2'}])
        ThreadLocalORMSession.flush_all()
        ThreadLocalORMSession.close_all()
        from allura.websetup import bootstrap
        bootstrap.create_user('test-user-0')
        with h.push_context(c.project._id, app_config_id=app1.config._id):
            ticket = Ticket.new()
            ticket.summary = 'test ticket'
            ticket.description = 'test description'
            ticket.custom_fields['_user_field'] = 'test-user'  # in project
            ticket.custom_fields['_user_field_2'] = 'test-user-0'  # not in project
            ticket.assigned_to_id = User.by_username('test-user-0')._id  # not in project

        t = ticket.move(app2.config)
        assert_equal(t.assigned_to_id, None)
        assert_equal(t.custom_fields['_user_field'], 'test-user')
        assert_equal(t.custom_fields['_user_field_2'], '')
        post = Post.query.find(dict(thread_id=ticket.discussion_thread._id)).first()
        assert post is not None, 'No comment about ticket moving'
        message = 'Ticket moved from /p/test/bugs/1/'
        message += '\n\nCan\'t be converted:\n'
        message += '\n- **_user_field_2**: test-user-0 (user not in project)'
        message += '\n- **assigned_to**: test-user-0 (user not in project)'
        assert_equal(post.text, message)
    def test_login(self):
        user = User.by_username("test-user")
        init_logins = user.stats.tot_logins_count
        r = self.app.post("/auth/do_login", params=dict(username=user.username, password="******"))

        assert user.stats.tot_logins_count == 1 + init_logins
        assert user.stats.getLastMonthLogins() == 1 + init_logins
Exemple #10
0
    def test_ticket_move_with_users_not_in_project(self):
        app1 = c.project.app_instance('bugs')
        app2 = c.project.app_instance('bugs2')
        app1.globals.custom_fields.extend([
            {'name': '_user_field', 'type': 'user', 'label': 'User field'},
            {'name': '_user_field_2', 'type': 'user', 'label': 'User field 2'}])
        app2.globals.custom_fields.extend([
            {'name': '_user_field', 'type': 'user', 'label': 'User field'},
            {'name': '_user_field_2', 'type': 'user', 'label': 'User field 2'}])
        ThreadLocalORMSession.flush_all()
        ThreadLocalORMSession.close_all()
        from allura.websetup import bootstrap
        bootstrap.create_user('test-user-0')
        with h.push_context(c.project._id, app_config_id=app1.config._id):
            ticket = Ticket.new()
            ticket.summary = 'test ticket'
            ticket.description = 'test description'
            ticket.custom_fields['_user_field'] = 'test-user'  # in project
            # not in project
            ticket.custom_fields['_user_field_2'] = 'test-user-0'
            # not in project
            ticket.assigned_to_id = User.by_username('test-user-0')._id

        t = ticket.move(app2.config)
        assert_equal(t.assigned_to_id, None)
        assert_equal(t.custom_fields['_user_field'], 'test-user')
        assert_equal(t.custom_fields['_user_field_2'], '')
        post = Post.query.find(
            dict(thread_id=ticket.discussion_thread._id)).first()
        assert post is not None, 'No comment about ticket moving'
        message = 'Ticket moved from /p/test/bugs/1/'
        message += '\n\nCan\'t be converted:\n'
        message += '\n- **_user_field_2**: test-user-0 (user not in project)'
        message += '\n- **assigned_to**: test-user-0 (user not in project)'
        assert_equal(post.text, message)
    def setUp(self):
        from allura.model import User

        setup_basic_test()
        setup_global_objects()
        self.user = User.by_username("test-user-2")
        c.user = self.user
    def setUp(self):
        from allura.model import User

        setup_basic_test()
        setup_global_objects()
        self.user = User.by_username('test-user-2')
        c.user = self.user
    def test_ticket_move(self):
        app1 = c.project.app_instance('bugs')
        app2 = c.project.app_instance('bugs2')
        with h.push_context(c.project._id, app_config_id=app1.config._id):
            ticket = Ticket.new()
            ticket.summary = 'test ticket'
            ticket.description = 'test description'
            ticket.assigned_to_id = User.by_username('test-user')._id
            ticket.discussion_thread.add_post(text='test comment')

        assert_equal(Ticket.query.find({'app_config_id': app1.config._id}).count(), 1)
        assert_equal(Ticket.query.find({'app_config_id': app2.config._id}).count(), 0)
        assert_equal(Post.query.find(dict(thread_id=ticket.discussion_thread._id)).count(), 1)

        t = ticket.move(app2.config)
        assert_equal(Ticket.query.find({'app_config_id': app1.config._id}).count(), 0)
        assert_equal(Ticket.query.find({'app_config_id': app2.config._id}).count(), 1)
        assert_equal(t.summary, 'test ticket')
        assert_equal(t.description, 'test description')
        assert_equal(t.assigned_to.username, 'test-user')
        assert_equal(t.url(), '/p/test/bugs2/1/')

        post = Post.query.find(dict(thread_id=ticket.discussion_thread._id,
                                    text={'$ne': 'test comment'})).first()
        assert post is not None, 'No comment about ticket moving'
        message = 'Ticket moved from /p/test/bugs/1/'
        assert_equal(post.text, message)

        post = Post.query.find(dict(text='test comment')).first()
        assert_equal(post.thread.discussion_id, app2.config.discussion_id)
        assert_equal(post.thread.app_config_id, app2.config._id)
        assert_equal(post.app_config_id, app2.config._id)
    def test_login(self):
        user = User.by_username('test-user')
        init_logins = user.stats.tot_logins_count
        self.app.post('/auth/do_login', params=dict(
            username=user.username, password='******'))

        assert user.stats.tot_logins_count == 1 + init_logins
        assert user.stats.getLastMonthLogins() == 1 + init_logins
    def test_login(self):
        user = User.by_username('test-user')
        init_logins = c.user.stats.tot_logins_count
        r = self.app.post('/auth/do_login',
                          params=dict(username=user.username, password='******'))

        assert user.stats.tot_logins_count == 1 + init_logins
        assert user.stats.getLastMonthLogins() == 1 + init_logins
    def setUp(self):
        super(TestGitCommit, self).setUp()
        setup_basic_test()

        user = User.by_username('test-admin')
        user.set_password('testpassword')
        addr = M.EmailAddress.upsert('*****@*****.**')
        user.claim_address('*****@*****.**')
        self.setup_with_tools()
    def setUp(self):
        super(TestGitCommit, self).setUp()
        setup_basic_test()

        user = User.by_username('test-admin')
        user.set_password('testpassword')
        addr = M.EmailAddress.upsert('*****@*****.**')
        user.claim_address('*****@*****.**')
        self.setup_with_tools()
Exemple #18
0
    def test_login(self):
        user = User.by_username('test-user')
        init_logins = user.stats.tot_logins_count
        self.app.get('/')  # establish session
        self.app.post('/auth/do_login', params=dict(
            username=user.username, password='******',
            _session_id=self.app.cookies['_session_id']
        ))

        assert user.stats.tot_logins_count == 1 + init_logins
        assert user.stats.getLastMonthLogins() == 1 + init_logins
Exemple #19
0
    def test_login(self):
        user = User.by_username('test-user')
        init_logins = user.stats.tot_logins_count
        self.app.get('/').follow()  # establish session
        self.app.post('/auth/do_login', antispam=True, params=dict(
            username=user.username, password='******',
            _session_id=self.app.cookies['_session_id'],
        ))

        assert user.stats.tot_logins_count == 1 + init_logins
        assert user.stats.getLastMonthLogins() == 1 + init_logins
Exemple #20
0
    def test_send_message(self, check, gen_message_id, sendsimplemail):
        check.return_value = True
        gen_message_id.return_value = 'id'
        test_user = User.by_username('test-user')
        test_user.set_pref('email_address', '*****@*****.**')
        response = self.app.get('/u/test-user/profile/send_message',
                                status=200)
        assert 'you currently have user messages disabled' not in response
        response.mustcontain(
            '<b>From:</b> &#34;Test Admin&#34; &lt;[email protected]&gt;'
        )

        self.app.post('/u/test-user/profile/send_user_message',
                      params={
                          'subject': 'test subject',
                          'message': 'test message',
                          'cc': 'on'
                      })

        sendsimplemail.post.assert_called_once_with(
            cc=User.by_username('test-admin').get_pref('email_address'),
            text=
            'test message\n\n---\n\nThis message was sent to you via the Allura web mail form.  You may reply to this message directly, or send a message to Test Admin at http://localhost/u/test-admin/profile/send_message\n',
            toaddr=User.by_username('test-user').get_pref('email_address'),
            fromaddr=User.by_username('test-admin').get_pref('email_address'),
            reply_to=User.by_username('test-admin').get_pref('email_address'),
            message_id='id',
            subject='test subject')
        sendsimplemail.reset_mock()
        self.app.post('/u/test-user/profile/send_user_message',
                      params={
                          'subject': 'test subject',
                          'message': 'test message'
                      })

        sendsimplemail.post.assert_called_once_with(
            cc=None,
            text=
            'test message\n\n---\n\nThis message was sent to you via the Allura web mail form.  You may reply to this message directly, or send a message to Test Admin at http://localhost/u/test-admin/profile/send_message\n',
            toaddr=User.by_username('test-user').get_pref('email_address'),
            fromaddr=User.by_username('test-admin').get_pref('email_address'),
            reply_to=User.by_username('test-admin').get_pref('email_address'),
            message_id='id',
            subject='test subject')

        check.return_value = False
        response = self.app.get('/u/test-user/profile/send_message',
                                status=200)
        assert 'Sorry, messaging is rate-limited' in response
Exemple #21
0
    def test_profile_user_card(self):
        user = User.by_username('test-admin')
        locals =  {
            'city': 'test-city',
            'country': 'US'
        }
        webpages = ['http://allura.apache.org/']
        user.set_pref('localization', locals)
        user.set_pref('webpages', webpages)
        r = self.app.get('/u/test-admin/profile/user_card')

        assert user.icon_url() in r.html.find('img').attrs['src']
        assert user.display_name == r.html.find('div', attrs={'class': 'name'}).getText()
        assert user.get_pref('localization')['city'] in r.html.find('span', attrs={'class': 'subitem-loc'}).getText()
        assert user.get_pref('localization')['country'] in r.html.find('span', attrs={'class': 'subitem-loc'}).getText()
        assert user.get_pref('webpages')[0] in str(r.html.find('span', attrs={'class': 'subitem-web'}))
    def test_ticket_move(self):
        app1 = c.project.app_instance('bugs')
        app2 = c.project.app_instance('bugs2')
        with h.push_context(c.project._id, app_config_id=app1.config._id):
            ticket = Ticket.new()
            ticket.summary = 'test ticket'
            ticket.description = 'test description'
            ticket.assigned_to_id = User.by_username('test-user')._id
            ticket.discussion_thread.add_post(text='test comment')

        assert_equal(
            Ticket.query.find({
                'app_config_id': app1.config._id
            }).count(), 1)
        assert_equal(
            Ticket.query.find({
                'app_config_id': app2.config._id
            }).count(), 0)
        assert_equal(
            Post.query.find(
                dict(thread_id=ticket.discussion_thread._id)).count(), 1)

        t = ticket.move(app2.config)
        assert_equal(
            Ticket.query.find({
                'app_config_id': app1.config._id
            }).count(), 0)
        assert_equal(
            Ticket.query.find({
                'app_config_id': app2.config._id
            }).count(), 1)
        assert_equal(t.summary, 'test ticket')
        assert_equal(t.description, 'test description')
        assert_equal(t.assigned_to.username, 'test-user')
        assert_equal(t.url(), '/p/test/bugs2/1/')

        post = Post.query.find(
            dict(thread_id=ticket.discussion_thread._id,
                 text={'$ne': 'test comment'})).first()
        assert post is not None, 'No comment about ticket moving'
        message = 'Ticket moved from /p/test/bugs/1/'
        assert_equal(post.text, message)

        post = Post.query.find(dict(text='test comment')).first()
        assert_equal(post.thread.discussion_id, app2.config.discussion_id)
        assert_equal(post.thread.app_config_id, app2.config._id)
        assert_equal(post.app_config_id, app2.config._id)
 def feed(self, since=None, until=None, page=None, limit=None):
     username = c.project.shortname.split('/')[1]
     user = User.by_username(username)
     if request.environ['PATH_INFO'].endswith('.atom'):
         feed_type = 'atom'
     else:
         feed_type = 'rss'
     title = 'Recent posts by %s' % user.display_name
     feed = Notification.feed(
         {'author_id':user._id},
         feed_type,
         title,
         c.project.url(),
         title,
         since, until, page, limit)
     response.headers['Content-Type'] = ''
     response.content_type = 'application/xml'
     return feed.writeString('utf-8')
Exemple #24
0
    def test_send_message(self, check, gen_message_id, sendsimplemail):
        check.return_value = True
        gen_message_id.return_value = 'id'
        test_user = User.by_username('test-user')
        test_user.set_pref('email_address', '*****@*****.**')
        response = self.app.get(
            '/u/test-user/profile/send_message', status=200)
        assert 'you currently have user messages disabled' not in response
        assert '<b>From:</b> &#34;Test Admin&#34; &lt;[email protected]&gt;' in response

        self.app.post('/u/test-user/profile/send_user_message',
                      params={'subject': 'test subject',
                              'message': 'test message',
                              'cc': 'on'})

        sendsimplemail.post.assert_called_once_with(
            cc=User.by_username('test-admin').get_pref('email_address'),
            text=u'test message\n\n---\n\nThis message was sent to you via the Allura web mail form.  You may reply to this message directly, or send a message to Test Admin at http://localhost/u/test-admin/profile/send_message\n',
            toaddr=User.by_username('test-user').get_pref('email_address'),
            fromaddr=User.by_username('test-admin').get_pref('email_address'),
            reply_to=User.by_username('test-admin').get_pref('email_address'),
            message_id=u'id',
            subject=u'test subject')
        sendsimplemail.reset_mock()
        self.app.post('/u/test-user/profile/send_user_message',
                      params={'subject': 'test subject',
                              'message': 'test message'})

        sendsimplemail.post.assert_called_once_with(
            cc=None,
            text=u'test message\n\n---\n\nThis message was sent to you via the Allura web mail form.  You may reply to this message directly, or send a message to Test Admin at http://localhost/u/test-admin/profile/send_message\n',
            toaddr=User.by_username('test-user').get_pref('email_address'),
            fromaddr=User.by_username('test-admin').get_pref('email_address'),
            reply_to=User.by_username('test-admin').get_pref('email_address'),
            message_id=u'id',
            subject=u'test subject')

        check.return_value = False
        response = self.app.get(
            '/u/test-user/profile/send_message', status=200)
        assert 'Sorry, messaging is rate-limited' in response
    def update_tickets(self, **post_data):
        from forgetracker.tracker_main import get_change_text, get_label
        tickets = Ticket.query.find(dict(
                _id={'$in':[ObjectId(id) for id in aslist(post_data['__ticket_ids'])]},
                app_config_id=self.app_config_id)).all()

        fields = set(['status', 'private'])
        values = {}
        labels = post_data.get('labels', [])

        for k in fields:
            v = post_data.get(k)
            if v: values[k] = v
        assigned_to = post_data.get('assigned_to')
        if assigned_to == '-':
            values['assigned_to_id'] = None
        elif assigned_to:
            user = c.project.user_in_project(assigned_to)
            if user:
                values['assigned_to_id'] = user._id
        private = post_data.get('private')
        if private:
            values['private'] = asbool(private)

        custom_values = {}
        custom_fields = {}
        for cf in self.custom_fields or []:
            v = post_data.get(cf.name)
            if v:
                custom_values[cf.name] = v
                custom_fields[cf.name] = cf

        changes = {}
        changed_tickets = {}
        for ticket in tickets:
            message = ''
            if labels:
                values['labels'] = self.append_new_labels(ticket.labels, labels.split(','))
            for k, v in sorted(values.iteritems()):
                if k == 'assigned_to_id':
                    new_user = User.query.get(_id=v)
                    old_user = User.query.get(_id=getattr(ticket, k))
                    if new_user:
                        message += get_change_text(
                            get_label(k),
                            new_user.display_name,
                            old_user.display_name)
                elif k == 'private':
                    def private_text(val):
                        if val:
                            return 'Yes'
                        else:
                            return 'No'
                    message += get_change_text(
                        get_label(k),
                        private_text(v),
                        private_text(getattr(ticket, k)))
                else:
                    message += get_change_text(
                        get_label(k),
                        v,
                        getattr(ticket, k))
                setattr(ticket, k, v)
            for k, v in sorted(custom_values.iteritems()):
                def cf_val(cf):
                    return ticket.get_custom_user(cf.name) \
                           if cf.type == 'user' \
                           else ticket.custom_fields.get(cf.name)
                cf = custom_fields[k]
                old_value = cf_val(cf)
                if cf.type == 'boolean':
                    v = asbool(v)
                ticket.custom_fields[k] = v
                new_value = cf_val(cf)
                message += get_change_text(
                    cf.label,
                    new_value,
                    old_value)
            if message != '':
                changes[ticket._id] = message
                changed_tickets[ticket._id] = ticket
                ticket.discussion_thread.post(message, notify=False)
                ticket.commit()

        filtered_changes = self.filtered_by_subscription(changed_tickets)
        users = User.query.find({'_id': {'$in': filtered_changes.keys()}}).all()
        def changes_iter(user):
            for t_id in filtered_changes.get(user._id, []):
                # mark changes text as safe, thus it wouldn't be escaped in plain-text emails
                # html part of email is handled by markdown and it'll be properly escaped
                yield (changed_tickets[t_id], jinja2.Markup(changes[t_id]))
        mail = dict(
            sender = c.project.app_instance(self.app_config).email_address,
            fromaddr = str(c.user._id),
            reply_to = tg_config['forgemail.return_path'],
            subject = '[%s:%s] Mass edit changes by %s' % (c.project.shortname,
                                                           self.app_config.options.mount_point,
                                                           c.user.display_name),
        )
        tmpl = g.jinja2_env.get_template('forgetracker:data/mass_report.html')
        head = []
        for f, v in sorted(values.iteritems()):
            if f == 'assigned_to_id':
                user = User.query.get(_id=v)
                v = user.display_name if user else v
            head.append('- **%s**: %s' % (get_label(f), v))
        for f, v in sorted(custom_values.iteritems()):
            cf = custom_fields[f]
            if cf.type == 'user':
                user = User.by_username(v)
                v = user.display_name if user else v
            head.append('- **%s**: %s' % (cf.label, v))
        tmpl_context = {'context': c, 'data': {'header': jinja2.Markup('\n'.join(['Mass edit changing:', ''] + head))}}
        for user in users:
            tmpl_context['data'].update({'changes': changes_iter(user)})
            mail.update(dict(
                message_id = h.gen_message_id(),
                text = tmpl.render(tmpl_context),
                destinations = [str(user._id)]))
            mail_tasks.sendmail.post(**mail)

        if self.app_config.options.get('TicketMonitoringType') in (
                'AllTicketChanges', 'AllPublicTicketChanges'):
            monitoring_email = self.app_config.options.get('TicketMonitoringEmail')
            visible_changes = []
            for t_id, t in changed_tickets.items():
                if (not t.private or
                        self.app_config.options.get('TicketMonitoringType') ==
                        'AllTicketChanges'):
                    visible_changes.append(
                            (changed_tickets[t_id], jinja2.Markup(changes[t_id])))
            if visible_changes:
                tmpl_context['data'].update({'changes': visible_changes})
                mail.update(dict(
                    message_id = h.gen_message_id(),
                    text = tmpl.render(tmpl_context),
                    destinations = [monitoring_email]))
                mail_tasks.sendmail.post(**mail)

        self.invalidate_bin_counts()
        ThreadLocalORMSession.flush_all()
        app = '%s/%s' % (c.project.shortname, self.app_config.options.mount_point)
        count = len(tickets)
        text = 'Updated {} ticket{} in {}'.format(count, 's' if count != 1 else '', app)
        Notification.post_user(c.user, None, 'flash', text=text)
Exemple #26
0
    def update_tickets(self, **post_data):
        from forgetracker.tracker_main import get_change_text, get_label

        tickets = Ticket.query.find(
            dict(
                _id={"$in": [ObjectId(id) for id in aslist(post_data["__ticket_ids"])]},
                app_config_id=self.app_config_id,
            )
        ).all()

        fields = set(["status", "private"])
        values = {}
        labels = post_data.get("labels", [])

        for k in fields:
            v = post_data.get(k)
            if v:
                values[k] = v
        assigned_to = post_data.get("assigned_to")
        if assigned_to == "-":
            values["assigned_to_id"] = None
        elif assigned_to:
            user = c.project.user_in_project(assigned_to)
            if user:
                values["assigned_to_id"] = user._id
        private = post_data.get("private")
        if private:
            values["private"] = asbool(private)

        discussion_disabled = post_data.get("discussion_disabled")
        if discussion_disabled:
            values["disabled_discussion"] = asbool(discussion_disabled)

        custom_values = {}
        custom_fields = {}
        for cf in self.custom_fields or []:
            v = post_data.get(cf.name)
            if v:
                custom_values[cf.name] = v
                custom_fields[cf.name] = cf

        changes = {}
        changed_tickets = {}
        for ticket in tickets:
            message = ""
            if labels:
                values["labels"] = self.append_new_labels(ticket.labels, labels.split(","))
            for k, v in sorted(values.iteritems()):
                if k == "assigned_to_id":
                    new_user = User.query.get(_id=v)
                    old_user = User.query.get(_id=getattr(ticket, k))
                    if new_user:
                        message += get_change_text(get_label(k), new_user.display_name, old_user.display_name)
                elif k == "private" or k == "discussion_disabled":

                    def _text(val):
                        if val:
                            return "Yes"
                        else:
                            return "No"

                    message += get_change_text(get_label(k), _text(v), _text(getattr(ticket, k)))
                else:
                    message += get_change_text(get_label(k), v, getattr(ticket, k))
                setattr(ticket, k, v)
            for k, v in sorted(custom_values.iteritems()):

                def cf_val(cf):
                    return ticket.get_custom_user(cf.name) if cf.type == "user" else ticket.custom_fields.get(cf.name)

                cf = custom_fields[k]
                old_value = cf_val(cf)
                if cf.type == "boolean":
                    v = asbool(v)
                ticket.custom_fields[k] = v
                new_value = cf_val(cf)
                message += get_change_text(cf.label, new_value, old_value)
            if message != "":
                changes[ticket._id] = message
                changed_tickets[ticket._id] = ticket
                ticket.discussion_thread.post(message, notify=False)
                ticket.commit()

        filtered_changes = self.filtered_by_subscription(changed_tickets)
        users = User.query.find({"_id": {"$in": filtered_changes.keys()}}).all()

        def changes_iter(user):
            for t_id in filtered_changes.get(user._id, []):
                # mark changes text as safe, thus it wouldn't be escaped in plain-text emails
                # html part of email is handled by markdown and it'll be
                # properly escaped
                yield (changed_tickets[t_id], jinja2.Markup(changes[t_id]))

        mail = dict(
            sender=c.project.app_instance(self.app_config).email_address,
            fromaddr=str(c.user._id),
            reply_to=tg_config["forgemail.return_path"],
            subject="[%s:%s] Mass edit changes by %s"
            % (c.project.shortname, self.app_config.options.mount_point, c.user.display_name),
        )
        tmpl = g.jinja2_env.get_template("forgetracker:data/mass_report.html")
        head = []
        for f, v in sorted(values.iteritems()):
            if f == "assigned_to_id":
                user = User.query.get(_id=v)
                v = user.display_name if user else v
            head.append("- **%s**: %s" % (get_label(f), v))
        for f, v in sorted(custom_values.iteritems()):
            cf = custom_fields[f]
            if cf.type == "user":
                user = User.by_username(v)
                v = user.display_name if user else v
            head.append("- **%s**: %s" % (cf.label, v))
        tmpl_context = {"context": c, "data": {"header": jinja2.Markup("\n".join(["Mass edit changing:", ""] + head))}}
        for user in users:
            tmpl_context["data"].update({"changes": changes_iter(user)})
            mail.update(
                dict(message_id=h.gen_message_id(), text=tmpl.render(tmpl_context), destinations=[str(user._id)])
            )
            mail_tasks.sendmail.post(**mail)

        if self.app_config.options.get("TicketMonitoringType") in ("AllTicketChanges", "AllPublicTicketChanges"):
            monitoring_email = self.app_config.options.get("TicketMonitoringEmail")
            visible_changes = []
            for t_id, t in changed_tickets.items():
                if not t.private or self.app_config.options.get("TicketMonitoringType") == "AllTicketChanges":
                    visible_changes.append((changed_tickets[t_id], jinja2.Markup(changes[t_id])))
            if visible_changes:
                tmpl_context["data"].update({"changes": visible_changes})
                mail.update(
                    dict(message_id=h.gen_message_id(), text=tmpl.render(tmpl_context), destinations=[monitoring_email])
                )
                mail_tasks.sendmail.post(**mail)

        self.invalidate_bin_counts()
        ThreadLocalORMSession.flush_all()
        app = "%s/%s" % (c.project.shortname, self.app_config.options.mount_point)
        count = len(tickets)
        text = "Updated {} ticket{} in {}".format(count, "s" if count != 1 else "", app)
        Notification.post_user(c.user, None, "flash", text=text)
Exemple #27
0
    def update_tickets(self, **post_data):
        from forgetracker.tracker_main import get_change_text, get_label
        tickets = Ticket.query.find(
            dict(_id={
                '$in':
                [ObjectId(id) for id in aslist(post_data['__ticket_ids'])]
            },
                 app_config_id=self.app_config_id)).all()

        fields = set(['status', 'private'])
        values = {}
        labels = post_data.get('labels', [])

        for k in fields:
            v = post_data.get(k)
            if v: values[k] = v
        assigned_to = post_data.get('assigned_to')
        if assigned_to == '-':
            values['assigned_to_id'] = None
        elif assigned_to:
            user = c.project.user_in_project(assigned_to)
            if user:
                values['assigned_to_id'] = user._id
        private = post_data.get('private')
        if private:
            values['private'] = asbool(private)

        custom_values = {}
        custom_fields = {}
        for cf in self.custom_fields or []:
            v = post_data.get(cf.name)
            if v:
                custom_values[cf.name] = v
                custom_fields[cf.name] = cf

        changes = {}
        changed_tickets = {}
        for ticket in tickets:
            message = ''
            if labels:
                values['labels'] = self.append_new_labels(
                    ticket.labels, labels.split(','))
            for k, v in sorted(values.iteritems()):
                if k == 'assigned_to_id':
                    new_user = User.query.get(_id=v)
                    old_user = User.query.get(_id=getattr(ticket, k))
                    if new_user:
                        message += get_change_text(get_label(k),
                                                   new_user.display_name,
                                                   old_user.display_name)
                elif k == 'private':

                    def private_text(val):
                        if val:
                            return 'Yes'
                        else:
                            return 'No'

                    message += get_change_text(
                        get_label(k), private_text(v),
                        private_text(getattr(ticket, k)))
                else:
                    message += get_change_text(get_label(k), v,
                                               getattr(ticket, k))
                setattr(ticket, k, v)
            for k, v in sorted(custom_values.iteritems()):

                def cf_val(cf):
                    return ticket.get_custom_user(cf.name) \
                           if cf.type == 'user' \
                           else ticket.custom_fields.get(cf.name)

                cf = custom_fields[k]
                old_value = cf_val(cf)
                if cf.type == 'boolean':
                    v = asbool(v)
                ticket.custom_fields[k] = v
                new_value = cf_val(cf)
                message += get_change_text(cf.label, new_value, old_value)
            if message != '':
                changes[ticket._id] = message
                changed_tickets[ticket._id] = ticket
                ticket.discussion_thread.post(message, notify=False)
                ticket.commit()

        filtered_changes = self.filtered_by_subscription(changed_tickets)
        users = User.query.find({
            '_id': {
                '$in': filtered_changes.keys()
            }
        }).all()

        def changes_iter(user):
            for t_id in filtered_changes.get(user._id, []):
                # mark changes text as safe, thus it wouldn't be escaped in plain-text emails
                # html part of email is handled by markdown and it'll be properly escaped
                yield (changed_tickets[t_id], jinja2.Markup(changes[t_id]))

        mail = dict(
            sender=c.project.app_instance(self.app_config).email_address,
            fromaddr=str(c.user._id),
            reply_to=str(c.user._id),
            subject='[%s:%s] Mass edit changes by %s' %
            (c.project.shortname, self.app_config.options.mount_point,
             c.user.display_name),
        )
        tmpl = g.jinja2_env.get_template('forgetracker:data/mass_report.html')
        head = []
        for f, v in sorted(values.iteritems()):
            if f == 'assigned_to_id':
                user = User.query.get(_id=v)
                v = user.display_name if user else v
            head.append('- **%s**: %s' % (get_label(f), v))
        for f, v in sorted(custom_values.iteritems()):
            cf = custom_fields[f]
            if cf.type == 'user':
                user = User.by_username(v)
                v = user.display_name if user else v
            head.append('- **%s**: %s' % (cf.label, v))
        tmpl_context = {
            'context': c,
            'data': {
                'header':
                jinja2.Markup('\n'.join(['Mass edit changing:', ''] + head))
            }
        }
        for user in users:
            tmpl_context['data'].update({'changes': changes_iter(user)})
            mail.update(
                dict(message_id=h.gen_message_id(),
                     text=tmpl.render(tmpl_context),
                     destinations=[str(user._id)]))
            mail_tasks.sendmail.post(**mail)

        if self.app_config.options.get('TicketMonitoringType') in (
                'AllTicketChanges', 'AllPublicTicketChanges'):
            monitoring_email = self.app_config.options.get(
                'TicketMonitoringEmail')
            visible_changes = []
            for t_id, t in changed_tickets.items():
                if (not t.private
                        or self.app_config.options.get('TicketMonitoringType')
                        == 'AllTicketChanges'):
                    visible_changes.append(
                        (changed_tickets[t_id], jinja2.Markup(changes[t_id])))
            if visible_changes:
                tmpl_context['data'].update({'changes': visible_changes})
                mail.update(
                    dict(message_id=h.gen_message_id(),
                         text=tmpl.render(tmpl_context),
                         destinations=[monitoring_email]))
                mail_tasks.sendmail.post(**mail)

        self.invalidate_bin_counts()
        ThreadLocalORMSession.flush_all()
        app = '%s/%s' % (c.project.shortname,
                         self.app_config.options.mount_point)
        count = len(tickets)
        text = 'Updated {} ticket{} in {}'.format(count,
                                                  's' if count != 1 else '',
                                                  app)
        Notification.post_user(c.user, None, 'flash', text=text)
Exemple #28
0
 def setUp(self):
     setup_basic_test()
     setup_global_objects()
     self.user = User.by_username('test-user-2')
     c.user = self.user
 def configuration(self):
     username = c.project.shortname.split('/')[1]
     user = User.by_username(username)
     return dict(user=user)
 def index(self, **kw):
     username = c.project.shortname.split('/')[1]
     user = User.by_username(username)
     return dict(user=user)
Exemple #31
0
 def setUp(self):
     setup_basic_test()
     setup_global_objects()
     self.user = User.by_username('test-user-2')
     c.user = self.user