def delete_not_possible_reasons(self): """A list of reasons why the context cannot be deleted. An empty list means that there are no reasons, so the delete can go ahead. """ reasons = [] celebrities = getUtility(ILaunchpadCelebrities) # We go through all of the conditions why the bug tracker # can't be deleted, and record reasons for all of them. We do # this so that users can discover the logic behind the # decision, and try something else, seek help, or give up as # appropriate. Just showing the first problem would stop users # from being able to help themselves. # Check that no products or projects use this bugtracker. pillars = ( getUtility(IBugTrackerSet).getPillarsForBugtrackers( [self.context]).get(self.context, [])) if len(pillars) > 0: reasons.append( 'This is the bug tracker for %s.' % english_list( sorted(pillar.title for pillar in pillars))) # Only admins and registry experts can delete bug watches en # masse. if not self.context.watches.is_empty(): admin_teams = [celebrities.admin, celebrities.registry_experts] for team in admin_teams: if self.user.inTeam(team): break else: reasons.append( 'There are linked bug watches and only members of %s ' 'can delete them en masse.' % english_list( sorted(team.title for team in admin_teams))) # Bugtrackers with imported messages cannot be deleted. if not self.context.imported_bug_messages.is_empty(): reasons.append( 'Bug comments have been imported via this bug tracker.') # If the bugtracker is a celebrity then we protect it from # deletion. celebrities_set = set( getattr(celebrities, name) for name in ILaunchpadCelebrities.names()) if self.context in celebrities_set: reasons.append( 'This bug tracker is protected from deletion.') return reasons
def main(self): selected_groups = self.args if len(selected_groups) == 0: self.parser.print_help() sys.exit(1) selected_job_sources = set() # Include job sources from selected groups. for group in selected_groups: selected_job_sources.update(self.grouped_sources[group]) # Then, exclude job sources. for source in self.options.excluded_job_sources: if source not in selected_job_sources: self.logger.info( '%r is not in %s' % ( source, english_list(selected_groups, "or"))) else: selected_job_sources.remove(source) # Process job sources. command = os.path.join( os.path.dirname(sys.argv[0]), 'process-job-source.py') child_args = [command] if self.options.verbose: child_args.append('-v') children = [] for job_source in selected_job_sources: child = subprocess.Popen(child_args + [job_source]) children.append(child) if self.options.do_wait: for child in children: child.wait()
def main(self): selected_groups = self.args if len(selected_groups) == 0: self.parser.print_help() sys.exit(1) selected_job_sources = set() # Include job sources from selected groups. for group in selected_groups: selected_job_sources.update(self.grouped_sources[group]) # Then, exclude job sources. for source in self.options.excluded_job_sources: if source not in selected_job_sources: self.logger.info('%r is not in %s' % (source, english_list(selected_groups, "or"))) else: selected_job_sources.remove(source) # Process job sources. command = os.path.join(os.path.dirname(sys.argv[0]), 'process-job-source.py') child_args = [command] if self.options.verbose: child_args.append('-v') children = [] for job_source in selected_job_sources: child = subprocess.Popen(child_args + [job_source]) children.append(child) if self.options.do_wait: for child in children: child.wait()
def _add_english_condition(self, conditions, variable, description): if len(variable) > 0: conditions.append(u"the %s is %s" % (description, english_list( (kind.title for kind in sorted(variable)), conjunction=u"or")))
def describe_grants(activity_value): if activity_value is not None: output = describe_git_permissions({ permission for attr, permission in _activity_permissions.items() if activity_value.get(attr)}) else: output = [] return english_list(output)
def register_action(self, action, data): """Register the new branch merge proposal.""" registrant = self.user source_branch = self.context target_branch = data['target_branch'] prerequisite_branch = data.get('prerequisite_branch') review_requests = [] reviewer = data.get('reviewer') review_type = data.get('review_type') if reviewer is None: reviewer = target_branch.code_reviewer if reviewer is not None: review_requests.append((reviewer, review_type)) branch_names = [branch.unique_name for branch in [source_branch, target_branch]] visibility_info = getUtility(IBranchSet).getBranchVisibilityInfo( self.user, reviewer, branch_names) visible_branches = list(visibility_info['visible_branches']) if self.request.is_ajax and len(visible_branches) < 2: self.request.response.setStatus(400, "Branch Visibility") self.request.response.setHeader( 'Content-Type', 'application/json') return simplejson.dumps({ 'person_name': visibility_info['person_name'], 'branches_to_check': branch_names, 'visible_branches': visible_branches, }) try: proposal = source_branch.addLandingTarget( registrant=registrant, merge_target=target_branch, merge_prerequisite=prerequisite_branch, needs_review=data['needs_review'], description=data.get('comment'), review_requests=review_requests, commit_message=data.get('commit_message')) if len(visible_branches) < 2: invisible_branches = [branch.unique_name for branch in [source_branch, target_branch] if branch.unique_name not in visible_branches] self.request.response.addNotification( 'To ensure visibility, %s is now subscribed to: %s' % (visibility_info['person_name'], english_list(invisible_branches))) # Success so we do a client redirect to the new mp page. if self.request.is_ajax: self.request.response.setStatus(201) self.request.response.setHeader( 'Location', canonical_url(proposal)) return None else: self.next_url = canonical_url(proposal) except InvalidBranchMergeProposal as error: self.addError(str(error))
def linkedMilestonesForSeries(self, series): """Return a string of linkified milestones in the series.""" # Listify to remove repeated queries. milestones = list(series.milestones) if len(milestones) == 0: return "" linked_milestones = [] for milestone in milestones: linked_milestones.append("<a href=%s>%s</a>" % (canonical_url(milestone), milestone.name)) return english_list(linked_milestones)
def linkedMilestonesForSeries(self, series): """Return a string of linkified milestones in the series.""" # Listify to remove repeated queries. milestones = list(series.milestones) if len(milestones) == 0: return "" linked_milestones = [] for milestone in milestones: linked_milestones.append( "<a href=%s>%s</a>" % (canonical_url(milestone), milestone.name)) return english_list(linked_milestones)
def conditions(self): """Descriptions of the bug subscription filter's conditions.""" conditions = [] bug_notification_level = self.context.bug_notification_level if bug_notification_level < BugNotificationLevel.COMMENTS: mapping = bug_notification_level_description_mapping('the bug') conditions.append(mapping[bug_notification_level].lower()[:-1]) self._add_english_condition(conditions, self.context.statuses, 'status') self._add_english_condition(conditions, self.context.importances, 'importance') tags = self.context.tags if len(tags) > 0: conditions.append(u"the bug is tagged with %s" % english_list( sorted(tags), conjunction=(u"and" if self.context.find_all_tags else u"or"))) self._add_english_condition(conditions, self.context.information_types, 'information type') return conditions
def conditions(self): """Descriptions of the bug subscription filter's conditions.""" conditions = [] bug_notification_level = self.context.bug_notification_level if bug_notification_level < BugNotificationLevel.COMMENTS: mapping = bug_notification_level_description_mapping( 'the bug') conditions.append( mapping[bug_notification_level].lower()[:-1]) self._add_english_condition( conditions, self.context.statuses, 'status') self._add_english_condition( conditions, self.context.importances, 'importance') tags = self.context.tags if len(tags) > 0: conditions.append( u"the bug is tagged with %s" % english_list( sorted(tags), conjunction=( u"and" if self.context.find_all_tags else u"or"))) self._add_english_condition( conditions, self.context.information_types, 'information type') return conditions
def requestBuild(self, data): """User action for requesting a number of builds. We raise exceptions for most errors, but if there's already a pending build for a particular architecture, we simply record that so that other builds can be queued and a message displayed to the caller. """ informational = {} builds = [] already_pending = [] for arch in data['distro_arch_series']: try: build = self.context.requestBuild( self.user, data['archive'], arch, data['pocket'], channels=data['channels']) builds.append(build) except SnapBuildAlreadyPending: already_pending.append(arch) if already_pending: informational['already_pending'] = ( "An identical build is already pending for %s." % english_list(arch.architecturetag for arch in already_pending)) return builds, informational
def _add_english_condition(self, conditions, variable, description): if len(variable) > 0: conditions.append( u"the %s is %s" % (description, english_list( (kind.title for kind in sorted(variable)), conjunction=u"or")))
def processors_text(self): return english_list(p.name for p in self.context.processors)
def register_action(self, action, data): """Register the new merge proposal.""" registrant = self.user source_ref = self.context target_ref = data['target_git_repository'].getRefByPath( data['target_git_path']) if (data.get('prerequisite_git_repository') is not None and data.get('prerequisite_git_path') is not None): prerequisite_ref = ( data['prerequisite_git_repository'].getRefByPath( data['prerequisite_git_path'])) else: prerequisite_ref = None review_requests = [] reviewer = data.get('reviewer') review_type = data.get('review_type') if reviewer is None: reviewer = target_ref.code_reviewer if reviewer is not None: review_requests.append((reviewer, review_type)) repository_names = [ ref.repository.unique_name for ref in (source_ref, target_ref)] repository_set = getUtility(IGitRepositorySet) visibility_info = repository_set.getRepositoryVisibilityInfo( self.user, reviewer, repository_names) visible_repositories = list(visibility_info['visible_repositories']) if self.request.is_ajax and len(visible_repositories) < 2: self.request.response.setStatus(400, "Repository Visibility") self.request.response.setHeader( 'Content-Type', 'application/json') return json.dumps({ 'person_name': visibility_info['person_name'], 'repositories_to_check': repository_names, 'visible_repositories': visible_repositories, }) try: proposal = source_ref.addLandingTarget( registrant=registrant, merge_target=target_ref, merge_prerequisite=prerequisite_ref, needs_review=data['needs_review'], description=data.get('comment'), review_requests=review_requests, commit_message=data.get('commit_message')) if len(visible_repositories) < 2: invisible_repositories = [ ref.repository.unique_name for ref in (source_ref, target_ref) if ref.repository.unique_name not in visible_repositories] self.request.response.addNotification( 'To ensure visibility, %s is now subscribed to: %s' % (visibility_info['person_name'], english_list(invisible_repositories))) # Success so we do a client redirect to the new mp page. if self.request.is_ajax: self.request.response.setStatus(201) self.request.response.setHeader( 'Location', canonical_url(proposal)) return None else: self.next_url = canonical_url(proposal) except InvalidBranchMergeProposal as error: self.addError(str(error))
def __init__(self, duplicates): super(DuplicateBuildOnError, self).__init__( "{} {} present in the 'build-on' of multiple items".format( english_list(duplicates), "is" if len(duplicates) == 1 else "are"))