71
from lp.blueprints.model.specificationsubscription import (
72
SpecificationSubscription,
70
74
from lp.registry.browser.branding import BrandingChangeView
71
75
from lp.registry.browser.menu import (
72
76
IRegistryCollectionNavigationMenu,
73
77
RegistryCollectionActionMenuBase,
79
from lp.registry.interfaces.person import IPersonSet
80
from lp.services.database.bulk import load_referencing
75
81
from lp.services.propertycache import cachedproperty
448
454
displayname=attendance.attendee.displayname,
449
455
start=attendance.time_starts.strftime('%Y-%m-%dT%H:%M:%SZ'),
450
456
end=attendance.time_ends.strftime('%Y-%m-%dT%H:%M:%SZ')))
451
attendee_set.add(attendance.attendee)
457
attendee_set.add(attendance.attendeeID)
453
self.specifications = []
454
for speclink in self.context.specificationLinks(
460
for spec in self.context.specifications(
455
461
filter=[SpecificationFilter.ACCEPTED]):
456
spec = speclink.specification
458
463
# skip sprints with no priority or less than low:
459
if (spec.priority is None or
460
spec.priority < SpecificationPriority.UNDEFINED):
464
if spec.priority < SpecificationPriority.UNDEFINED:
463
467
if (spec.definition_status not in
465
469
SpecificationDefinitionStatus.DISCUSSION,
466
470
SpecificationDefinitionStatus.DRAFT]):
472
model_specs.append(spec)
474
people = defaultdict(dict)
475
# Attendees per specification
476
for subscription in load_referencing(SpecificationSubscription,
477
model_specs, ['specificationID']):
478
if subscription.personID not in attendee_set:
480
people[subscription.specificationID][subscription.personID] = \
481
subscription.essential
482
# Spec specials - drafter/assignee. Don't need approver for performance
483
# as specifications() above eager loaded the people, and approvers
484
# don't count as a 'required person'.
485
for spec in model_specs:
469
486
# get the list of attendees that will attend the sprint
470
is_required = dict((sub.person, sub.essential)
471
for sub in spec.subscriptions)
472
interested = set(is_required.keys()).intersection(attendee_set)
473
if spec.assignee is not None:
474
interested.add(spec.assignee)
475
is_required[spec.assignee] = True
476
if spec.drafter is not None:
477
interested.add(spec.drafter)
478
is_required[spec.drafter] = True
479
interested = [dict(name=person.name,
480
required=is_required[person])
481
for person in interested]
483
self.specifications.append(dict(
485
interested=interested))
487
spec_people = people[spec.id]
488
if spec.assigneeID is not None:
489
spec_people[spec.assigneeID] = True
490
attendee_set.add(spec.assigneeID)
491
if spec.drafterID is not None:
492
spec_people[spec.drafterID] = True
493
attendee_set.add(spec.drafterID)
494
people_by_id = dict((person.id, person) for person in
495
getUtility(IPersonSet).getPrecachedPersonsFromIDs(attendee_set))
496
self.specifications = [
497
dict(spec=spec, interested=[
498
dict(name=people_by_id[person_id].name, required=required)
499
for (person_id, required) in people[spec.id].items()]
500
) for spec in model_specs]
487
502
def render(self):
488
503
self.request.response.setHeader('content-type',