def _getBatchNavigator(self, grantees): """Return the batch navigator to be used to batch the grantees.""" return BatchNavigator(grantees, self.request, hide_counts=True, size=config.launchpad.default_batch_size, range_factory=StormRangeFactory(grantees))
def initialize(self): """See `LaunchpadView.initialize`.""" review_status_field = copy_field( ICodeImport['review_status'], required=False, default=None) self.review_status_widget = CustomWidgetFactory(DropdownWidgetWithAny) setUpWidget(self, 'review_status', review_status_field, IInputWidget) rcs_type_field = copy_field( ICodeImport['rcs_type'], required=False, default=None) self.rcs_type_widget = CustomWidgetFactory(DropdownWidgetWithAny) setUpWidget(self, 'rcs_type', rcs_type_field, IInputWidget) # status should be None if either (a) there were no query arguments # supplied, i.e. the user browsed directly to this page (this is when # hasValidInput returns False) or (b) the user chose 'Any' in the # status widget (this is when hasValidInput returns True but # getInputValue returns None). review_status = None if self.review_status_widget.hasValidInput(): review_status = self.review_status_widget.getInputValue() # Similar for 'type' rcs_type = None if self.rcs_type_widget.hasValidInput(): rcs_type = self.rcs_type_widget.getInputValue() imports = self.context.search( review_status=review_status, rcs_type=rcs_type) self.batchnav = BatchNavigator(imports, self.request)
def batchnav(self): # No point using StormRangeFactory right now, as the sorted # lookup can't be fully indexed (it spans multiple archives). return BatchNavigator( DecoratedResultSet(self.context.publishing_history, pre_iter_hook=self._preload_people), self.request)
def cached_differences(self): """Return a batch navigator of filtered results.""" package_type_dsd_status = { NON_IGNORED: DistroSeriesDifferenceStatus.NEEDS_ATTENTION, HIGHER_VERSION_THAN_PARENT: (DistroSeriesDifferenceStatus.BLACKLISTED_CURRENT), RESOLVED: DistroSeriesDifferenceStatus.RESOLVED, ALL: None, } # If the package_type option is not supported, add an error to # the field and return an empty list. if self.specified_package_type not in package_type_dsd_status: self.setFieldError('package_type', 'Invalid option') differences = [] else: status = package_type_dsd_status[self.specified_package_type] child_version_higher = ( self.specified_package_type == HIGHER_VERSION_THAN_PARENT) differences = get_dsd_source().getForDistroSeries( self.context, difference_type=self.differences_type, name_filter=self.specified_name_filter, status=status, child_version_higher=child_version_higher, packagesets=self.specified_packagesets_filter, changed_by=self.specified_changed_by_filter) return BatchNavigator(differences, self.request)
def setupBuildList(self): """Setup a batched build records list. Return None, so use tal:condition="not: view/setupBuildList" to invoke it in template. """ # recover selected build state state_tag = self.request.get('build_state', '') self.text = self.request.get('build_text', None) if self.text == '': self.text = None # build self.state & self.available_states structures self._setupMappedStates(state_tag) # By default, we use the binary_only class attribute, but we # ensure it is true if we are passed an arch tag or a name. binary_only = self.binary_only if self.text is not None or self.arch_tag is not None: binary_only = True # request context build records according to the selected state builds = self.context.getBuildRecords( build_state=self.state, name=self.text, arch_tag=self.arch_tag, user=self.user, binary_only=binary_only) self.batchnav = BatchNavigator( builds, self.request, range_factory=self.range_factory(builds)) # We perform this extra step because we don't what to issue one # extra query to retrieve the BuildQueue for each Build (batch item) # A more elegant approach should be extending Batching class and # integrating the fix into it. However the current solution is # simpler and shorter, producing the same result. cprov 20060810 self.complete_builds = setupCompleteBuilds( self.batchnav.currentBatch())
def initialize(self, series, translationgroup): self.series = series self.translationgroup = translationgroup self.form = self.request.form if IDistroSeriesLanguage.providedBy(self.context): self.batchnav = BatchNavigator( self.series.getCurrentTranslationTemplates(), self.request) self.pofiles = self.context.getPOFilesFor( self.batchnav.currentBatch()) load_related( SourcePackageName, self.batchnav.currentBatch(), ['sourcepackagenameID']) else: self.batchnav = BatchNavigator(self.context.pofiles, self.request) self.pofiles = self.batchnav.currentBatch()
def members(self): """Return a batch navigator for all members. This batch does not test for whether the person has specifications or not. """ members = self.context.allmembers batch_nav = BatchNavigator(members, self.request, size=20) return batch_nav
def batchnav(self): """Iterate over person's translation_history.""" translations_person = ITranslationsPerson(self.context) batchnav = BatchNavigator(translations_person.translation_history, self.request) pofiletranslatorset = getUtility(IPOFileTranslatorSet) batch = batchnav.currentBatch() self._pofiletranslator_cache = ( pofiletranslatorset.prefetchPOFileTranslatorRelations(batch)) return batchnav
def searchResults(self): """Return the questions corresponding to the search.""" if self.search_params is None: # Search button wasn't clicked, use the default filter. # Copy it so that it doesn't get mutated accidently. self.search_params = dict(self.getDefaultFilter()) # The search parameters used is defined by the union of the fields # present in ISearchQuestionsForm (search_text, status, sort) and the # ones defined in getDefaultFilter() which varies based on the # concrete view class. question_collection = IQuestionCollection(self.context) return BatchNavigator( question_collection.searchQuestions(**self.search_params), self.request)
def search_results(self): """Process search form request.""" if self.name_filter is None: return None # Preserve self.show_inactive state because it's used in the # template and build a boolean field to be passed for # searchPPAs. show_inactive = (self.show_inactive == 'on') ppas = self.context.searchPPAs(text=self.name_filter, show_inactive=show_inactive, user=self.user) self.batchnav = BatchNavigator(ppas, self.request) return self.batchnav.currentBatch()
def assertEmptyResultSetsWorking(self, range_factory): # getSlice() and getSliceByIndex() return empty ShadowedLists. sliced = range_factory.getSlice(1) self.assertEqual([], sliced.values) self.assertEqual([], sliced.shadow_values) sliced = range_factory.getSliceByIndex(0, 1) self.assertEqual([], sliced.values) self.assertEqual([], sliced.shadow_values) # The endpoint memos are empty strings. request = LaunchpadTestRequest() batchnav = BatchNavigator( range_factory.resultset, request, size=3, range_factory=range_factory) first, last = range_factory.getEndpointMemos(batchnav.batch) self.assertEqual('', first) self.assertEqual('', last)
def initialize(self): """Ensure that we are dealing with a private archive.""" # If this archive is not private, then we should not be # managing the subscribers. if not self.context.private: self.request.response.addNotification( "Only private archives can have subscribers.") self.request.response.redirect(canonical_url(self.context)) return super(ArchiveSubscribersView, self).initialize() subscription_set = getUtility(IArchiveSubscriberSet) self.subscriptions = subscription_set.getByArchive(self.context) self.batchnav = BatchNavigator(self.subscriptions, self.request, range_factory=StormRangeFactory( self.subscriptions))
def test_getEndpointMemos__decorated_result_set(self): # getEndpointMemos() works for DecoratedResultSet # instances too. resultset = self.makeDecoratedStormResultSet() resultset.order_by(LibraryFileAlias.id) range_factory = StormRangeFactory(resultset) request = LaunchpadTestRequest() batchnav = BatchNavigator( resultset, request, size=3, range_factory=range_factory) first, last = range_factory.getEndpointMemos(batchnav.batch) expected_first = simplejson.dumps( [resultset.get_plain_result_set()[0][1].id], cls=DateTimeJSONEncoder) expected_last = simplejson.dumps( [resultset.get_plain_result_set()[2][1].id], cls=DateTimeJSONEncoder) self.assertEqual(expected_first, first) self.assertEqual(expected_last, last)
def test_getEndpointMemos(self): # getEndpointMemos() returns JSON representations of the # sort fields of the first and last element of a batch. resultset = self.makeStormResultSet() resultset.order_by(Person.name) range_factory = StormRangeFactory(resultset) memo_value = range_factory.getOrderValuesFor(resultset[0]) request = LaunchpadTestRequest( QUERY_STRING='memo=%s' % simplejson.dumps(memo_value)) batchnav = BatchNavigator( resultset, request, size=3, range_factory=range_factory) first, last = range_factory.getEndpointMemos(batchnav.batch) expected_first = simplejson.dumps( [resultset[1].name], cls=DateTimeJSONEncoder) expected_last = simplejson.dumps( [resultset[3].name], cls=DateTimeJSONEncoder) self.assertEqual(expected_first, first) self.assertEqual(expected_last, last)
def setupQueueList(self): """Setup a batched queue list. Returns None, so use tal:condition="not: view/setupQueueList" to invoke it in template. """ # recover selected queue state and name filter self.name_filter = self.request.get('queue_text', '') try: state_value = int(self.request.get('queue_state', '')) except ValueError: state_value = PackageUploadStatus.NEW.value try: self.state = PackageUploadStatus.items[state_value] except KeyError: raise UnexpectedFormData( 'No suitable status found for value "%s"' % state_value) self.queue = self.context.getPackageUploadQueue(self.state) valid_states = [ PackageUploadStatus.NEW, PackageUploadStatus.ACCEPTED, PackageUploadStatus.REJECTED, PackageUploadStatus.DONE, PackageUploadStatus.UNAPPROVED, ] self.filtered_options = [] for state in valid_states: selected = (state == self.state) self.filtered_options.append( dict(name=state.title, value=state.value, selected=selected)) queue_items = self.context.getPackageUploads(status=self.state, name=self.name_filter) self.batchnav = BatchNavigator(queue_items, self.request, size=QUEUE_SIZE)
def initialize(self): """See `LaunchpadView`.""" self.person = None person = self.request.form.get('person') if person is None: self.request.response.addErrorNotification( "No person to filter by specified.") translations = None else: self.person = getUtility(IPersonSet).getByName(person) if self.person is None: self.request.response.addErrorNotification( "Requested person not found.") translations = None else: translations = self.context.getTranslationsFilteredBy( person=self.person) self.batchnav = BatchNavigator(translations, self.request, size=self.DEFAULT_BATCH_SIZE)
def initialize(self): if IPerson.providedBy(self.context): self.is_person = True elif IDistribution.providedBy(self.context): self.is_target = True self.is_pillar = True self.show_series = True elif IProduct.providedBy(self.context): self.is_target = True self.is_pillar = True self.has_wiki = True self.show_series = True elif IProjectGroup.providedBy(self.context): self.is_project = True self.is_pillar = True self.has_wiki = True self.show_target = True self.show_series = True elif IProjectGroupSeries.providedBy(self.context): self.show_milestone = True self.show_target = True self.show_series = True elif (IProductSeries.providedBy(self.context) or IDistroSeries.providedBy(self.context)): self.is_series = True self.show_milestone = True elif ISprint.providedBy(self.context): self.is_sprint = True self.show_target = True else: raise AssertionError('Unknown blueprint listing site.') if IHasDrivers.providedBy(self.context): self.has_drivers = True self.batchnav = BatchNavigator( self.specs, self.request, size=config.launchpad.default_batch_size)
def subscribedBugTasks(self): """ Return a BatchNavigator for distinct bug tasks to which the person is subscribed. """ bug_tasks = self.context.searchTasks( None, user=self.user, order_by='-date_last_updated', status=(BugTaskStatus.NEW, BugTaskStatus.INCOMPLETE, BugTaskStatus.CONFIRMED, BugTaskStatus.TRIAGED, BugTaskStatus.INPROGRESS, BugTaskStatus.FIXCOMMITTED, BugTaskStatus.INVALID), bug_subscriber=self.context) sub_bug_tasks = [] sub_bugs = set() # XXX: GavinPanella 2010-10-08 bug=656904: This materializes the # entire result set. It would probably be more efficient implemented # with a pre_iter_hook on a DecoratedResultSet. for task in bug_tasks: # We order the bugtasks by date_last_updated but we always display # the default task for the bug. This is to avoid ordering issues # in tests and also prevents user confusion (because nothing is # more confusing than your subscription targets changing seemingly # at random). if task.bug not in sub_bugs: # XXX: GavinPanella 2010-10-08 bug=656904: default_bugtask # causes a query to be executed. It would be more efficient to # get the default bugtask in bulk, in a pre_iter_hook on a # DecoratedResultSet perhaps. sub_bug_tasks.append(task.bug.default_bugtask) sub_bugs.add(task.bug) return BatchNavigator(sub_bug_tasks, self.request)
def __call__(self): name = self.request.form.get('name') if name is None: raise MissingInputError('name', '') search_text = self.request.form.get('search_text') if search_text is None: raise MissingInputError('search_text', '') search_filter = self.request.form.get('search_filter') try: factory = getUtility(IVocabularyFactory, name) except ComponentLookupError: raise UnexpectedFormData( 'Unknown vocabulary %r' % name) vocabulary = factory(self.context) if IHugeVocabulary.providedBy(vocabulary): matches = vocabulary.searchForTerms(search_text, search_filter) total_size = matches.count() else: matches = list(vocabulary) total_size = len(matches) batch_navigator = BatchNavigator(matches, self.request) # We need to collate what IPickerEntrySource adapters are required for # the items in the current batch. We expect that the batch will be # homogenous and so only one adapter instance is required, but we # allow for the case where the batch may contain disparate entries # requiring different adapter implementations. # A mapping from adapter class name -> adapter instance adapter_cache = {} # A mapping from adapter class name -> list of vocab terms picker_entry_terms = {} for term in batch_navigator.currentBatch(): picker_entry_source = IPickerEntrySource(term.value) adapter_class = picker_entry_source.__class__.__name__ picker_terms = picker_entry_terms.get(adapter_class) if picker_terms is None: picker_terms = [] picker_entry_terms[adapter_class] = picker_terms adapter_cache[adapter_class] = picker_entry_source picker_terms.append(term.value) # A mapping from vocab terms -> picker entries picker_term_entries = {} # For the list of terms associated with a picker adapter, we get the # corresponding picker entries by calling the adapter. for adapter_class, term_values in picker_entry_terms.items(): picker_entries = adapter_cache[adapter_class].getPickerEntries( term_values, self.context) for term_value, picker_entry in izip(term_values, picker_entries): picker_term_entries[term_value] = picker_entry result = [] for term in batch_navigator.currentBatch(): entry = dict(value=term.token, title=term.title) # The canonical_url without just the path (no hostname) can # be passed directly into the REST PATCH call. api_request = IWebServiceClientRequest(self.request) try: entry['api_uri'] = canonical_url( term.value, request=api_request, path_only_if_possible=True) except NoCanonicalUrl: # The exception is caught, because the api_url is only # needed for inplace editing via a REST call. The # form picker doesn't need the api_url. entry['api_uri'] = 'Could not find canonical url.' picker_entry = picker_term_entries[term.value] if picker_entry.description is not None: if len(picker_entry.description) > MAX_DESCRIPTION_LENGTH: entry['description'] = ( picker_entry.description[:MAX_DESCRIPTION_LENGTH - 3] + '...') else: entry['description'] = picker_entry.description if picker_entry.image is not None: entry['image'] = picker_entry.image if picker_entry.css is not None: entry['css'] = picker_entry.css if picker_entry.alt_title is not None: entry['alt_title'] = picker_entry.alt_title if picker_entry.title_link is not None: entry['title_link'] = picker_entry.title_link if picker_entry.details is not None: entry['details'] = picker_entry.details if picker_entry.alt_title_link is not None: entry['alt_title_link'] = picker_entry.alt_title_link if picker_entry.link_css is not None: entry['link_css'] = picker_entry.link_css if picker_entry.badges: entry['badges'] = picker_entry.badges if picker_entry.metadata is not None: entry['metadata'] = picker_entry.metadata if picker_entry.target_type is not None: entry['target_type'] = picker_entry.target_type result.append(entry) self.request.response.setHeader('Content-type', 'application/json') return simplejson.dumps(dict(total_size=total_size, entries=result))
def getAllBatched(self): return BatchNavigator(self.context.getAll(), self.request)
def getAllBatched(self): """A BatchNavigator instance with the submissions.""" submissions = getUtility(IHWSubmissionSet).getByFingerprintName( self.system_name, self.user) return BatchNavigator(submissions, self.request)
def initialize(self): self.batchnav = BatchNavigator(self.context.watches, self.request)
def batchnav(self): return BatchNavigator( getUtility(IWebhookSet).findByTarget(self.context), self.request)
def cached_unlinked_packages(self): """The batched `ISourcePackage`s that needs packaging links.""" packages = self.context.getPrioritizedUnlinkedSourcePackages() navigator = BatchNavigator(packages, self.request, size=20) navigator.setHeadings('package', 'packages') return navigator
def all_batched(self): return BatchNavigator(self.context.all, self.request)
def specs_batched(self): navigator = BatchNavigator(self.specs, self.request, size=500) navigator.setHeadings('specification', 'specifications') return navigator
def announcement_nav(self): return BatchNavigator(self.announcements, self.request, size=self.batch_size)
def deliveries(self): return BatchNavigator( self.context.deliveries, self.request, hide_counts=True, range_factory=StormRangeFactory(self.context.deliveries))
def milestone_batch_navigator(self): return BatchNavigator(self.context.all_milestones, self.request)
def cached_packagings(self): """The batched upstream packaging links.""" packagings = self.context.getPrioritizedPackagings() navigator = BatchNavigator(packagings, self.request, size=20) navigator.setHeadings('packaging', 'packagings') return navigator