def _to_python(self, value, state): from allura.model import User if value: if c.user == User.anonymous(): raise fe.Invalid('Log in to Mark as Private', value, state) else: return value
def move(self, app_config, notify=True): """Move ticket from current tickets app to tickets app with given app_config""" app = app_config.project.app_instance(app_config) prior_url = self.url() prior_app = self.app prior_ticket_num = self.ticket_num attachments = self.attachments attach_metadata = BaseAttachment.metadata_for(self) prior_cfs = [(cf["name"], cf["type"], cf["label"]) for cf in prior_app.globals.custom_fields or []] new_cfs = [(cf["name"], cf["type"], cf["label"]) for cf in app.globals.custom_fields or []] skipped_fields = [] user_fields = [] for cf in prior_cfs: if cf not in new_cfs: # can't convert skipped_fields.append(cf) elif cf[1] == "user": # can convert and field type == user user_fields.append(cf) messages = [] for cf in skipped_fields: name = cf[0] messages.append("- **%s**: %s" % (name, self.custom_fields.get(name, ""))) for cf in user_fields: name = cf[0] username = self.custom_fields.get(name, None) user = app_config.project.user_in_project(username) if not user or user == User.anonymous(): messages.append("- **%s**: %s (user not in project)" % (name, username)) self.custom_fields[name] = "" # special case: not custom user field (assigned_to_id) user = self.assigned_to if user and not app_config.project.user_in_project(user.username): messages.append("- **assigned_to**: %s (user not in project)" % user.username) self.assigned_to_id = None custom_fields = {} for cf in new_cfs: fn, ft, fl = cf old_val = self.custom_fields.get(fn, None) if old_val is None: custom_fields[fn] = None if ft == "user" else "" custom_fields[fn] = old_val self.custom_fields = custom_fields # move ticket. ensure unique ticket_num while True: with h.push_context(app_config.project_id, app_config_id=app_config._id): ticket_num = app.globals.next_ticket_num() self.ticket_num = ticket_num self.app_config_id = app_config._id new_url = app_config.url() + str(self.ticket_num) + "/" try: session(self).flush(self) h.log_action(log, "moved").info("Ticket %s moved to %s" % (prior_url, new_url)) break except OperationFailure, err: if "duplicate" in err.args[0]: log.warning("Try to create duplicate ticket %s when moving from %s" % (new_url, prior_url)) session(self).expunge(self) continue
def update(self, ticket_form): self.globals.invalidate_bin_counts() # update is not allowed to change the ticket_num ticket_form.pop('ticket_num', None) self.labels = ticket_form.pop('labels', []) custom_sums = set() custom_users = set() other_custom_fields = set() for cf in self.globals.custom_fields or []: (custom_sums if cf['type'] == 'sum' else custom_users if cf['type'] == 'user' else other_custom_fields).add(cf['name']) if cf['type'] == 'boolean' and 'custom_fields.' + cf[ 'name'] not in ticket_form: self.custom_fields[cf['name']] = 'False' # this has to happen because the milestone custom field has special layout treatment if '_milestone' in ticket_form: other_custom_fields.add('_milestone') milestone = ticket_form.pop('_milestone', None) if 'custom_fields' not in ticket_form: ticket_form['custom_fields'] = dict() ticket_form['custom_fields']['_milestone'] = milestone attachment = None if 'attachment' in ticket_form: attachment = ticket_form.pop('attachment') for k, v in ticket_form.iteritems(): if k == 'assigned_to': if v: user = c.project.user_in_project(v) if user: self.assigned_to_id = user._id elif k != 'super_id': setattr(self, k, v) if 'custom_fields' in ticket_form: for k, v in ticket_form['custom_fields'].iteritems(): if k in custom_sums: # sums must be coerced to numeric type try: self.custom_fields[k] = float(v) except (TypeError, ValueError): self.custom_fields[k] = 0 elif k in custom_users: # restrict custom user field values to project members user = self.app_config.project.user_in_project(v) self.custom_fields[k] = user.username \ if user and user != User.anonymous() else '' elif k in other_custom_fields: # strings are good enough for any other custom fields self.custom_fields[k] = v self.commit() if attachment is not None: self.attach(attachment.filename, attachment.file, content_type=attachment.type) # flush so we can participate in a subticket search (if any) session(self).flush() super_id = ticket_form.get('super_id') if super_id: self.set_as_subticket_of(bson.ObjectId(super_id))
def update(self, ticket_form): self.globals.invalidate_bin_counts() # update is not allowed to change the ticket_num ticket_form.pop('ticket_num', None) self.labels = ticket_form.pop('labels', []) custom_users = set() other_custom_fields = set() for cf in self.globals.custom_fields or []: (custom_users if cf['type'] == 'user' else other_custom_fields).add(cf['name']) if cf['type'] == 'boolean' and 'custom_fields.' + cf[ 'name'] not in ticket_form: self.custom_fields[cf['name']] = 'False' # this has to happen because the milestone custom field has special layout treatment if '_milestone' in ticket_form: other_custom_fields.add('_milestone') milestone = ticket_form.pop('_milestone', None) if 'custom_fields' not in ticket_form: ticket_form['custom_fields'] = dict() ticket_form['custom_fields']['_milestone'] = milestone attachment = None if 'attachment' in ticket_form: attachment = ticket_form.pop('attachment') for k, v in ticket_form.iteritems(): if k == 'assigned_to': if v: user = c.project.user_in_project(v) if user: self.assigned_to_id = user._id else: setattr(self, k, v) if 'custom_fields' in ticket_form: for k, v in ticket_form['custom_fields'].iteritems(): if k in custom_users: # restrict custom user field values to project members user = self.app_config.project.user_in_project(v) self.custom_fields[k] = user.username \ if user and user != User.anonymous() else '' elif k in other_custom_fields: # strings are good enough for any other custom fields self.custom_fields[k] = v self.commit() if attachment is not None: self.attach(attachment.filename, attachment.file, content_type=attachment.type)
def update(self, ticket_form): self.globals.invalidate_bin_counts() # update is not allowed to change the ticket_num ticket_form.pop('ticket_num', None) self.labels = ticket_form.pop('labels', []) custom_users = set() other_custom_fields = set() for cf in self.globals.custom_fields or []: (custom_users if cf['type'] == 'user' else other_custom_fields).add(cf['name']) if cf['type'] == 'boolean' and 'custom_fields.' + cf['name'] not in ticket_form: self.custom_fields[cf['name']] = 'False' # this has to happen because the milestone custom field has special layout treatment if '_milestone' in ticket_form: other_custom_fields.add('_milestone') milestone = ticket_form.pop('_milestone', None) if 'custom_fields' not in ticket_form: ticket_form['custom_fields'] = dict() ticket_form['custom_fields']['_milestone'] = milestone attachment = None if 'attachment' in ticket_form: attachment = ticket_form.pop('attachment') for k, v in ticket_form.iteritems(): if k == 'assigned_to': if v: user = c.project.user_in_project(v) if user: self.assigned_to_id = user._id else: setattr(self, k, v) if 'custom_fields' in ticket_form: for k,v in ticket_form['custom_fields'].iteritems(): if k in custom_users: # restrict custom user field values to project members user = self.app_config.project.user_in_project(v) self.custom_fields[k] = user.username \ if user and user != User.anonymous() else '' elif k in other_custom_fields: # strings are good enough for any other custom fields self.custom_fields[k] = v self.commit() if attachment is not None: self.attach( attachment.filename, attachment.file, content_type=attachment.type)
def get_custom_user(self, custom_user_field_name): fld = None for f in c.app.globals.custom_fields: if f.name == custom_user_field_name: fld = f break if not fld: raise KeyError, 'Custom field "%s" does not exist.' % custom_user_field_name if fld.type != 'user': raise TypeError, 'Custom field "%s" is of type "%s"; expected ' \ 'type "user".' % (custom_user_field_name, fld.type) username = self.custom_fields.get(custom_user_field_name) if not username: return None user = self.app_config.project.user_in_project(username) if user == User.anonymous(): return None return user
def _check_can_message(self, from_user, to_user): if from_user is User.anonymous(): flash('You must be logged in to send user messages.', 'info') redirect(request.referer) if not (from_user and from_user.get_pref('email_address')): flash('In order to send messages, you must have an email address ' 'associated with your account.', 'info') redirect(request.referer) if not (to_user and to_user.get_pref('email_address')): flash('This user can not receive messages because they do not have ' 'an email address associated with their account.', 'info') redirect(request.referer) if to_user.get_pref('disable_user_messages'): flash('This user has disabled direct email messages', 'info') redirect(request.referer)
def _check_can_message(self, from_user, to_user): if from_user is User.anonymous(): flash('You must be logged in to send user messages.', 'info') redirect(request.referer or '/') if not (from_user and from_user.get_pref('email_address')): flash('In order to send messages, you must have an email address ' 'associated with your account.', 'info') redirect(request.referer or '/') if not (to_user and to_user.get_pref('email_address')): flash('This user can not receive messages because they do not have ' 'an email address associated with their account.', 'info') redirect(request.referer or '/') if to_user.get_pref('disable_user_messages'): flash('This user has disabled direct email messages', 'info') redirect(request.referer or '/')
def update(self, ticket_form): # update is not allowed to change the ticket_num ticket_form.pop("ticket_num", None) self.labels = ticket_form.pop("labels", []) custom_users = set() other_custom_fields = set() for cf in self.globals.custom_fields or []: (custom_users if cf["type"] == "user" else other_custom_fields).add(cf["name"]) if cf["type"] == "boolean" and "custom_fields." + cf["name"] not in ticket_form: self.custom_fields[cf["name"]] = "False" # this has to happen because the milestone custom field has special # layout treatment if "_milestone" in ticket_form: other_custom_fields.add("_milestone") milestone = ticket_form.pop("_milestone", None) if "custom_fields" not in ticket_form: ticket_form["custom_fields"] = dict() ticket_form["custom_fields"]["_milestone"] = milestone attachment = None if "attachment" in ticket_form: attachment = ticket_form.pop("attachment") for k, v in ticket_form.iteritems(): if k == "assigned_to": if v: user = c.project.user_in_project(v) if user: self.assigned_to_id = user._id else: setattr(self, k, v) if "custom_fields" in ticket_form: for k, v in ticket_form["custom_fields"].iteritems(): if k in custom_users: # restrict custom user field values to project members user = self.app_config.project.user_in_project(v) self.custom_fields[k] = user.username if user and user != User.anonymous() else "" elif k in other_custom_fields: # strings are good enough for any other custom fields self.custom_fields[k] = v if attachment is not None: self.add_multiple_attachments(attachment) # flush the session to make attachments available in the # notification email ThreadLocalORMSession.flush_all() self.commit()
def assigned_to_name(self): who = self.assigned_to if who in (None, User.anonymous()): return 'nobody' return who.get_pref('display_name')
def move(self, app_config, notify=True): '''Move ticket from current tickets app to tickets app with given app_config''' app = app_config.project.app_instance(app_config) prior_url = self.url() prior_app = self.app prior_ticket_num = self.ticket_num attachments = self.attachments attach_metadata = BaseAttachment.metadata_for(self) prior_cfs = [(cf['name'], cf['type'], cf['label']) for cf in prior_app.globals.custom_fields or []] new_cfs = [(cf['name'], cf['type'], cf['label']) for cf in app.globals.custom_fields or []] skipped_fields = [] user_fields = [] for cf in prior_cfs: if cf not in new_cfs: # can't convert skipped_fields.append(cf) elif cf[1] == 'user': # can convert and field type == user user_fields.append(cf) messages = [] for cf in skipped_fields: name = cf[0] messages.append('- **%s**: %s' % (name, self.custom_fields.get(name, ''))) for cf in user_fields: name = cf[0] username = self.custom_fields.get(name, None) user = app_config.project.user_in_project(username) if not user or user == User.anonymous(): messages.append('- **%s**: %s (user not in project)' % (name, username)) self.custom_fields[name] = '' # special case: not custom user field (assigned_to_id) user = self.assigned_to if user and not app_config.project.user_in_project(user.username): messages.append('- **assigned_to**: %s (user not in project)' % user.username) self.assigned_to_id = None custom_fields = {} for cf in new_cfs: fn, ft, fl = cf old_val = self.custom_fields.get(fn, None) if old_val is None: custom_fields[fn] = None if ft == 'user' else '' custom_fields[fn] = old_val self.custom_fields = custom_fields # move ticket. ensure unique ticket_num while True: with h.push_context(app_config.project_id, app_config_id=app_config._id): ticket_num = app.globals.next_ticket_num() self.ticket_num = ticket_num self.app_config_id = app_config._id new_url = app_config.url() + str(self.ticket_num) + '/' try: session(self).flush(self) h.log_action(log, 'moved').info('Ticket %s moved to %s' % (prior_url, new_url)) break except OperationFailure, err: if 'duplicate' in err.args[0]: log.warning( 'Try to create duplicate ticket %s when moving from %s' % (new_url, prior_url)) session(self).expunge(self) continue