Пример #1
0
    def check_rooms(self, exclude=[]):
        """
        Check for repetetive rooms, ie. when one room
        is occupied simultanously by two lessons.

        :param exclude: You can exclude specific room, eg. gym.
        :type excelud: :class:`list` of :class:`int`

        """
        stmt = Session.query(Lesson.room, Lesson.day, Lesson.order,
                             Lesson.schedule_id)
        stmt = stmt.group_by(Lesson.room, Lesson.order, Lesson.day,
                             Lesson.schedule_id)
        stmt = stmt.having(func.count(Lesson.room) > 1)
        stmt = stmt.filter(not_(Lesson.room.in_(exclude)))
        stmt = stmt.subquery()
        q = Session.query(Lesson).join(
            (stmt,
             and_(Lesson.room == stmt.c.room, Lesson.day == stmt.c.day,
                  Lesson.order == stmt.c.order,
                  Lesson.schedule_id == stmt.c.schedule_id)))
        q = q.order_by(Lesson.day, Lesson.order, Lesson.room)

        conflicts = q.all()
        if len(conflicts) == 0:
            return []
        rooms = [[conflicts.pop(0), conflicts.pop(0)]]
        for c in conflicts:
            prev = rooms[-1][-1]
            if c.room == prev.room and c.day == prev.day and c.order == \
            prev.order and c.schedule_id == prev.schedule_id:
                rooms[-1].append(c)
            else:
                rooms.append([c])
        return rooms
Пример #2
0
Файл: now.py Проект: kuba/SIS
    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')
Пример #3
0
Файл: now.py Проект: kuba/SIS
    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')
Пример #4
0
Файл: basic.py Проект: kuba/SIS
    def check_rooms(self, exclude=[]):
        """
        Check for repetetive rooms, ie. when one room
        is occupied simultanously by two lessons.

        :param exclude: You can exclude specific room, eg. gym.
        :type excelud: :class:`list` of :class:`int`

        """
        stmt = Session.query(Lesson.room, Lesson.day, Lesson.order,
            Lesson.schedule_id)
        stmt = stmt.group_by(Lesson.room, Lesson.order, Lesson.day, Lesson.schedule_id)
        stmt = stmt.having(func.count(Lesson.room)>1)
        stmt = stmt.filter(not_(Lesson.room.in_(exclude)))
        stmt = stmt.subquery()
        q = Session.query(Lesson).join((stmt, and_(
            Lesson.room == stmt.c.room,
            Lesson.day == stmt.c.day,
            Lesson.order == stmt.c.order,
            Lesson.schedule_id == stmt.c.schedule_id)))
        q = q.order_by(Lesson.day, Lesson.order, Lesson.room)

        conflicts = q.all()
        if len(conflicts) == 0:
            return []
        rooms = [[conflicts.pop(0), conflicts.pop(0)]]
        for c in conflicts:
            prev = rooms[-1][-1]
            if c.room == prev.room and c.day == prev.day and c.order == \
            prev.order and c.schedule_id == prev.schedule_id:
                rooms[-1].append(c)
            else:
                rooms.append([c])
        return rooms
Пример #5
0
 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')
Пример #6
0
 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')
Пример #7
0
 def delete(self, id):
     """DELETE /substitutions/id: Delete an existing item"""
     # Forms posted to this method should contain a hidden field:
     #    <input type="hidden" name="_method" value="DELETE" />
     # Or using helpers:
     #    h.form(url('substitution', id=ID),
     #           method='delete')
     # url('substitution', id=ID)
     s = Session.query(Substitution).get(id)
     Session.delete(s)
     Session.commit()
     redirect(url('substitutions'))
Пример #8
0
 def delete(self, id):
     """DELETE /substitutions/id: Delete an existing item"""
     # Forms posted to this method should contain a hidden field:
     #    <input type="hidden" name="_method" value="DELETE" />
     # Or using helpers:
     #    h.form(url('substitution', id=ID),
     #           method='delete')
     # url('substitution', id=ID)
     s = Session.query(Substitution).get(id)
     Session.delete(s)
     Session.commit()
     redirect(url('substitutions'))
Пример #9
0
 def teacher_lesson(self):
     """Get teacher's scheduled lesson."""
     day = datetime.date.weekday(self.date)
     query = Session.query(Lesson).filter_by(day=day,
                                             order=self.order,
                                             teacher_id=self.teacher.id)
     return query.all()
Пример #10
0
Файл: lucky.py Проект: kuba/SIS
    def all(self):
        """
        Render all lucky numbers.

        """
        c.numbers = Session.query(LuckyNumber).order_by(LuckyNumber.date).all()
        return render('lucky/list.xml')
Пример #11
0
    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')
Пример #12
0
    def current_week(cls, change_hour, now=None):
        """
        Return ``current week``'s lucky numbers.

        ``current week`` is defined based on the given ``now`` and
        ``change_hour`` If there are no more lucky numbers in the
        ``current week`` fetch lucky numbers from the next available week.

        :param change_hour: The hour that defines the end of the day.
        :type change_hour: :class:`int`

        :param now: One of the ``current week``'s days. If value is set to
                    None it will use real current datetime.
        :type now: :class:`datetime.datetime` or :class:`NoneType`

        """
        if now is None:
            now = datetime.datetime.now()

        if now.hour >= change_hour:
            closest_day = now.date() + datetime.timedelta(1)
        else:
            closest_day = now.date()
        closest_weekday = datetime.date.weekday(closest_day)

        # Retrieve the date of the first day in the week
        start_date = closest_day - datetime.timedelta(closest_weekday)
        first_week_end = start_date + datetime.timedelta(7)
        second_week_end = start_date + datetime.timedelta(14)

        q = Session.query(cls).filter(cls.date >= start_date)

        # Optmization. If the ``closest_day`` is 0 it is already new week,
        # no need to query next two weeks, only one.
        if closest_weekday == 0:
            q = q.limit(7)
        else:
            q = q.limit(14)

        # Fetch numbers from the database
        numbers = q.all()

        first_week = []
        second_week = []

        for number in numbers:
            if number.date < first_week_end:
                first_week.append(number)
            else:
                if len(second_week) == 0:
                    second_week_end = number.date + datetime.timedelta(7)
                if number.date < second_week_end:
                    second_week.append(number)

        # Check whether first week any more lucky numbers relatively to
        # the current closest day.
        if len(first_week) > 0 and first_week[-1].date >= closest_day:
            return first_week
        else:
            return second_week
Пример #13
0
    def current(cls, change_hour, now=None):
        """
        Return current lucky number.

        If the current hour is less than ``change_hour`` try to fetch lucky
        number for the same date. Otherwise fetch the closest lucky number.

        :param change_hour: The hour that defines the end of the day.
        :type change_hour: :class:`int`

        :param now: Fetch lucky number relatively to given datetime. If value
                    is set to None it will use real current datetime.
        :type now: :class:`datetime.datetime` or :class:`NoneType`

        """
        if now is None:
            now = datetime.datetime.now()

        if now.hour >= change_hour:
            start_date = now.date() + datetime.timedelta(1)
        else:
            start_date = now.date()

        lucky = Session.query(cls).\
                    filter(cls.date >= start_date).\
                    order_by(cls.date).first()
        return lucky
Пример #14
0
    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')
Пример #15
0
 def group_lesson(self):
     """Get group's scheduled lesson."""
     day = datetime.date.weekday(self.date)
     query = Session.query(Lesson).\
             filter_by(day=day, order=self.order, group_id=self.group_id). \
             filter(not_(and_(Lesson.first_part == False,
                              Lesson.second_part == False)))
     return query.all()
Пример #16
0
Файл: subs.py Проект: kuba/SIS
 def group_lesson(self):
     """Get group's scheduled lesson."""
     day = datetime.date.weekday(self.date)
     query = Session.query(Lesson).\
             filter_by(day=day, order=self.order, group_id=self.group_id). \
             filter(not_(and_(Lesson.first_part == False,
                              Lesson.second_part == False)))
     return query.all()
Пример #17
0
Файл: lucky.py Проект: kuba/SIS
    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')
Пример #18
0
Файл: now.py Проект: kuba/SIS
    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')
Пример #19
0
Файл: now.py Проект: kuba/SIS
    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')
Пример #20
0
Файл: basic.py Проект: kuba/SIS
    def query_active(cls, schedule_id=None):
        """
        Query educator with lessons in the schedule.

        """
        q = Session.query(cls).outerjoin(Lesson).join(Schedule)
        if schedule_id is None:
            stmt = Schedule.query_current_id().subquery()
            q = q.join((stmt, Lesson.schedule_id == stmt.c.id))
        else:
            q = q.filter(Schedule.id == schedule_id)
        return q
Пример #21
0
    def query_active(cls, schedule_id=None):
        """
        Query educator with lessons in the schedule.

        """
        q = Session.query(cls).outerjoin(Lesson).join(Schedule)
        if schedule_id is None:
            stmt = Schedule.query_current_id().subquery()
            q = q.join((stmt, Lesson.schedule_id == stmt.c.id))
        else:
            q = q.filter(Schedule.id == schedule_id)
        return q
Пример #22
0
    def left(cls):
        """
        Get left lucky numbers, not used before, sorted.

        """
        student_count = func.count(Student.id).label('student_count')
        recent_years = [sy.id for sy in SchoolYear.recent()]
        stmt =  Session.query(student_count, Student).\
                        join(GroupMembership).\
                        join(Group).group_by(Group.id).\
                        filter(Group.year_id.in_(recent_years)).subquery()
        max = Session.query(func.max(stmt.c.student_count)).first()[0]
        count = Session.query(func.count(LuckyNumber.id)).first()[0]
        past = Session.query(LuckyNumber.number).\
                       order_by(desc(LuckyNumber.date)).\
                       limit(count % max).all()

        all = set(range(1, max + 1))
        past = set(x[0] for x in past)
        left = list(all.difference(past))
        left.sort()
        return left
Пример #23
0
Файл: lucky.py Проект: kuba/SIS
    def add(self):
        form_numbers = self.form_result['lucky']
        numbers = []
        for lucky in form_numbers:
            if lucky['date'] and lucky['number']:
                ln = LuckyNumber(lucky['date'], lucky['number'])
                numbers.append(ln)

        Session.add_all(numbers)

        try:
            Session.commit()
        except IntegrityError as e:
            session['flash'] = 'There is already lucky number for %s' % e.params[0]
            session.save()
            return redirect(url('lucky_add'))
        else:
            if len(numbers) == 0:
                session['flash'] = 'No lucky number has been added!'
            else:
                session['flash'] = 'Lucky numbers have been added!'
            session.save()
            return redirect(url('lucky_home'))
Пример #24
0
    def query_started(cls, date=None):
        """
        Query already started years and sort it by date
        from the newest to the oldest.

        :param date: query relatively to the given date.
        :type date: :class:`datetime.date`

        """
        if date is None:
            date = func.date()
        q = Session.query(SchoolYear).\
                filter(SchoolYear.start <= date).\
                order_by(desc(SchoolYear.start))
        return q
Пример #25
0
Файл: basic.py Проект: kuba/SIS
    def query_started(cls, date=None):
        """
        Query already started years and sort it by date
        from the newest to the oldest.

        :param date: query relatively to the given date.
        :type date: :class:`datetime.date`

        """
        if date is None:
            date = func.date()
        q = Session.query(SchoolYear).\
                filter(SchoolYear.start <= date).\
                order_by(desc(SchoolYear.start))
        return q
Пример #26
0
    def query_current(cls, schedule_id=None):
        """
        Query (ordered) lessons according to current schedule.

        Order by: day, order, part.

        """
        q = Session.query(cls).\
                    order_by(cls.day, cls.order, desc(cls.first_part),
                             desc(cls.second_part))
        if schedule_id is None:
            stmt = Schedule.query_current_id().subquery()
            q = q.join((stmt, cls.schedule_id == stmt.c.id))
        else:
            q = q.filter_by(schedule_id=schedule_id)
        return q
Пример #27
0
Файл: basic.py Проект: kuba/SIS
    def query_current(cls, schedule_id=None):
        """
        Query (ordered) lessons according to current schedule.

        Order by: day, order, part.

        """
        q = Session.query(cls).\
                    order_by(cls.day, cls.order, desc(cls.first_part),
                             desc(cls.second_part))
        if schedule_id is None:
            stmt = Schedule.query_current_id().subquery()
            q = q.join((stmt, cls.schedule_id == stmt.c.id))
        else:
            q = q.filter_by(schedule_id=schedule_id)
        return q
Пример #28
0
    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')
Пример #29
0
    def by_full_name(self, full_name, relative_year=None):
        """
        Return group by its full_name (index + name).

        Full name could be, eg. "1bch", "2inf1" or "2inf2".

        """
        if len(full_name) < 1:
            return None
        try:
            index = int(full_name[0])
        except ValueError:
            return None
        name = full_name[1:]

        year = SchoolYear.by_index(index, relative_year)

        group = Session.query(Group).filter_by(year=year, name=name).first()
        return group
Пример #30
0
Файл: basic.py Проект: kuba/SIS
    def by_full_name(self, full_name, relative_year=None):
        """
        Return group by its full_name (index + name).

        Full name could be, eg. "1bch", "2inf1" or "2inf2".

        """
        if len(full_name) < 1:
            return None
        try:
            index = int(full_name[0])
        except ValueError:
            return None
        name = full_name[1:]

        year = SchoolYear.by_index(index, relative_year)

        group = Session.query(Group).filter_by(year=year, name=name).first()
        return group
Пример #31
0
    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')
Пример #32
0
Файл: basic.py Проект: kuba/SIS
    def query_current(cls, year_id=None, date=None, q=None):
        """
        Query current active schedule.

        :param year_id: School year of the Schedule
        :type year_id: :class:`int`

        :param date: If year_id is None method queries already started
                     school years relatively to the given date
        :type date: :class:`datetime.date`

        """
        if q is None:
            q = Session.query(Schedule)

        if year_id is None:
            stmt = SchoolYear.query_started(date).limit(1).subquery()
            q = q.join((stmt, Schedule.year_id == stmt.c.id))
        else:
            q = q.filter_by(year_id=year_id)

        q = q.filter(Schedule.start <= func.date())
        return q
Пример #33
0
    def query_current(cls, year_id=None, date=None, q=None):
        """
        Query current active schedule.

        :param year_id: School year of the Schedule
        :type year_id: :class:`int`

        :param date: If year_id is None method queries already started
                     school years relatively to the given date
        :type date: :class:`datetime.date`

        """
        if q is None:
            q = Session.query(Schedule)

        if year_id is None:
            stmt = SchoolYear.query_started(date).limit(1).subquery()
            q = q.join((stmt, Schedule.year_id == stmt.c.id))
        else:
            q = q.filter_by(year_id=year_id)

        q = q.filter(Schedule.start <= func.date())
        return q
Пример #34
0
    def create(self):
        """POST /substitutions: Create a new item"""
        # url('substitutions')
        date = datetime.datetime.strptime(request.params['date'], '%Y-%m-%d')
        order = int(request.params['order'])
        group = Session.query(Group).get(int(request.params['group']))
        part = int(request.params['part'])
        raw_educator = request.params['educator']
        if raw_educator == 0:
            teacher = None
        else:
            teacher = Session.query(Educator).get(raw_educator)
        comment = request.params['comment']

        s = Substitution(date, order, group, teacher, part, comment)
        Session.add(s)
        Session.commit()
        redirect(url('substitutions'))
Пример #35
0
    def create(self):
        """POST /substitutions: Create a new item"""
        # url('substitutions')
        date = datetime.datetime.strptime(request.params['date'], '%Y-%m-%d')
        order = int(request.params['order'])
        group = Session.query(Group).get(int(request.params['group']))
        part = int(request.params['part'])
        raw_educator = request.params['educator']
        if raw_educator == 0:
            teacher = None
        else:
            teacher = Session.query(Educator).get(raw_educator)
        comment = request.params['comment']

        s = Substitution(date, order, group, teacher, part, comment)
        Session.add(s)
        Session.commit()
        redirect(url('substitutions'))
Пример #36
0
def init_model(engine):
    """Call me before using any of the tables or classes in the model"""
    Session.configure(bind=engine)
Пример #37
0
Файл: subs.py Проект: kuba/SIS
 def teacher_lesson(self):
     """Get teacher's scheduled lesson."""
     day = datetime.date.weekday(self.date)
     query = Session.query(Lesson).filter_by(
         day=day, order=self.order, teacher_id=self.teacher.id)
     return query.all()
Пример #38
0
 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')
Пример #39
0
Файл: basic.py Проект: kuba/SIS
 def query_current_id(cls, year_id=None, date=None):
     q = Session.query(Schedule.id)
     return cls.query_current(year_id, date, q)
Пример #40
0
    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')
Пример #41
0
    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')
Пример #42
0
 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')
Пример #43
0
def init_model(engine):
    """Call me before using any of the tables or classes in the model"""
    Session.configure(bind=engine)
Пример #44
0
    def last(cls):
        """
        Return most recent lucky number.

        """
        return Session.query(cls).order_by(desc(cls.date)).first()
Пример #45
0
 def query_current_id(cls, year_id=None, date=None):
     q = Session.query(Schedule.id)
     return cls.query_current(year_id, date, q)