class Course(Model): """A course – ordered collection of sessions""" def __str__(self): return '{} - {}'.format(self.slug, self.title) info = YamlProperty() title = DataProperty(info) description = DataProperty(info) long_description = DataProperty(info) vars = DataProperty(info) subtitle = DataProperty(info, default=None) time = DataProperty(info, default=None) place = DataProperty(info, default=None) canonical = DataProperty(info, default=False) derives = DataProperty(info, default=None) @reify def slug(self): directory = self.path.parts[-1] parent_directory = self.path.parts[-2] if parent_directory == "courses": parent_directory = "course" # legacy URL return parent_directory + "/" + directory @reify def sessions(self): base_collection = self.info.get('base_collection') return _get_sessions(self, self.info['plan'], base_collection) @reify def edit_path(self): return self.path.relative_to(self.root.path) / "info.yml"
class Course(Model): """A course – ordered collection of sessions""" def __str__(self): return '{} - {}'.format(self.slug, self.title) info = YamlProperty() title = DataProperty(info) description = DataProperty(info) long_description = DataProperty(info) # Only runs use this: vars = DataProperty(info) subtitle = DataProperty(info, default=None) time = DataProperty(info, default=None) place = DataProperty(info, default=None) @reify def slug(self): if self.place is not None: return '/'.join(self.path.parts[-2:]) return self.path.parts[-1] @reify def sessions(self): base_collection = self.info.get('base_collection') return _get_sessions(self, self.info['plan'], base_collection) @reify def edit_path(self): return self.path.relative_to(self.root.path) / "info.yml"
class Session(Model): """An ordered collection of materials""" def __init__(self, root, path, info, base_collection=None): super().__init__(root, path) self.info = info self.base_collection = base_collection # self.prev and self.next are set later def __str__(self): return self.title info = YamlProperty() title = DataProperty(info) slug = DataProperty(info) date = DataProperty(info, default=None) @reify def materials(self): materials = [material(self.root, self.path, s, self.base_collection) for s in self.info['materials']] materials_with_nav = [mat for mat in materials if mat.has_navigation] for prev, current, next in zip([None] + materials_with_nav, materials_with_nav, materials_with_nav[1:] + [None] ): current.set_prev_next(prev, next) return materials
class Lesson(Model): """An individual lesson stored on naucse""" def __str__(self): return '{} - {}'.format(self.slug, self.title) info = YamlProperty() title = DataProperty(info) @reify def slug(self): return '/'.join(self.path.parts[-2:]) @reify def pages(self): pages = dict(self.info.get('subpages', {})) pages.setdefault('index', {}) return { slug: Page(self, slug, self.info, p) for slug, p in pages.items() } @reify def index_page(self): return self.pages['index']
class License(Model): def __str__(self): return self.path.parts[-1] info = YamlProperty() title = DataProperty(info) url = DataProperty(info)
class Session(Model): """An ordered collection of materials""" def __init__(self, root, path, base_course, info): super().__init__(root, path) base_name = info.get('base') if base_name is None: self.info = info else: base = base_course.sessions[base_name].info self.info = merge_dict(base, info) # self.prev and self.next are set later def __str__(self): return self.title info = YamlProperty() title = DataProperty(info) slug = DataProperty(info) date = DataProperty(info, default=None) @reify def materials(self): materials = [ material(self.root, self.path, s) for s in self.info['materials'] ] materials_with_nav = [mat for mat in materials if mat.has_navigation] for prev, current, next in zip([None] + materials_with_nav, materials_with_nav, materials_with_nav[1:] + [None]): current.set_prev_next(prev, next) return materials def get_edit_path(self, run, coverpage): coverpage_path = self.path / "sessions" / self.slug / (coverpage + ".md") if coverpage_path.exists(): return coverpage_path.relative_to(self.root.path) return run.edit_path def get_coverpage_content(self, run, coverpage, app): coverpage += ".md" q = self.path / 'sessions' / self.slug / coverpage try: with q.open() as f: md_content = f.read() except FileNotFoundError: return "" html_content = convert_markdown(md_content) return html_content
class Course(Model): """A course – ordered collection of sessions""" def __str__(self): return '{} - {}'.format(self.slug, self.title) info = YamlProperty() title = DataProperty(info) description = DataProperty(info) long_description = DataProperty(info) vars = DataProperty(info) subtitle = DataProperty(info, default=None) time = DataProperty(info, default=None) place = DataProperty(info, default=None) canonical = DataProperty(info, default=False) @reify def base_course(self): name = self.info.get('derives') if name is None: return None return self.root.courses[name] @reify def slug(self): directory = self.path.parts[-1] parent_directory = self.path.parts[-2] if parent_directory == "courses": parent_directory = "course" # legacy URL return parent_directory + "/" + directory @reify def sessions(self): return _get_sessions(self, self.info['plan']) @reify def edit_path(self): return self.path.relative_to(self.root.path) / "info.yml" @reify def start_date(self): dates = [s.date for s in self.sessions.values() if s.date is not None] if not dates: return None return min(dates) @reify def end_date(self): dates = [s.date for s in self.sessions.values() if s.date is not None] if not dates: return None return max(dates)
class Course(Model): """A course – ordered collection of sessions""" def __str__(self): return self.slug info = YamlProperty() title = DataProperty(info) description = DataProperty(info) long_description = DataProperty(info) @reify def slug(self): return self.path.parts[-1] @reify def sessions(self): base_collection = self.info.get('base_collection') return _get_sessions(self, self.info['plan'], base_collection)
class Run(Model): """A run""" def __str__(self): return '{} - {}'.format(self.slug, self.title) info = YamlProperty() title = DataProperty(info) subtitle = DataProperty(info) description = DataProperty(info) long_description = DataProperty(info) vars = DataProperty(info) @reify def sessions(self): base_collection = self.info.get('base_collection') return _get_sessions(self, self.info['plan'], base_collection) @reify def slug(self): return '/'.join(self.path.parts[-2:])
class Course(Model): """A course – ordered collection of sessions""" def __str__(self): return '{} - {}'.format(self.slug, self.title) info = YamlProperty() title = DataProperty(info) description = DataProperty(info) long_description = DataProperty(info) vars = DataProperty(info) subtitle = DataProperty(info, default=None) time = DataProperty(info, default=None) place = DataProperty(info, default=None) canonical = DataProperty(info, default=False) @reify def base_course(self): name = self.info.get('derives') if name is None: return None return self.root.courses[name] @reify def slug(self): directory = self.path.parts[-1] parent_directory = self.path.parts[-2] if parent_directory == "courses": parent_directory = "course" # legacy URL return parent_directory + "/" + directory @reify def sessions(self): return _get_sessions(self, self.info['plan']) @reify def edit_path(self): return self.path.relative_to(self.root.path) / "info.yml" @reify def start_date(self): dates = [s.date for s in self.sessions.values() if s.date is not None] if not dates: return None return min(dates) @reify def end_date(self): dates = [s.date for s in self.sessions.values() if s.date is not None] if not dates: return None return max(dates) def _default_time(self, key): default_time = self.info.get('default_time') if default_time: time_string = default_time[key] hour, minute = time_string.split(':') hour = int(hour) minute = int(minute) tzinfo = dateutil.tz.gettz(_TIMEZONE) return datetime.time(hour, minute, tzinfo=tzinfo) return None @reify def default_start_time(self): return self._default_time('start') @reify def default_end_time(self): return self._default_time('end')