class FlourishReportReferenceView(WideContainerPage, ReportReferenceView): def done_link(self): return absoluteURL(self.context, self.request) + '/manage' def rows(self): self.collator = ICollator(self.request.locale) utility = getReportRegistrationUtility() app = self.context rows = {} for group_key, group_reports in utility.reports_by_group.items(): reference_url = reportLinksURL(app, self.request, name=group_key) for report in group_reports: group = report['group'] name = report['name'] row = { 'url': reference_url, 'group': group, 'title': report['title'], 'file_type': report['file_type'].upper(), 'description': report['description'], } # XXX: this check is needed to override old skin # report links with flourish ones if (group, name) not in rows or \ report['layer'] is IFlourishLayer: rows[group, name] = row return sorted(rows.values(), key=self.sortKey) def sortKey(self, row): return self.collator.key(row['group']), self.collator.key(row['title'])
def update(self): self.collator = ICollator(self.request.locale) groups = [ group for group in self.context.groups if (canAccess(group, 'title') and not ISection.providedBy(group)) ] schoolyears_data = {} for group in groups: sy = ISchoolYear(group.__parent__) if sy not in schoolyears_data: schoolyears_data[sy] = [] schoolyears_data[sy].append(group) self.schoolyears = [] for sy in sorted(schoolyears_data, key=lambda x: x.first, reverse=True): sy_info = { 'obj': sy, 'groups': sorted(schoolyears_data[sy], cmp=self.collator.cmp, key=lambda x: x.title) } self.schoolyears.append(sy_info)
class FlourishGroupsViewlet(Viewlet, ActiveSchoolYearContentMixin): """A flourish viewlet showing the groups a person is in.""" template = ViewPageTemplateFile('templates/f_groupsviewlet.pt') render = lambda self, *a, **kw: self.template(*a, **kw) def app_states(self, key): app = ISchoolToolApplication(None) states = IRelationshipStateContainer(app)[key] return states def group_current_states(self, link_info, app_states): states = [] for date, active, code in link_info.state.all(): state = app_states.states.get(code) title = state.title if state is not None else '' states.append({ 'date': date, 'title': title, }) return states def update(self): self.collator = ICollator(self.request.locale) relationships = Membership.bind(member=self.context).all().relationships group_states = self.app_states('group-membership') student_states = self.app_states('student-enrollment') schoolyears_data = {} for link_info in relationships: group = removeSecurityProxy(link_info.target) if ISection.providedBy(group) or not canAccess(group, 'title'): continue sy = ISchoolYear(group.__parent__) if sy not in schoolyears_data: schoolyears_data[sy] = [] schoolyears_data[sy].append((group, link_info)) self.schoolyears = [] for sy in sorted(schoolyears_data, key=lambda x:x.first, reverse=True): sy_info = { 'obj': sy, 'css_class': 'active' if sy is self.schoolyear else 'inactive', 'groups': [], } for group, link_info in sorted(schoolyears_data[sy], key=lambda x:self.collator.key( x[0].title)): is_students = group.__name__ == 'students' app_states = student_states if is_students else group_states states = self.group_current_states(link_info, app_states) group_info = { 'obj': group, 'title': group.title, 'states': states, } sy_info['groups'].append(group_info) self.schoolyears.append(sy_info) @property def canModify(self): return canAccess(self.context.__parent__, '__delitem__')
def update(self): self.collator = ICollator(self.request.locale) relationships = Membership.bind(member=self.context).all().relationships group_states = self.app_states('group-membership') student_states = self.app_states('student-enrollment') schoolyears_data = {} for link_info in relationships: group = removeSecurityProxy(link_info.target) if ISection.providedBy(group) or not canAccess(group, 'title'): continue sy = ISchoolYear(group.__parent__) if sy not in schoolyears_data: schoolyears_data[sy] = [] schoolyears_data[sy].append((group, link_info)) self.schoolyears = [] for sy in sorted(schoolyears_data, key=lambda x:x.first, reverse=True): sy_info = { 'obj': sy, 'css_class': 'active' if sy is self.schoolyear else 'inactive', 'groups': [], } for group, link_info in sorted(schoolyears_data[sy], key=lambda x:self.collator.key( x[0].title)): is_students = group.__name__ == 'students' app_states = student_states if is_students else group_states states = self.group_current_states(link_info, app_states) group_info = { 'obj': group, 'title': group.title, 'states': states, } sy_info['groups'].append(group_info) self.schoolyears.append(sy_info)
def persons(self): collator = ICollator(self.request.locale) factory = getUtility(IPersonFactory) sorting_key = lambda x: factory.getSortingKey(x, collator) sorted_persons = sorted(self.context.members, key=sorting_key) result = [self.getPersonData(person) for person in sorted_persons] return result
def activeSchoolyearInfo(self): result = {} request = self.request collator = ICollator(request.locale) activeSchoolyear = self.context.getActiveSchoolYear() if activeSchoolyear is not None: result['title'] = activeSchoolyear.title result['hasCourses'] = self.hasCourses(activeSchoolyear) result['hasTimetables'] = self.hasTimetableSchemas( activeSchoolyear) result['groups'] = [] groups = IGroupContainer(activeSchoolyear) for groupId, group in sorted(groups.items(), cmp=collator.cmp, key=lambda (groupId, group): group.title): info = {} info['id'] = groupId info['title'] = group.title info['isDefault'] = groupId in defaultGroups info['hasMembers'] = bool(list(group.members)) info['sent'] = groupId in self.customGroupsToImport info['membersSent'] = groupId in self.groupsWithMembersToImport result['groups'].append(info) return result
class IndexedLocaleAwareGetterColumn(IndexedGetterColumn): _cached_collator = None def getSortKey(self, item, formatter): if not self._cached_collator: self._cached_collator = ICollator(formatter.request.locale) s = super(IndexedLocaleAwareGetterColumn, self).getSortKey(item, formatter) return s and self._cached_collator.key(s)
def rows(self): collator = ICollator(self.request.locale) utility = getReportRegistrationUtility() app = self.context rows = [] for group_key, group_reports in utility.reports_by_group.items(): reference_url = reportLinksURL(app, self.request, name=group_key) for report in group_reports: row = { 'url': reference_url, 'group': report['group'], 'title': report['title'], 'description': report['description'], } rows.append([collator.key(report['group']), collator.key(report['title']), row]) return [row for group, title, row in sorted(rows)]
def ptos(self): collator = ICollator(self.request.locale) ptos_dict = {} for resource in sorted(self.context.values(), key=lambda x:collator.key(x.title)): if ILocation(resource, None) is not None: resource_type = _('Location') elif IEquipment(resource, None) is not None: resource_type = _('Equipment') else: resource_type = _('Resource') pto = ptos_dict.setdefault(resource_type, { 'type': resource_type, 'rows': [], }) pto['rows'].append({ 'title': resource.title, 'description': resource.description, }) return [ptos_dict[k] for k in sorted(ptos_dict.keys(), key=lambda x:collator.key(x))]
def ptos(self): collator = ICollator(self.request.locale) ptos_dict = {} for resource in sorted(self.context.values(), key=lambda x: collator.key(x.title)): if ILocation(resource, None) is not None: resource_type = _('Location') elif IEquipment(resource, None) is not None: resource_type = _('Equipment') else: resource_type = _('Resource') pto = ptos_dict.setdefault(resource_type, { 'type': resource_type, 'rows': [], }) pto['rows'].append({ 'title': resource.title, 'description': resource.description, }) return [ ptos_dict[k] for k in sorted(ptos_dict.keys(), key=lambda x: collator.key(x)) ]
def update(self): self.collator = ICollator(self.request.locale) relationships = Membership.bind( member=self.context).all().relationships group_states = self.app_states('group-membership') student_states = self.app_states('student-enrollment') schoolyears_data = {} for link_info in relationships: group = removeSecurityProxy(link_info.target) if ISection.providedBy(group) or not canAccess(group, 'title'): continue sy = ISchoolYear(group.__parent__) if sy not in schoolyears_data: schoolyears_data[sy] = [] schoolyears_data[sy].append((group, link_info)) self.schoolyears = [] for sy in sorted(schoolyears_data, key=lambda x: x.first, reverse=True): sy_info = { 'obj': sy, 'css_class': 'active' if sy is self.schoolyear else 'inactive', 'groups': [], } for group, link_info in sorted( schoolyears_data[sy], key=lambda x: self.collator.key(x[0].title)): is_students = group.__name__ == 'students' app_states = student_states if is_students else group_states states = self.group_current_states(link_info, app_states) group_info = { 'obj': group, 'title': group.title, 'states': states, } sy_info['groups'].append(group_info) self.schoolyears.append(sy_info)
def groups(self): groups = [] container = self.groupContainer() collator = ICollator(self.request.locale) group_items = sorted(container.items(), cmp=collator.cmp, key=lambda (gid, g): g.title) for id, group in group_items: if len(group.members) > 0: groups.append({ 'id': id, 'title': "%s (%s)" % (group.title, len(group.members)) }) return groups
def __init__(self, *args, **kw): super(FlourishCoursesViewlet, self).__init__(*args, **kw) self.collator = ICollator(self.request.locale)
class FlourishCoursesViewlet(Viewlet, ActiveSchoolYearContentMixin): """A flourish viewlet showing the courses a person is in.""" template = ViewPageTemplateFile('templates/f_coursesviewlet.pt') render = lambda self, *a, **kw: self.template(*a, **kw) def __init__(self, *args, **kw): super(FlourishCoursesViewlet, self).__init__(*args, **kw) self.collator = ICollator(self.request.locale) def update(self): self.instructorOf = self.sectionsAsTeacher() self.learnerOf = self.sectionsAsLearner() def isTeacher(self): """Find out if the person is an instructor for any sections.""" return bool(self.instructorOf) def isLearner(self): """Find out if the person is a member of any sections.""" return bool(self.learnerOf) def sectionsAsTeacher(self): """Get the sections the person instructs.""" app_states = self.app_states('section-instruction') relationships = Instruction.bind(instructor=self.context).all().relationships return self.sectionsAs(app_states, relationships) def sectionsAsLearner(self): """Get the sections the person is a member of.""" app_states = self.app_states('section-membership') relationships = Membership.bind(member=self.context).all().relationships return self.sectionsAs(app_states, relationships) def sectionsAs(self, app_states, relationships): schoolyears_data = {} for link_info in relationships: if not ISection.providedBy(link_info.target): continue section = removeSecurityProxy(link_info.target) sy = ISchoolYear(section) if sy not in schoolyears_data: schoolyears_data[sy] = {} term = ITerm(section) if term not in schoolyears_data[sy]: schoolyears_data[sy][term] = [] schoolyears_data[sy][term].append((section, link_info)) result = [] for sy in sorted(schoolyears_data, key=lambda x:x.first, reverse=True): sy_info = { 'obj': sy, 'css_class': 'active' if sy is self.schoolyear else 'inactive', 'terms': [], } for term in sorted(schoolyears_data[sy], key=lambda x:x.first, reverse=True): term_info = {'obj': term, 'sections': []} for section, link_info in sorted(schoolyears_data[sy][term], key=self.sortingKey): states = self.section_current_states( section, app_states, link_info) section_info = { 'obj': section, 'title': section.title, 'states': states, } term_info['sections'].append(section_info) sy_info['terms'].append(term_info) result.append(sy_info) return result def sortingKey(self, t): section, link = t course_title = ', '.join([c.title for c in section.courses]) return (self.collator.key(course_title), self.collator.key(section.title)) def app_states(self, key): app = ISchoolToolApplication(None) states = IRelationshipStateContainer(app)[key] return states def section_current_states(self, section, app_states, link_info): states = [] for date, active, code in link_info.state.all(): state = app_states.states.get(code) title = state.title if state is not None else '' states.append({ 'date': date, 'title': title, }) return states
class FlourishCompletedCoursesViewlet(Viewlet, ActiveSchoolYearContentMixin): """A flourish viewlet showing the courses a person completed.""" template = ViewPageTemplateFile('templates/f_completedcoursesviewlet.pt') body_template = None def __init__(self, *args, **kw): Viewlet.__init__(self, *args, **kw) self.collator = ICollator(self.request.locale) def render(self, *args, **kw): if not self.courses: return '' return self.template(*args, **kw) def update(self): self.courses = self.collectCourses() @property def completed_state_codes(self): app = ISchoolToolApplication(None) states = IRelationshipStateContainer(app)['section-membership'] codes = [state.code for state in states if states.overlap(COMPLETED, state.active)] return codes def collectCourses(self): today = self.request.util.today student=removeSecurityProxy(self.context) codes = self.completed_state_codes completed_sections = [ relationship.target for relationship in Membership.relationships(member=student) if relationship.state.has(today, codes) ] schoolyears_data = {} for section in completed_sections: section = removeSecurityProxy(section) sy = ISchoolYear(section) if sy not in schoolyears_data: schoolyears_data[sy] = {} term = ITerm(section) if term not in schoolyears_data[sy]: schoolyears_data[sy][term] = [] schoolyears_data[sy][term].extend(section.courses) result = [] sortingKey = lambda course: self.collator.key(course.title) for sy in sorted(schoolyears_data, key=lambda x:x.first, reverse=True): sy_info = { 'obj': sy, 'css_class': 'active' if sy is self.schoolyear else 'inactive', 'terms': [], } for term in sorted(schoolyears_data[sy], key=lambda x:x.first, reverse=True): term_info = {'obj': term, 'courses': []} for course in sorted(schoolyears_data[sy][term], key=sortingKey): course_info = { 'obj': course, 'title': course.title, } term_info['courses'].append(course_info) sy_info['terms'].append(term_info) result.append(sy_info) return result
def __init__(self, *args, **kw): Viewlet.__init__(self, *args, **kw) self.collator = ICollator(self.request.locale)
def getSortKey(self, item, formatter): collator = ICollator(formatter.request.locale) s = self.getter(item, formatter) return s and collator.key(s)
class FlourishGroupsViewlet(Viewlet, ActiveSchoolYearContentMixin): """A flourish viewlet showing the groups a person is in.""" template = ViewPageTemplateFile('templates/f_groupsviewlet.pt') render = lambda self, *a, **kw: self.template(*a, **kw) def app_states(self, key): app = ISchoolToolApplication(None) states = IRelationshipStateContainer(app)[key] return states def group_current_states(self, link_info, app_states): states = [] for date, active, code in link_info.state.all(): state = app_states.states.get(code) title = state.title if state is not None else '' states.append({ 'date': date, 'title': title, }) return states def update(self): self.collator = ICollator(self.request.locale) relationships = Membership.bind( member=self.context).all().relationships group_states = self.app_states('group-membership') student_states = self.app_states('student-enrollment') schoolyears_data = {} for link_info in relationships: group = removeSecurityProxy(link_info.target) if ISection.providedBy(group) or not canAccess(group, 'title'): continue sy = ISchoolYear(group.__parent__) if sy not in schoolyears_data: schoolyears_data[sy] = [] schoolyears_data[sy].append((group, link_info)) self.schoolyears = [] for sy in sorted(schoolyears_data, key=lambda x: x.first, reverse=True): sy_info = { 'obj': sy, 'css_class': 'active' if sy is self.schoolyear else 'inactive', 'groups': [], } for group, link_info in sorted( schoolyears_data[sy], key=lambda x: self.collator.key(x[0].title)): is_students = group.__name__ == 'students' app_states = student_states if is_students else group_states states = self.group_current_states(link_info, app_states) group_info = { 'obj': group, 'title': group.title, 'states': states, } sy_info['groups'].append(group_info) self.schoolyears.append(sy_info) @property def canModify(self): return canAccess(self.context.__parent__, '__delitem__')
class CoursesViewlet(ViewletBase): """A viewlet showing the courses a person is in.""" def __init__(self, *args, **kw): super(CoursesViewlet, self).__init__(*args, **kw) self.collator = ICollator(self.request.locale) def update(self): self.instructorOf = self.sectionsAsTeacher() self.learnerOf = self.sectionsAsLearner() def isTeacher(self): """Find out if the person is an instructor for any sections.""" return bool(self.instructorOf) def isLearner(self): """Find out if the person is a member of any sections.""" return bool(self.learnerOf) def sectionsAsTeacher(self): """Get the sections the person instructs.""" return self.sectionsAs(IInstructor) def sectionsAsLearner(self): """Get the sections the person is a member of.""" return self.sectionsAs(ILearner) def sectionsAs(self, role_interface): schoolyears_data = {} for section in role_interface(self.context).sections(): sy = ISchoolYear(section) if sy not in schoolyears_data: schoolyears_data[sy] = {} term = ITerm(section) if term not in schoolyears_data[sy]: schoolyears_data[sy][term] = [] schoolyears_data[sy][term].append(section) result = [] for sy in sorted(schoolyears_data, key=lambda x:x.first, reverse=True): sy_info = {'obj': sy, 'terms': []} for term in sorted(schoolyears_data[sy], key=lambda x:x.first): sortingKey = lambda section:{'course': ', '.join([course.title for course in section.courses]), 'section_title': section.title} term_info = {'obj': term, 'sections': []} for section in sorted(schoolyears_data[sy][term], cmp=self.sortByCourseAndSection, key=sortingKey): section_info = {'obj': section, 'title': '%s -- %s' % \ (', '.join(course.title for course in section.courses), section.title)} term_info['sections'].append(section_info) sy_info['terms'].append(term_info) result.append(sy_info) return result def sortByCourseAndSection(self, this, other): if this['course'] is other['course']: return self.collator.cmp(this['section_title'], other['section_title']) return self.collator.cmp(this['course'], other['course'])