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 )
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")
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
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")
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, )
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
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)
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
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
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)
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))
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
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()
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()
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)
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
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 )
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
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}'), ]
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()
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()
def _query_object(self, criteria, cursor): cursor.execute(self.__sql_query_by_uk, criteria) rec = cursor.fetchone() if rec: return Lesson(**rec)
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 )
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)