def now(self, surname): """ Get the lesson for given person ``surname``. """ current_order = self.current_order() c.lesson = None if current_order is None: return render('now/now.xml') today = datetime.weekday(datetime.today()) schedule = Schedule.current() c.year = schedule.year students = Session.query(Student).\ filter(Student.last_name.like(surname)).all() teachers = Session.query(Educator).\ filter(Educator.last_name.like(surname)).all() people = students + teachers if len(people) != 1: c.people = people return render('now/list.xml') c.lesson = people[0].lesson(today, current_order, schedule.id) return render('now/now.xml')
def group_week(self, group_name, course_name=None): """ Render group's schedule for entire week. :param group_name: Full name of the group (including year index) :pram course_name: Optional name of the course """ schedule = Schedule.current() group = Group.by_full_name(group_name) if group is None: c.group_name = group_name return render('schedule/group/not_found.xml') gs = group.schedule(schedule.id) # Fetch the course schedule and merge it with group schedule if course_name is not None: course = Group.by_full_name(group_name[0] + course_name) c.course = course if course is None: c.group_name = group_name[0] + course_name return render('schedule/group/not_found.xml') else: cs = course.schedule(schedule.id) if cs is not None: for day_number, day in enumerate(cs): for order, lesson in enumerate(day): while len(gs[day_number]) < order + 1: gs[day_number].append(None) if gs[day_number][order] is None: gs[day_number][order] = lesson else: c.course = None c.courses = None if len(group_name) != 2: # group is not course from sqlalchemy import func q = Group.query_active().filter(Group.year_id == group.year_id).\ filter(func.length(Group.name) == 1).\ order_by(Group.name) c.courses = q.all() c.group = group c.group_name = group_name c.year = schedule.year c.schedule = gs return render('schedule/group/week.xml')
def group_week(self, group_name, course_name=None): """ Render group's schedule for entire week. :param group_name: Full name of the group (including year index) :pram course_name: Optional name of the course """ schedule = Schedule.current() group = Group.by_full_name(group_name) if group is None: c.group_name = group_name return render('schedule/group/not_found.xml') gs = group.schedule(schedule.id) # Fetch the course schedule and merge it with group schedule if course_name is not None: course = Group.by_full_name(group_name[0]+course_name) c.course = course if course is None: c.group_name = group_name[0]+course_name return render('schedule/group/not_found.xml') else: cs = course.schedule(schedule.id) if cs is not None: for day_number, day in enumerate(cs): for order, lesson in enumerate(day): while len(gs[day_number]) < order + 1: gs[day_number].append(None) if gs[day_number][order] is None: gs[day_number][order] = lesson else: c.course = None c.courses = None if len(group_name) != 2: # group is not course from sqlalchemy import func q = Group.query_active().filter(Group.year_id == group.year_id).\ filter(func.length(Group.name) == 1).\ order_by(Group.name) c.courses = q.all() c.group = group c.group_name = group_name c.year = schedule.year c.schedule = gs return render('schedule/group/week.xml')
def all(self): """ Render all lucky numbers. """ c.numbers = Session.query(LuckyNumber).order_by(LuckyNumber.date).all() return render('lucky/list.xml')
def left(self): """ Render left lucky numbers. """ c.numbers = LuckyNumber.left() return render('lucky/left.xml')
def document(self): """Render the error document""" resp = request.environ.get('pylons.original_response') content = literal(resp.body) or cgi.escape(request.GET.get('message', '')) c.code=cgi.escape(request.GET.get('code', str(resp.status_int))) c.message=content return render('error.xml')
def teacher(self, teacher_name, day_name=None): """ Render teacher's schedule for the given day. :param teacher_name: Surname of the teacher :param day_name: Name of the day """ day = self._translate_weekday(day_name) if day is None: return 'Bad day!' try: teacher = Session.query(Educator).\ filter(Educator.last_name.like(teacher_name)).one() except MultipleResultsFound: # TODO: how to do that properly? return """Hey, too much teachers with given surname were found. Please report it to administrator!""" except NoResultFound: return "No such teacher!" schedule = Schedule.current() c.teacher = teacher c.year = schedule.year c.lessons = teacher.schedule_for_day(day, schedule.id) return render('schedule/teacher.xml')
def add_week_form(self): """Displays a form for adding lucky numbers for one week (at most).""" today = datetime.date.today() weekday = datetime.date.weekday(today) # If it is Saturday or Sunday today, go to the next Monday if weekday > 4: monday = self._closest_working_day(today) else: monday = today - datetime.timedelta(weekday) # Find the first date a lucky number can be drown for last = LuckyNumber.last() if last.date < monday: c.first_date = monday else: c.first_date = self._closest_working_day(last.date) # Find the count of remaining days c.count = 5 - datetime.date.weekday(c.first_date) # Draw lucky numbers c.numbers = LuckyNumber.draw() # Not enough numbers to fill entire week if len(c.numbers) < c.count: c.count = len(c.numbers) return render('lucky/add_form.xml')
def current_week(self): """ Lucky numbers for current or next week. """ change_hour = 15 c.numbers = LuckyNumber.current_week(change_hour) return render('lucky/week.xml')
def group(self, group_name, day_name=None, course_name=None): """ Render group's schedule for the given day. Optionally with the course. :param group_name: Full name of the group (includeing year index) :param day_name: Name of the day :param course_name: Optional couse name """ schedule = Schedule.current() year = schedule.year group = Group.by_full_name(group_name) if group is None: c.group_name = group_name return render('schedule/group/not_found.xml') day = self._translate_weekday(day_name) if day is None: return 'Bad day!' gs = group.schedule_for_day(day, schedule.id) if course_name is not None: course_full_name = group_name[0] + course_name course = Group.by_full_name(course_full_name) if course is None: c.group_name = course_full_name return render('schedule/group/not_found.xml') else: cs = course.schedule_for_day(day, schedule.id) for o, lesson in enumerate(cs): while len(gs) < o + 1: gs.append(None) if gs[o] is None: gs[o] = lesson # TODO elif gs[o] is list c.course = course else: c.course = None c.group = group c.year = year c.lessons = gs return render('schedule/group.xml')
def search_form(self): """ Render search form. """ number = request.params.get("number", None) if number is not None: redirect(url('lucky_search', number=number)) return render('lucky/search.xml')
def date(self, date): """ Lucky number for the given date. :param date: Date in format: %Y-%m-%d """ date = date = datetime.datetime.strptime(date, '%Y-%m-%d') c.lucky = Session.query(LuckyNumber).filter_by(date=date).first() return render('lucky/current.xml')
def index(self): """ Render index page or redirect to now or now_id actions if surname is available in the request's params. """ if 'surname' in request.params: redirect(url('now_name', surname=request.params['surname'])) else: return render('now/index.xml')
def teacher_week(self, teacher_name): """ Render teacher's weekly schedule. :param teacher_name: Last name of the teacher """ teachers = Session.query(Educator).\ filter(Educator.last_name.like(teacher_name)).all() if len(teachers) != 1: c.teachers = teachers return render('schedule/teacher/list.xml') schedule = Schedule.current() c.year = schedule.year c.teacher = teachers[0] c.schedule = c.teacher.schedule(schedule.id) return render('schedule/teacher/week.xml')
def new(self, format='html'): """GET /substitutions/new: Form to create a new item""" # url('new_substitution') c.date = self._closest_working_day(datetime.date.today()) c.groups = Session.query(Group).join(Group.year).\ order_by(desc(SchoolYear.start), Group.name).all() c.educators = Session.query(Educator).\ order_by(Educator.last_name).all() c.year = SchoolYear.current() return render('substitutions/new.xml')
def now_id(self, id): """ Get the lesson for given person ``id``. """ current_order = self.current_order() if current_order is None: c.lesson = None return render('now/now.xml') today = datetime.weekday(datetime.today()) schedule = Schedule.current() c.year = schedule.year person = Session.query(Student).get(id) if not person: person = Session.query(Educator).get(id) c.lesson = person.lesson(today, current_order, schedule.id) return render('now/now.xml')
def teachers(self): """ Render full currently active teachers schedule table (every teacher and every weekday). """ schedule = Schedule.current() q = Educator.query_active(schedule_id=schedule.id).\ order_by(Educator.last_name) educators = [] for e in q.all(): s = e.schedule() educators.append((e, s)) c.year = schedule.year c.educators = educators return render('schedule/teacher/full_table.xml')
def search(self, number): """ Search lucky number. Redirect to form if invalid ``number`` :param number: Number to search for. """ schema = SearchLuckyForm() try: c.form_result = schema.to_python({'number' : number}) except formencode.Invalid, error: c.form_result = error.value c.form_errors = error.error_dict or {} html = render('lucky/search.xml') return htmlfill.render( html, defaults=c.form_result, errors=c.form_errors )
def groups(self): """ Render full currently active groups schedule (every group and every weekday). """ schedule = Schedule.current() q = Group.query_active(schedule_id=schedule.id).\ join((SchoolYear, Group.year_id == SchoolYear.id)).\ order_by(desc(SchoolYear.start), Group.name) groups = [] for g in q.all(): s = g.schedule(schedule.id) groups.append((g, s)) c.year = schedule.year c.groups = groups return render('schedule/group/full_table.xml')
def draw(self): c.numbers = LuckyNumber.draw() return render('lucky/draw.xml')
def index(self, format='html'): """GET /substitutions: All items in the collection""" # url('substitutions') c.subs = Session.query(Substitution).order_by(Substitution.date).all() return render('substitutions/list.xml')
def index(self): """ Render schedule management control panel. Handle POST redirects. """ day = request.params.get('day', None) group_name = request.params.get('group_name', None) course_name = request.params.get('course_name', None) teacher_last_name = request.params.get('teacher_last_name', None) if group_name is not None: if course_name is not None: if day == 'week': redirect( url('schedule_group_course_week', group_name=group_name, course_name=course_name)) elif day is not None: redirect( url('schedule_group_course', day_name=day, group_name=group_name, course_name=course_name)) else: redirect( url('schedule_group_course_today', group_name=group_name, course_name=course_name)) else: if day == 'week': redirect(url('schedule_group_week', group_name=group_name)) elif day is not None: redirect( url('schedule_group', day_name=day, group_name=group_name)) else: redirect(url('schedule_group_today', group_name=group_name)) if teacher_last_name is not None: if day == 'week': redirect( url('schedule_teacher_week', teacher_name=teacher_last_name)) elif day is not None: redirect( url('schedule_teacher', day_name=day, teacher_name=request.params.get('teacher_last_name'))) else: redirect( url('schedule_teacher_today', teacher_name=request.params.get('teacher_last_name'))) schedule = Schedule.current() c.year = schedule.year groups = Group.query_active(schedule.id).\ join((SchoolYear, Group.year_id == SchoolYear.id)).\ order_by(desc(SchoolYear.start), Group.name).all() courses = [] classes = [] for g in groups: if len(g.name) == 1 and g.name not in courses: courses.append(g.name) elif len(g.name) != 1 and g.name not in classes: classes.append(g.full_name(schedule.year)) courses.sort() classes.sort() teachers = Educator.query_active(schedule.id).\ order_by(Educator.last_name).all() c.groups = groups c.courses = courses c.classes = classes c.teachers = teachers return render('schedule/index.xml')
def table(self, date=None): """ Create a table of substitutions. This action tries to recreate table view as based on http://www.staszic.edu.pl/zastepstwa/. It gathers following data: 1. Which lessons do the group ussually have? 2. Which lessons do groups have in substitution? 3. Which groups (parts) are released (freed from the lesson) """ if date is None: date = self._closest_working_day(datetime.datetime.today()).date() else: date = datetime.datetime.strptime(date, '%Y-%m-%d').date() # Fetch substitutions from database q = Session.query(Substitution).filter_by(date=date) # Filter out pointless substitutions (those, which have both # parts set as False - no part is set) q = q.filter(not_(and_(Substitution.part1 == False, Substitution.part2 == False))) subs = q.all() # Create a dictionary of educators and their lessons by schedule # (before) and the new ones which are substitutes (after). before = {} after = {} # Create released groups dict: # keys are lesson orders and value is the list of released groups released = {} def fill(d, educator, order, fill): """ Helper function for filling the dict. It tries to fill as less data as possible so it merges parts intro groups. """ if not d.has_key(educator): d[educator] = {} e = d[educator] if not e.has_key(order): e[order] = [] o = e[order] g = fill[0] p = fill[1] if (g, None) in o: # We are trying to append part whereas entire group is present return if p is None: # We are appending entire group, delete "parted" entries for x in [1, 2]: try: o.remove((g, x)) except ValueError: pass o.append(fill) def opposite_substituted(subs, sub): """ Helper function for checking whether opposite group has been already substituted or the scheduled teacher is having a substituion which stops him from keeping the opposite group. It return True when both conditions are met: 1. Opposite group doesn't have any substituion on that hour and, 2. Scheduled teacher doesn't have any substition with other group. """ SUBSTITUTED = False EDUCATOR_FREE = True opposite_part = sub.part % 2 + 1 for s in subs: if s.order != sub.order: # We want only the same lesson order continue if s.group == sub.group and s.part == opposite_part: SUBSTITUTED = True break if s.teacher == lesson.teacher: EDUCATOR_FREE = False if not SUBSTITUTED and EDUCATOR_FREE: return True else: return False class ReleasedGroup(Exception): pass # Loop the substitutions for sub in subs: if sub.teacher is None: # Group is released for lesson in sub.group_lesson(): fill(before, lesson.teacher, lesson.order, (lesson.group, lesson.part)) if sub.part is not None and \ opposite_substituted(subs, sub): fill(after, lesson.teacher, lesson.order, (lesson.group, sub.part % 2 + 1)) if not released.has_key(sub.order): released[sub.order] = [] released[sub.order].append((sub.group, sub.part)) continue # What lesson does the group have normally? # And with which educator it is? for lesson in sub.group_lesson(): fill(before, lesson.teacher, lesson.order, (lesson.group, lesson.part)) if lesson.part is None and sub.part is not None: if opposite_substituted(subs, sub): fill(after, lesson.teacher, lesson.order, (lesson.group, sub.part % 2 + 1)) for lesson in sub.teacher_lesson(): fill(after, lesson.teacher, lesson.order, (lesson.group, lesson.part)) fill(after, sub.teacher, sub.order, (sub.group, sub.part)) c.debug = ("Substitutions for %s:\nbefore:\t\t%r\nafter:\t\t%r\n" + \ "released:\t%r") % (date, before, after, released) c.year = SchoolYear.current() c.date = date c.before = before c.after = after c.released = released return render('substitutions/table.xml')
def about(self): return render('pages/about.xml')
def current(self): # TODO This could be set in the settings file change_hour = 15 c.lucky = LuckyNumber.current(change_hour) return render('lucky/current.xml')
def index(self): return render('pages/index.xml')
def index(self): """ Render schedule management control panel. Handle POST redirects. """ day = request.params.get('day', None) group_name = request.params.get('group_name', None) course_name = request.params.get('course_name', None) teacher_last_name = request.params.get('teacher_last_name', None) if group_name is not None: if course_name is not None: if day == 'week': redirect(url('schedule_group_course_week', group_name=group_name, course_name=course_name)) elif day is not None: redirect(url('schedule_group_course', day_name=day, group_name=group_name, course_name=course_name)) else: redirect(url('schedule_group_course_today', group_name=group_name, course_name=course_name)) else: if day == 'week': redirect(url('schedule_group_week', group_name=group_name)) elif day is not None: redirect(url('schedule_group', day_name=day, group_name=group_name)) else: redirect(url('schedule_group_today', group_name=group_name)) if teacher_last_name is not None: if day == 'week': redirect(url('schedule_teacher_week', teacher_name=teacher_last_name)) elif day is not None: redirect(url('schedule_teacher', day_name=day, teacher_name=request.params.get('teacher_last_name'))) else: redirect(url('schedule_teacher_today', teacher_name=request.params.get('teacher_last_name'))) schedule = Schedule.current() c.year = schedule.year groups = Group.query_active(schedule.id).\ join((SchoolYear, Group.year_id == SchoolYear.id)).\ order_by(desc(SchoolYear.start), Group.name).all() courses = [] classes = [] for g in groups: if len(g.name) == 1 and g.name not in courses: courses.append(g.name) elif len(g.name) != 1 and g.name not in classes: classes.append(g.full_name(schedule.year)) courses.sort() classes.sort() teachers = Educator.query_active(schedule.id).\ order_by(Educator.last_name).all() c.groups = groups c.courses = courses c.classes = classes c.teachers = teachers return render('schedule/index.xml')
def table(self, date=None): """ Create a table of substitutions. This action tries to recreate table view as based on http://www.staszic.edu.pl/zastepstwa/. It gathers following data: 1. Which lessons do the group ussually have? 2. Which lessons do groups have in substitution? 3. Which groups (parts) are released (freed from the lesson) """ if date is None: date = self._closest_working_day(datetime.datetime.today()).date() else: date = datetime.datetime.strptime(date, '%Y-%m-%d').date() # Fetch substitutions from database q = Session.query(Substitution).filter_by(date=date) # Filter out pointless substitutions (those, which have both # parts set as False - no part is set) q = q.filter( not_(and_(Substitution.part1 == False, Substitution.part2 == False))) subs = q.all() # Create a dictionary of educators and their lessons by schedule # (before) and the new ones which are substitutes (after). before = {} after = {} # Create released groups dict: # keys are lesson orders and value is the list of released groups released = {} def fill(d, educator, order, fill): """ Helper function for filling the dict. It tries to fill as less data as possible so it merges parts intro groups. """ if not d.has_key(educator): d[educator] = {} e = d[educator] if not e.has_key(order): e[order] = [] o = e[order] g = fill[0] p = fill[1] if (g, None) in o: # We are trying to append part whereas entire group is present return if p is None: # We are appending entire group, delete "parted" entries for x in [1, 2]: try: o.remove((g, x)) except ValueError: pass o.append(fill) def opposite_substituted(subs, sub): """ Helper function for checking whether opposite group has been already substituted or the scheduled teacher is having a substituion which stops him from keeping the opposite group. It return True when both conditions are met: 1. Opposite group doesn't have any substituion on that hour and, 2. Scheduled teacher doesn't have any substition with other group. """ SUBSTITUTED = False EDUCATOR_FREE = True opposite_part = sub.part % 2 + 1 for s in subs: if s.order != sub.order: # We want only the same lesson order continue if s.group == sub.group and s.part == opposite_part: SUBSTITUTED = True break if s.teacher == lesson.teacher: EDUCATOR_FREE = False if not SUBSTITUTED and EDUCATOR_FREE: return True else: return False class ReleasedGroup(Exception): pass # Loop the substitutions for sub in subs: if sub.teacher is None: # Group is released for lesson in sub.group_lesson(): fill(before, lesson.teacher, lesson.order, (lesson.group, lesson.part)) if sub.part is not None and \ opposite_substituted(subs, sub): fill(after, lesson.teacher, lesson.order, (lesson.group, sub.part % 2 + 1)) if not released.has_key(sub.order): released[sub.order] = [] released[sub.order].append((sub.group, sub.part)) continue # What lesson does the group have normally? # And with which educator it is? for lesson in sub.group_lesson(): fill(before, lesson.teacher, lesson.order, (lesson.group, lesson.part)) if lesson.part is None and sub.part is not None: if opposite_substituted(subs, sub): fill(after, lesson.teacher, lesson.order, (lesson.group, sub.part % 2 + 1)) for lesson in sub.teacher_lesson(): fill(after, lesson.teacher, lesson.order, (lesson.group, lesson.part)) fill(after, sub.teacher, sub.order, (sub.group, sub.part)) c.debug = ("Substitutions for %s:\nbefore:\t\t%r\nafter:\t\t%r\n" + \ "released:\t%r") % (date, before, after, released) c.year = SchoolYear.current() c.date = date c.before = before c.after = after c.released = released return render('substitutions/table.xml')
def index(self): change_hour = 15 c.current = LuckyNumber.current(change_hour) c.week = LuckyNumber.current_week(change_hour) c.left = LuckyNumber.left() return render('lucky/index.xml')
def login(self): c.came_from = str(request.params.get('came_from', '')) or url('/') return render('auth/login_form.xml')