Ejemplo n.º 1
0
def lesson(lesson_id, section_id):
    user_db = auth.current_user_db()
    if user_db.progress < lesson_id:
        return redirect(url_for('lesson', lesson_id=user_db.progress, section_id=1))
    if lesson_id > 0 and not user_db.registered:
        flash(u'Please register with your email below to access additional Lessons.')
        return redirect(url_for('welcome'))
    if request.method == 'POST':
        if answers.check(request.form, lesson_id):
            user_db.progress = lesson_id + 1
            try:
                user_db.put()
                flash(u'Congratulations! Welcome to Lesson %s.' % user_db.progress, 'success')
                return redirect(url_for('lesson', lesson_id=user_db.progress, section_id=1))
            except:
                flash(u'Something went wrong.', 'info')
                return redirect(url_for('lesson', lesson_id=lesson_id,section_id=section_id))
    lesson_db = Lesson.query(Lesson.number == lesson_id).get()
    section_dbs = Section.query(Section.lesson == lesson_id).order(Section.number)
    piece_dbs = Piece.query(Piece.lesson == lesson_id, Piece.section == section_id).order(Piece.number)
    graph_string = 'graphs/graph_' + str(lesson_id) + '_' + str(section_id)
    return render_template(
        'lesson.html',
        html_class='lesson',
        lesson=lesson_db,
        sections=section_dbs,
        pieces=piece_dbs,
        graph=graph_string + '.html',
        graph_head=graph_string + '_head.html',
        lesson_id=lesson_id,
        section_id=section_id,
        progress=user_db.progress
    )
Ejemplo n.º 2
0
 def stop_all_lessons(self):
     from model import Lesson
     lessons = Lesson.fetch_all(filter_expr="teacher", filter_value=self.person)
     for lesson in lessons:
         self.stop_lesson(lesson, False)
             
     self.write_response_plain_text("OK")
Ejemplo n.º 3
0
 def get_lesson_json(self, lesson_code):
     from model import Lesson
     import json
     import datetime
         
     def handler(o):
         if isinstance(o, datetime.datetime):
             return "(new Date(%d, %d, %d, %d, %d, %d))"%(
                     o.year,
                     o.month,  
                     o.day,
                     o.hour,
                     o.minute,
                     o.second)
         else:
             raise TypeError(repr(o))
 
     lesson = Lesson.get_by_key_name(lesson_code)
     lesson_info = []
     if not lesson.is_deleted:
         lesson_info.append({
             "lesson_code" : lesson.lesson_code,
             "title" : lesson.title,
             "description" : lesson.description,
             "class_name" : lesson.class_name,
             "start_time" : lesson.start_time,
             "stop_time" : lesson.stop_time,
             "tasks" : lesson.tasks,
             "is_active" : lesson.is_active
         })
     lesson_json = json.dumps(lesson_info, default=handler)
     return lesson_json
Ejemplo n.º 4
0
 def delete_all_lessons(self):
     from model import Lesson
     lessons = Lesson.fetch_all(filter_expr="teacher", filter_value=self.person)
     for lesson in lessons:
         self.delete_lesson(lesson, False)
         self.log_out_all_students(lesson, False);
     self.write_response_plain_text("OK")
Ejemplo n.º 5
0
def lesson_view():
    lesson_dbs = Lesson.query().order(Lesson.number)
    return render_template(
        'lesson_view.html',
        html_class='lesson-view',
        title='Lessons',
        lessons=lesson_dbs,
    )
Ejemplo n.º 6
0
def lesson_delete(lesson_id):
    lesson_db = Lesson.get_by_id(lesson_id)
    try:
        lesson_db.key.delete()
        flash(u'Lesson id %s successfully deleted.' % lesson_id, 'success')
        return redirect(url_for('lesson_view'))
    except:
        flash(u'Something went wrong.', 'info')
        return redirect(url_for('lesson_view'))
    def get_lessons_json(self, returnAll=False):
        from model import Lesson
        import json
        import datetime

        def handler(o):
            if isinstance(o, datetime.datetime):
                return "(new Date(%d, %d, %d, %d, %d, %d))" % (
                    o.year,
                    o.month - 1,  # javascript months start at zero
                    o.day,
                    o.hour,
                    o.minute,
                    o.second,
                )
            else:
                raise TypeError(repr(o))

        if returnAll:
            lessons = Lesson.fetch_all(sort="title")
        elif self.person is not None and self.is_teacher:
            lessons = Lesson.fetch_all(filter_expr="teacher", filter_value=self.person, sort="title")
        else:
            lessons = Lesson.fetch_all(sort="title")

        lesson_infos = []
        for lesson in lessons:
            if not lesson.is_deleted:
                lesson_infos.append(
                    {
                        "lesson_code": lesson.lesson_code,
                        "title": lesson.title,
                        "description": lesson.description,
                        "class_name": lesson.class_name,
                        "teacher_name": lesson.teacher.nickname,
                        "start_time": lesson.start_time,
                        "stop_time": lesson.stop_time,
                        "tasks": lesson.tasks,
                        "is_active": lesson.is_active,
                    }
                )
        lessons_json = json.dumps(lesson_infos, default=handler)
        return lessons_json
Ejemplo n.º 8
0
def lesson_create():
    form = LessonForm()
    if form.validate_on_submit():
        lesson_db = Lesson(
            title = form.title.data,
            number = form.number.data,
        )
        try:
            lesson_db.put()
            flash(u'Lesson id %s successfully saved.' % lesson_db.key.id(), 'success')
            return redirect(url_for('lesson_view'))
        except:
            flash(u'Something went wrong.', 'info')
            return redirect(url_for('lesson_update'))
    return render_template(
        'lesson_update.html',
        html_class='lesson-create',
        title='Create Lesson',
        form=form)
Ejemplo n.º 9
0
def create_lesson(title, description, author_id, public = False):
    """Create and return a new lesson."""

    new_lesson = Lesson(title=title, description=description, 
                        author_id=author_id, public=public)
    
    db.session.add(new_lesson)
    db.session.commit()

    return new_lesson
Ejemplo n.º 10
0
def get_room_timetable(day, aula, orari_group_by_aula, all_teachings):
    if len(orari_group_by_aula) == 0:
        return None
    timetable = Timetable()

    start = datetime.datetime.strptime(
        day.strftime("%Y-%m-%d") + "T00:00:00", "%Y-%m-%dT%H:%M:%S")
    stop = datetime.datetime.strptime(
        day.strftime("%Y-%m-%d") + "T23:59:59", "%Y-%m-%dT%H:%M:%S")

    for o in orari_group_by_aula[aula.aula_codice]:
        try:
            inizio = datetime.datetime.strptime(o["inizio"],
                                                "%Y-%m-%dT%H:%M:%S")
            fine = datetime.datetime.strptime(o["fine"], "%Y-%m-%dT%H:%M:%S")

            if inizio > start and inizio < stop and aula.aula_codice in o[
                    "aula_codici"]:

                t = all_teachings[o["componente_id"]]

                l = Lesson(
                    t.corso_codice, t.materia_codice, t.materia_descrizione,
                    t.docente_nome, t.componente_id, t.url,
                    datetime.datetime.strptime(o["inizio"],
                                               "%Y-%m-%dT%H:%M:%S"),
                    datetime.datetime.strptime(o["fine"], "%Y-%m-%dT%H:%M:%S"),
                    t.anno, t.crediti, t.componente_padre, t.componente_radice)

                l.add_aula(aula)

                timetable.add_lesson(l)

        except:
            print(o)
            traceback.print_exc()
            now = datetime.datetime.now()
            logging.info("TIMESTAMP = " + now.strftime("%b %d %Y %H:%M:%S") +
                         " ### EXCEPTION = " + traceback.format_exc())

    timetable.lessons.sort(key=lambda x: x.inizio, reverse=False)
    return timetable
Ejemplo n.º 11
0
    def get(self):
        # Fetches votes for currently logged in user
        # Replace lesson_id and practice_id with full versions
        params = self.get_params()
        if 'practice_id' in params:
            params[u'practice_id'] = Practice.get_long_uid(
                params[u'practice_id'])
        if 'lesson_id' in params:
            params[u'lesson_id'] = Lesson.get_long_uid(params[u'lesson_id'])

        votes = self.api.get('Vote', ancestor=self.api.user, **params)
        self.write(votes)
Ejemplo n.º 12
0
    def clone_lesson(self, lesson):
        lesson_title = lesson.title + " (Clone)"
        lesson_code = self.make_lesson_code()
        
        task_infos = []
        for task_idx in range(0, len(lesson.tasks)):
            task_title = lesson.tasks[task_idx][0];
            if task_title != "":
                task_description = lesson.tasks[task_idx][1];
                task_infos.append((task_title, task_description))

        import json
        tasks_json = json.dumps(task_infos)

        from datetime import datetime
        from model import Lesson
        lesson = Lesson(key_name=lesson_code,
            teacher=self.person, title=lesson_title, lesson_code=lesson_code,
            description=lesson.description, class_name=lesson.class_name, 
            start_time=datetime.now(), stop_time=lesson.stop_time, tasks_json=tasks_json)
        lesson.put()           
        self.response.out.write(self.get_lesson_json(lesson_code))
Ejemplo n.º 13
0
 def make_lesson_code(self):
     import random
     from model import Lesson
     digits = 5
     
     # This is essentially a do loop, but I'm using a generous upper bound to prevent the
     # possibility of an endless (and potentially costly) spin, in case of a bug, for example.
     for i in range(1000):
         assert i < 1000 - 1, "Looks like infinite loop."
         n = random.randint(0,10**digits - 1)
         lesson_code = "%05d"%n
         lesson = Lesson.get_by_key_name(lesson_code)
         if lesson is None:
             break
     return lesson_code
Ejemplo n.º 14
0
    def delete(self, id):
        if not self.user:
            raise PermissionDenied("Public cannot delete.")

        logging.info(u'Api.delete(id={})'.format(id))

        entity = Model.get_by_id(id)
        if not self.user.is_admin:
            # Then the user must be the creator of the thing, which equates
            # to being the parent entity (in a Datastore sense) of the thing
            # being deleted.
            if entity.key.parent() != self.user.key:
                raise PermissionDenied(
                    "{} does not own {} and may not delete it.".format(
                        self.user, entity))

        entity.deleted = True
        # We're about to take it out of the index, so don't bother updating
        # it with the new value of the deleted property.
        # See model.Model._post_put_hook()
        entity.forbid_post_put_hook = True
        entity.put()

        if isinstance(entity, (Lesson, Practice)):
            logging.info("Removing soft-deleted content from search.")
            search.Index(config.content_index).delete(entity.uid)

        entity_kind = Model.get_kind(entity)

        # If User object, need to remove unique properties from unique model
        if entity_kind is 'User':
            entity.remove_unique_properties(entity)

        # If vote, need to decrement vote on subject object
        if entity_kind is 'Vote':
            if entity.practice_id:
                practice_id = entity.practice_id
                practice = Practice.get_by_id(practice_id)
                if practice is not None:
                    practice.votes_for -= 1
                    practice.put()
            if entity.lesson_id:
                lesson_id = entity.lesson_id
                lesson = Lesson.get_by_id(lesson_id)
                if lesson is not None:
                    lesson.votes_for -= 1
                    lesson.put()
Ejemplo n.º 15
0
    def get(self):
        self.load_search_party_context(user_type="teacher")

        try:
            if not self.is_teacher:
                raise NotAnAuthenticatedTeacherError()
            
            else:
                lesson = None
                form_item = lambda key:self.request.get(key, "").strip()
                if form_item is not None:
                    lesson_code = form_item("lesson_code")
                    if lesson_code != "":
                        from model import Lesson
                        lesson = Lesson.get_by_key_name(lesson_code)       
                    action = form_item("action")
                if action=="create":
                    self.create_edit_lesson(form_item)
                elif action=="clone":
                    self.clone_lesson(lesson)
                elif action=="edit":
                    self.create_edit_lesson(form_item)
                elif action=="start":
                    self.start_lesson(lesson)  
                elif action=="stop":
                    self.stop_lesson(lesson)
                elif action=="stopall":
                    self.stop_all_lessons()
                elif action=="clear":
                    self.clear_lesson(lesson)
                elif action=="delete":
                    self.delete_lesson(lesson)
                elif action=="deleteall":
                    self.delete_all_lessons()
                elif action=="logoutstudent":
                    from model import Student
                    student_nickname = form_item("student_nickname")
                    student_key = "::".join((student_nickname, lesson_code))
                    student = Student.get_by_key_name(student_key)
                    self.log_out_student(student)
                elif action=="logoutallstudents":
                    self.log_out_all_students(lesson)
                else:
                    self.show_dashboard()

        except NotAnAuthenticatedTeacherError:
            self.redirect_to_teacher_login()
Ejemplo n.º 16
0
    def get(self, lesson_code):

        self.load_search_party_context(user_type="teacher")

        try:
            from model import Lesson
            import json
            import settings
            
            if not self.is_teacher:
                raise NotAnAuthenticatedTeacherError()

            lesson = Lesson.get_by_key_name(lesson_code)
            if lesson is None:
                raise LessonNotFoundError()
            if lesson.teacher_key != self.teacher_key:
                raise WrongTeacherError()

            teacher = self.person
            person_key = teacher.user.user_id();
            token = self.create_channel(person_key=person_key, lesson_code=lesson_code)
            default_start_pane = "students"

            template_values = {
                'header'             : self.gen_header("teacher"),
                'token'              : token,
                'lesson'             : lesson,
                'lesson_json'        : self.get_lesson_json(lesson_code),
                'students_js'        : self.make_student_structure_js2(lesson=lesson, indent="  "),
                'default_start_pane' : default_start_pane,
                'debug_mode'         : json.dumps(settings.DEBUG)
            }

            if self.session.has_key('msg'):
                template_values['msg'] = self.session.pop('msg')  # only show the message once

            self.write_response_with_template("teacher.html", template_values)

        except NotAnAuthenticatedTeacherError:
            self.redirect_to_teacher_login()

        except LessonNotFoundError:
            self.redirect_with_msg("There was an internal error.  Please choose your lesson to continue.", "/teacher_dashboard")

        except WrongTeacherError:
            self.redirect_to_teacher_login()
 def post(self):
     from helpers import log
     self.load_user()
     self.person.add_client_id(self.client_id)
     if self.person_type=="student" and len(self.person.client_ids)==1:
         self.person.latest_logout_timestamp = None
     self.person.put()
     
     log("=> CHANNEL CONNECTED: {0} ({1})".format(str(self.client_id),len(self.person.client_ids)))
             
     if self.person_type=="student" and len(self.person.client_ids)==1:
         from client_id_utils import lesson_code_for_client_id
         from model import Lesson
         from updates import send_update_log_in
         lesson_code = lesson_code_for_client_id(self.client_id)
         lesson = Lesson.get_by_key_name(lesson_code)
         send_update_log_in(student=self.person, teacher=lesson.teacher)
Ejemplo n.º 18
0
def get_plan_timetable(day, plan, orari, all_aule):
    if len(orari) == 0:
        return None
    timetable = Timetable()

    if plan.is_empty():
        return timetable

    start = datetime.datetime.strptime(
        day.strftime("%Y-%m-%d") + "T00:00:00", "%Y-%m-%dT%H:%M:%S")
    stop = datetime.datetime.strptime(
        day.strftime("%Y-%m-%d") + "T23:59:59", "%Y-%m-%dT%H:%M:%S")

    for t in plan.teachings:
        for o in orari[t.componente_id]:
            try:
                ##### DEBUG #####
                # if t.componente_id == '448380':
                #     print(t)
                #################
                inizio = datetime.datetime.strptime(o["inizio"],
                                                    "%Y-%m-%dT%H:%M:%S")

                if inizio > start and inizio < stop:
                    l = Lesson(
                        t.corso_codice, t.materia_codice,
                        t.materia_descrizione, t.docente_nome, t.componente_id,
                        t.url,
                        datetime.datetime.strptime(o["inizio"],
                                                   "%Y-%m-%dT%H:%M:%S"),
                        datetime.datetime.strptime(o["fine"],
                                                   "%Y-%m-%dT%H:%M:%S"),
                        t.anno, t.crediti, t.componente_padre,
                        t.componente_radice)
                    for code in o["aula_codici"].split():
                        try:
                            a = all_aule[code]
                            l.add_aula(a)
                        except:
                            l.add_aula(
                                Aula("-", "UNKNOWN AULA", "UNKNOWN ADDRESS",
                                     "", "NO LAT", "NO LON"))

                    timetable.add_lesson(l)
            except:
                traceback.print_exc()
                now = datetime.datetime.now()
                logging.info("TIMESTAMP = " +
                             now.strftime("%b %d %Y %H:%M:%S") +
                             " ### EXCEPTION = " + traceback.format_exc())

    timetable.lessons.sort(key=lambda x: x.inizio, reverse=False)
    return timetable
Ejemplo n.º 19
0
def lesson_update(lesson_id):
    lesson_db = Lesson.get_by_id(lesson_id)
    form = LessonForm(obj=lesson_db)
    if form.validate_on_submit():
        form.populate_obj(lesson_db)
        try:
            lesson_db.put()
            flash(u'Lesson id %s successfully saved.' % lesson_db.key.id(), 'success')
            return redirect(url_for('lesson_view'))
        except:
            flash(u'Something went wrong.', 'info')
            return redirect(url_for('lesson_view'))
    return render_template(
        'lesson_update.html',
        html_class='lesson-update',
        title='Edit Lesson',
        form=form,
        lesson_db=lesson_db
    )
Ejemplo n.º 20
0
def get_lessons(chat_id, now, plan, orari, all_aule):

    timetable = Timetable()

    if plan.is_empty():
        return timetable

    u = um.get_user(chat_id)
    lesson_time = now + datetime.timedelta(minutes=u.notification_time)

    for t in plan.teachings:
        for o in orari[t.componente_id]:
            try:
                ##### DEBUG #####
                #                if t.componente_id == '448380':
                #                    print(t)
                #################
                inizio = datetime.datetime.strptime(o["inizio"],
                                                    "%Y-%m-%dT%H:%M:%S")

                if inizio == lesson_time:
                    l = Lesson(
                        t.corso_codice, t.materia_codice,
                        t.materia_descrizione, t.docente_nome, t.componente_id,
                        t.url,
                        datetime.datetime.strptime(o["inizio"],
                                                   "%Y-%m-%dT%H:%M:%S"),
                        datetime.datetime.strptime(o["fine"],
                                                   "%Y-%m-%dT%H:%M:%S"),
                        t.anno, t.crediti, t.componente_padre,
                        t.componente_radice)
                    for code in o["aula_codici"].split():
                        try:
                            a = all_aule[code]
                            l.add_aula(a)
                        except:
                            l.add_aula(
                                Aula("-", "UNKNOWN AULA", "UNKNOWN ADDRESS",
                                     "", "NO LAT", "NO LON"))

                    timetable.add_lesson(l)
            except:
                traceback.print_exc()
                now = datetime.datetime.now()
                logging.info("TIMESTAMP = " +
                             now.strftime("%b %d %Y %H:%M:%S") +
                             " ### EXCEPTION = " + traceback.format_exc())

    timetable.lessons.sort(key=lambda x: x.inizio, reverse=False)
    return timetable
Ejemplo n.º 21
0
    def create_edit_lesson(self, form_item):
        lesson_code = form_item("lesson_code")
        is_new = lesson_code == ""
        if is_new:
            lesson_code = self.make_lesson_code()
        lesson_title = form_item("lesson_title")
        lesson_description = form_item("lesson_description")
        class_name = form_item("class_name")
        task_infos = []
    
        for task_num in range(1, int(self.request.get("max_num_tasks", "10"))+1):
            task_title = form_item("task_title_%d"%task_num)
            task_description = form_item("task_description_%d"%task_num)
            if task_title != "":
                task_infos.append((task_title, task_description))

        import json
        tasks_json = json.dumps(task_infos)

        if (len(lesson_title) > 0) and (len(lesson_code) > 0) and (len(task_infos) > 0):
            from model import Lesson
            from datetime import datetime
            now = datetime.now()

            lesson = Lesson(key_name=lesson_code,
                teacher=self.person, title=lesson_title, lesson_code=lesson_code,
                description=lesson_description, class_name=class_name, 
                tasks_json=tasks_json, start_time=now, stop_time=None)
            
            if not is_new:
                old_lesson = Lesson.get_by_key_name(lesson_code)       
                lesson.start_time = old_lesson.start_time
                lesson.stop_time = old_lesson.stop_time
            
            lesson.put()
            self.response.out.write(self.get_lessons_json())
        
        else:
            data = { 'error': 1, 'msg': 'Required fields are missing.' }
            self.response.out.write(json.dumps(data))
          ),  # temp_pass
     User(name='Mr. GovTech',
          username='******',
          password=
          '******'
          ),  # govtech_strong_password
     User(name='Admin',
          username='******',
          password=
          '******'
          ),  # super_duper_whitehacks_strong_password
     Module(code='IS200', name='Software Foundations'),
     Module(code='IS103', name='Computational Thinking'),
     Module(code='IS101', name='Seminar on Information Systems'),
     Module(code='WRIT001', name='Academic Writing'),
     Lesson(module_code='IS200', name='Lesson 01'),
     Lesson(module_code='IS103', name='Lesson 01'),
     Lesson(module_code='IS101', name='Lesson 01'),
     Lesson(module_code='WRIT001', name='Lesson 01'),
     Document(
         lesson_id=1,
         name='Document 01',
         is_draft=False,
         content=
         'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum'
     ),
     Document(lesson_id=4,
              name='Document Flag',
              is_draft=True,
              content='NOTFLAG{youre_almost_there_try_harder}'),
 ]
Ejemplo n.º 23
0
    def get(self, topic_id, lesson_id):
        full_lesson_id = Lesson.get_long_uid(lesson_id)
        lesson = self.api.get_by_id(full_lesson_id)

        full_topic_id = Topic.get_long_uid(topic_id)
        topic = self.api.get_by_id(full_topic_id)

        # check all content objects were found
        if not (lesson is None or topic is None):

            # Increment view counts on the lesson
            view_counter.increment(full_lesson_id)
            view_counter.increment('{}:{}'.format(full_topic_id,
                                                  full_lesson_id))

            theme = self.api.get_by_id(topic.themes[0])
            # Determines if current theme is for Teachers or not
            # 'teacher_theme' variable affects the UI
            teacher_theme = (theme.short_uid
                             in ['growth-mindset', 'growth-mindset-teachers'])

            # Get related practices
            related_practices = Practice.get_related_practices(topic, 4)

            # get other lessons in topic for navigating
            lessons = []
            # first check for bad topic--lesson match
            if topic.lessons:
                lessons = self.api.get_by_id(topic.lessons)

                # get lesson index and previous and next lessons
                lesson_index = 0
                if lesson.uid in topic.lessons:
                    lesson_index = topic.lessons.index(lesson.uid)

                next_topic = ''
                related_topics = []

                # get next lesson from current or next topic
                next_lesson = ''
                next_lesson_url = ''
                next_url = ''
                if lesson_index < len(lessons) - 1:
                    next_lesson = lessons[lesson_index + 1]
                    next_lesson_url = '/topics/{}/{}'.format(
                        topic.short_uid, next_lesson.short_uid)
                    next_url = next_lesson_url
                else:
                    # fetch next topic for final lesson
                    topic_index = 0
                    if topic.uid in theme.topics:
                        topic_index = theme.topics.index(topic.uid)
                    if topic_index < len(theme.topics) - 1:
                        next_topic = self.api.get_by_id(
                            theme.topics[topic_index + 1])
                        next_url = '/topics/{}'.format(next_topic.short_uid)

                    # get list of 3 other topics
                    related_topic_ids = []
                    for idx, val in enumerate(theme.topics):
                        if next_topic:
                            if val != topic.uid and val != next_topic.uid:
                                related_topic_ids.append(val)
                        elif val != topic.uid:
                            related_topic_ids.append(val)
                    if related_topic_ids:
                        related_topics = self.api.get_by_id(related_topic_ids)
                        if len(related_topics) >= 3:
                            related_topics = random.sample(related_topics, 3)

            # All topic lessons use default locale
            locale = config.default_locale

            if os.path.isfile('templates/lessons/' + lesson.short_uid +
                              '.html'):
                self.write(
                    '/lessons/{}.html'.format(lesson.short_uid),
                    theme=theme,
                    teacher_theme=teacher_theme,
                    topic=topic,
                    lesson=lesson,
                    lessons=lessons,
                    lesson_index=lesson_index,
                    next_lesson=next_lesson,
                    next_lesson_url=next_lesson_url,
                    next_url=next_url,
                    next_topic=next_topic,
                    color=topic.color,
                    related_topics=related_topics,
                    related_practices=related_practices,
                    locale=locale,
                    translation=locales.translations[locale]["lessons"],
                )
            else:
                # 404 if lesson html cannot be found
                return self.http_not_found()

        else:
            # 404 if lesson cannot be found
            return self.http_not_found()
Ejemplo n.º 24
0
    def get(self, theme_id, topic_id, lesson_id):
        full_lesson_id = Lesson.get_long_uid(lesson_id)
        lesson = self.api.get_by_id(full_lesson_id)

        full_theme_id = Theme.get_long_uid(theme_id)
        theme = self.api.get_by_id(full_theme_id)

        full_topic_id = Topic.get_long_uid(topic_id)
        topic = self.api.get_by_id(full_topic_id)

        # check all content objects were found
        if lesson is not None and topic is not None and theme is not None:

            # Increment view counts on the lesson
            view_counter.increment(full_lesson_id)
            view_counter.increment('{}:{}:{}'.format(full_theme_id,
                                                     full_topic_id,
                                                     full_lesson_id))

            # Get other topics in theme for navigating
            topics = []
            if theme.topics:
                topics = self.api.get_by_id(theme.topics)

            # get other lessons in topic for navigating
            lessons = []
            # first check for bad topic--lesson match
            if topic.lessons:
                lessons = self.api.get_by_id(topic.lessons)

                # get lesson index and previous and next lessons
                lesson_index = 0
                topic_index = 0
                if topic.uid in theme.topics:
                    topic_index = theme.topics.index(topic.uid)
                if lesson.uid in topic.lessons:
                    lesson_index = topic.lessons.index(lesson.uid)

                # get next lesson from current or next topic
                next_lesson = ''
                next_lesson_url = ''
                next_topic = ''
                next_topic_url = ''
                next_url = ''
                if lesson_index < len(lessons) - 1:
                    next_lesson = lessons[lesson_index + 1]
                    next_lesson_url = '/{}/{}/{}'.format(
                        theme.short_uid, topic.short_uid,
                        next_lesson.short_uid)
                    next_url = next_lesson_url
                elif topic_index < len(theme.topics) - 1:
                    next_topic = topics[topic_index + 1]
                    next_topic_url = '/{}/{}'.format(theme.short_uid,
                                                     next_topic.short_uid)
                    next_url = next_topic_url

            # Get translated text and locale
            if theme.locale in config.available_locales:
                locale = theme.locale
            else:
                locale = config.default_locale

            if os.path.isfile('templates/lessons/' + lesson.short_uid +
                              '.html'):
                self.write(
                    '/lessons/{}.html'.format(lesson.short_uid),
                    theme=theme,
                    topic=topic,
                    lesson=lesson,
                    lessons=lessons,
                    lesson_index=lesson_index,
                    next_lesson=next_lesson,
                    next_lesson_url=next_lesson_url,
                    next_topic=next_topic,
                    next_topic_url=next_topic_url,
                    next_url=next_url,
                    color=topic.color,
                    audience=theme.target_audience,
                    locale=locale,
                    translation=locales.translations[locale]["lessons"],
                )
            else:
                # 404 if lesson html cannot be found
                return self.http_not_found()

        else:
            # 404 if lesson cannot be found
            return self.http_not_found()
Ejemplo n.º 25
0
 def _query_object(self, criteria, cursor):
     cursor.execute(self.__sql_query_by_uk, criteria)
     rec = cursor.fetchone()
     if rec:
         return Lesson(**rec)
Ejemplo n.º 26
0
def get_plan_timetable_web_api(day, plan):
    timetable = Timetable()

    if plan.is_empty():
        return timetable

    orari_table = "orari_" + config.accademic_year
    aule_table = "aule_" + config.accademic_year
    url_o = "https://dati.unibo.it/api/action/datastore_search_sql"
    url_a = "https://dati.unibo.it/api/action/datastore_search?resource_id=" + \
        aule_table + "&q="

    sql_orari = "SELECT " + orari_table + ".inizio, " \
                + orari_table + ".fine, " \
                + orari_table + ".aula_codici, " \
                + orari_table + ".componente_id " \
                + " FROM " + orari_table \
                + " WHERE " + orari_table + ".inizio between \'" + day.strftime(
                    "%Y/%m/%d") + " 00:00:00\' and " + "\'" + day.strftime("%Y/%m/%d") + " 23:59:59\' AND ("

    for i in range(0, len(plan.teachings), 1):
        t = plan.teachings[i]
        if i == 0:
            sql_orari += orari_table + ".componente_id=" + t.componente_id
        else:
            sql_orari += " OR " + orari_table + ".componente_id=" + t.componente_id
    sql_orari += " )"

    headers = {
        'Content-type': 'application/json',
        'Accept': 'application/json'
    }
    json_orari = requests.post(url_o,
                               headers=headers,
                               data='{"sql":' + '"' + sql_orari + '"}').text

    try:
        ok = json.loads(json_orari)["success"]
    except:
        pass

    if ok:

        orari_dict = json.loads(json_orari)["result"]["records"]
        for o in orari_dict:
            try:
                componente_id = o["componente_id"]

                t = plan.find_teaching_by_componente_id(componente_id)
                if t != None:
                    ##### DEBUG #####
                    # if t.componente_id == '448380':
                    #     print(t)
                    #################
                    l = Lesson(
                        t.corso_codice, t.materia_codice,
                        t.materia_descrizione, t.docente_nome, t.componente_id,
                        t.url,
                        datetime.datetime.strptime(o["inizio"],
                                                   "%Y-%m-%dT%H:%M:%S"),
                        datetime.datetime.strptime(o["fine"],
                                                   "%Y-%m-%dT%H:%M:%S"),
                        t.anno, t.crediti, t.componente_padre,
                        t.componente_radice)
                    for code in o["aula_codici"].split():
                        try:
                            a = all_aule[code]
                            l.add_aula(a)
                        except:
                            l.add_aula(
                                Aula("-", "UNKNOWN AULA", "UNKNOWN ADDRESS",
                                     "", "NO LAT", "NO LON"))

                    timetable.add_lesson(l)
            except:
                traceback.print_exc()
                now = datetime.datetime.now()
                logging.info("TIMESTAMP = " +
                             now.strftime("%b %d %Y %H:%M:%S") +
                             " ### EXCEPTION = " + traceback.format_exc())
        timetable.lessons.sort(key=lambda x: x.inizio, reverse=False)
        return timetable
    else:
        return None
    def post(self):
        import json
        from model import Student, Lesson
        from all_exceptions import StudentLoginException
        from datetime import datetime
        from helpers import log

        try:
            self.load_search_party_context(user_type="student")

            # Get CGI form fields.
            lesson_code = self.request.get('lesson_code')
            student_nickname = self.request.get('student_nickname')
            ext = int(self.request.get('ext', 0))

            # Normalize whitespace in student name.
            # Replace any string of >=1 whitespace with a single space (equivalent to s/\s+/ /g).
            student_nickname = " ".join(student_nickname.split())

            if not lesson_code:
            # No lesson code
                raise StudentLoginException("Please enter a lesson code.",
                        "lesson_code==%r"%lesson_code)
                
            # If no student nickname, generate an anonymous one
            anonymous = False
            if not student_nickname:
                import random, string
                alphabet = string.letters + string.digits

                anonymous_student = None
                for i in range(8):
                    random_nickname = "".join(random.choice(alphabet) for i in range(10))
                    key_name = Student.make_key_name(student_nickname=random_nickname, lesson_code=lesson_code)
                    anonymous_student = Student.get_by_key_name(key_name)
                    if anonymous_student is None:
                        student_nickname = random_nickname
                        anonymous = True
                        break
    
            if anonymous and not student_nickname:
            # No student name
                raise StudentLoginException("Could not login as anonymous student.",
                        "student_nickname==%r"%student_nickname)

#            if not lesson_code and not student_nickname:
#            # Blank form
#                raise StudentLoginException("Please enter a lesson code and a student name.",
#                        "lesson_code==%r, student_nickname==%r"%(lesson_code, student_nickname))
#            elif not lesson_code:
#            # No lesson code
#                raise StudentLoginException("Please enter a lesson code.",
#                        "lesson_code==%r"%lesson_code)
#            elif not student_nickname:
#            # No student name
#                raise StudentLoginException("Please enter a student name.",
#                        "student_nickname==%r"%student_nickname)

            lesson = Lesson.get_by_key_name(lesson_code)
            # Retrieve lesson from DB
            # - If lesson does not exist, this will return None.
            # - If lesson existed but is disabled, it will return the lesson, but lesson.is_active will be False.
            # - If lesson existed but was deleted (hidden), it will return the lesson, but lesson.is_deleted will be True.
            #   (Deleting lessons is done lazily.  Actually, they are merely hidden from the teacher's view.)

            if lesson is None or lesson.is_deleted:
            # Lesson does not exist or was deleted (hidden).
                raise StudentLoginException("Please check the lesson code.",
                        "lesson retrieved from datastore with lesson_code %r is None"%lesson_code)
            elif not lesson.is_active:
            # Lesson has been disabled by teacher.  Students are not allowed to work on it anymore.
                raise StudentLoginException("This lesson is finished.  You cannot work on it now.",
                        "lesson_code %r has is_active=False"%lesson_code)
            
            # Fetch student from DB.
            # - Might return None if nobody has ever logged in with this nickname+lesson combination.
            key_name = Student.make_key_name(student_nickname=student_nickname, lesson_code=lesson_code)
            student = Student.get_by_key_name(key_name)
            login_timestamp = datetime.now()

            if student is not None:
            # Found the student.
                student.session_sid=self.session.sid
                student.latest_login_timestamp = login_timestamp
                student.latest_logout_timestamp = None
                if not student.first_login_timestamp:
                    student.first_login_timestamp = login_timestamp

            else:                
                student = Student(
                    key_name=key_name,
                    nickname=student_nickname,
                    teacher=lesson.teacher_key,
                    lesson=lesson,
                    task_idx=self.INITIAL_TASK_IDX,
                    first_login_timestamp=login_timestamp,
                    latest_login_timestamp=login_timestamp,
                    latest_logout_timestamp=None,
                    session_sid=self.session.sid,
                    anonymous=anonymous,
                    client_ids=[]
                )

            assert student.session_sid is not None
            student.put()
            self.set_person(student)
            displayName = "Anonymous" if self.is_student and self.person.anonymous else self.person.nickname
            self.session['msg'] = "Student logged in:  Hello " + displayName
            self.response.headers.add_header('Content-Type', 'application/json', charset='utf-8')
            self.response.out.write(json.dumps({"status":"logged_in", "ext":ext}))
            log( "=> LOGIN SUCCESS" )

        except StudentLoginException, e:
            e.log()
            self.set_person(None)
            msg = e.args[0]
            self.session['msg'] = msg
            self.response.headers.add_header('Content-Type', 'application/json', charset='utf-8')
            self.response.out.write(json.dumps({"status":"logged_out", "error":msg}))
            log( "=> LOGIN FAILURE:  %s"%msg )
Ejemplo n.º 28
0
	def _send_tab_delimited_report(self, lesson_code, utc_offset):
		import StringIO
		from model import Student, StudentActivity, Lesson
		import helpers
		encoding = "UTF-8"

		lesson = Lesson.get_by_key_name(lesson_code)
		assert lesson is not None

		if lesson is None or lesson.teacher_key != self.teacher_key:
			self.write_response_plain_text("ERROR:  Lesson code appears to be incorrect.")
		else:

			students = Student.fetch_all("lesson =", lesson)
			task_titles = tuple(task_info[0] for task_info in lesson.tasks)
			student_key_to_nickname = dict((s.key().name(), s.nickname) for s in students)
			activities = StudentActivity.fetch_all("lesson =", lesson)

			report_buffer = StringIO.StringIO()
			excel_writer = UnicodeWriter(report_buffer, "excel-tab", "utf8")

			headers = (
#					"Lesson_Code",
					"Timestamp",
					"Student",
					"Task_Number",
					"Task_Name",
					"Activity_Type",
					"Query",
					"Link_URL",
					"Link_Title",
					"Is_Helpful",
					"Answer_Text",
					"Answer_Explanation"
			)
			excel_writer.writerow(headers)

			for activity in activities:
				student_key = activity.student_key.name()
				student_nickname = student_key_to_nickname[student_key]
				timestamp = (activity.timestamp - utc_offset).strftime("%m/%d/%Y %H:%M:%S")
				task_idx = activity.task_idx
				task_title = task_titles[task_idx]
				task_num = task_idx + 1
				line_parts = (
#						lesson_code,
						timestamp,
						student_nickname,
						task_num,
						task_title,
						activity.activity_type,
						activity.search,
						activity.link,
						activity.link_title,
						activity.is_helpful,
						activity.answer_text,
						activity.answer_explanation
				)
#				line_parts = tuple(unicode(p).encode("utf8") for p in line_parts)
				excel_writer.writerow(line_parts)
			report_text = report_buffer.getvalue()
			report_buffer.close()

			content_type = "text/tab-separated-values"
			filename = "search_party_lesson_%s_activity_as_of_%s.txt"%(lesson_code, helpers.timestamp())
			self.write_response_as_file(encoded_content=report_text, content_type=content_type, filename=filename, encoding=encoding)