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_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)
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
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
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
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()
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
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
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> "Test Admin" <[email protected]>' ) 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
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')
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> "Test Admin" <[email protected]>' 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)
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)
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)
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)
def setUp(self): setup_basic_test() setup_global_objects() self.user = User.by_username('test-user-2') c.user = self.user