def set_course(self, message): try: user = self.handler.user if user.status != 'seat': return # Load Course course = yield Course.get(message['course_id']) self.handler.course = course # User Assign Course yield user.assign_course(course.id) self.pub_subs['w'].send_message( {'type': 'studentSetup.course.set.ok'}) except KeyError: if 'course_id' not in message: self.handler.send_malformed_message_error(message) else: raise except NoObjectReturnedFromDB: self.handler.send_malformed_message_error(message) except AttributeError: if not hasattr(self.handler, 'user'): self.handler.send_user_not_loaded_error(message) else: raise
def set_course(self, message): try: user = self.handler.user if user.status != 'seat': return # Load Course course = yield Course.get(message['course_id']) self.handler.course = course # User Assign Course yield user.assign_course(course.id) self.pub_subs['w'].send_message( {'type': 'studentSetup.course.set.ok'}) except KeyError: if 'course_id' not in message: self.handler.send_malformed_message_error( message) else: raise except NoObjectReturnedFromDB: self.handler.send_malformed_message_error( message) except AttributeError: if not hasattr(self.handler, 'user'): self.handler.send_user_not_loaded_error( message) else: raise
def create_course(self, message): try: course_name = xhtml_escape(message['name']) if not re.search('\S', course_name): self.pub_subs['w'].send_message({ 'type': 'createCourseResult', 'result': 'emptyName' }) return course = yield Course.create(self.handler.user, course_name) self.pub_subs['w'].send_message({ 'type': 'createCourseResult', 'result': 'ok', 'course_id': course.id }) except KeyError: self.handler.send_malformed_message_error(message) except AttributeError: if not hasattr(self.handler, 'user'): self.handler.send_user_not_loaded_error(message) except DuplicateKeyError: self.pub_subs['w'].send_message({ 'type': 'createCourseResult', 'result': 'duplicate' })
def create_course(self, message): try: course_name = xhtml_escape(message['name']) if not re.search('\S', course_name): self.pub_subs['w'].send_message( {'type': 'createCourseResult', 'result': 'emptyName'}) return course = yield Course.create( self.handler.user, course_name) self.pub_subs['w'].send_message( { 'type': 'createCourseResult', 'result': 'ok', 'course_id': course.id } ) except KeyError: self.handler.send_malformed_message_error( message) except AttributeError: if not hasattr(self.handler, 'user'): self.handler.send_user_not_loaded_error( message) except DuplicateKeyError: self.pub_subs['w'].send_message( {'type': 'createCourseResult', 'result': 'duplicate'})
def assign_course_to_current_room(self, message): try: user = self.handler.user if user.status != 'room': return # Load Course course = yield Course.get(message['course_id']) self.handler.course = course # Room Deasign Course if user.course_id is not None: self.handler.room.deassign_course( user.course_id) # Room Assign Course room = yield self.handler.room_code.room yield room.assign_course(course.id) # User Assign Course yield user.assign_course(course.id) self.course_assignment_source = True """This variable identifies the source of the ``course.assignment.ok`` message.""" self.pub_subs['d'].send_message( { 'type': self.handler.user_msg_type, 'content': { 'type': 'course.assignment.ok' } } ) except KeyError: if 'course_id' not in message: self.handler.send_malformed_message_error( message) else: raise except NoObjectReturnedFromDB: self.handler.send_malformed_message_error( message) except AttributeError: if not hasattr(self.handler, 'user'): self.handler.send_user_not_loaded_error( message) elif not hasattr(self.handler, 'room_code') or \ self.handler.room_code is None: self.handler.send_room_not_loaded_error( message) else: raise
def sync_course_id_and_forward_to_client(self, message): if not (hasattr(self, 'course_assignment_source') and self.course_assignment_source): yield self.handler.user.sync('course_id') course_id = self.handler.user.course_id if course_id is not None: self.handler.course = yield Course.get(course_id) self.pub_subs['w'].send_message({'type': 'course.assignment.ok'})
def assign_course_to_current_room(self, message): try: user = self.handler.user if user.status != 'room': return # Load Course course = yield Course.get(message['course_id']) self.handler.course = course # Room Deasign Course if user.course_id is not None: self.handler.room.deassign_course(user.course_id) # Room Assign Course room = yield self.handler.room_code.room yield room.assign_course(course.id) # User Assign Course yield user.assign_course(course.id) self.course_assignment_source = True """This variable identifies the source of the ``course.assignment.ok`` message.""" self.pub_subs['d'].send_message({ 'type': self.handler.user_msg_type, 'content': { 'type': 'course.assignment.ok' } }) except KeyError: if 'course_id' not in message: self.handler.send_malformed_message_error(message) else: raise except NoObjectReturnedFromDB: self.handler.send_malformed_message_error(message) except AttributeError: if not hasattr(self.handler, 'user'): self.handler.send_user_not_loaded_error(message) elif not hasattr(self.handler, 'room_code') or \ self.handler.room_code is None: self.handler.send_room_not_loaded_error(message) else: raise
def sync_course_id_and_forward_to_client(self, message): if not (hasattr(self, 'course_assignment_source') and self.course_assignment_source): yield self.handler.user.sync('course_id') course_id = self.handler.user.course_id if course_id is not None: self.handler.course = yield Course.get( course_id) self.pub_subs['w'].send_message( {'type': 'course.assignment.ok'})
def send_room_courses(self, message): """Send current room's courses to the client. This method is subscribed to the ``courses.room.get`` message type. The ``user_id`` field of each course is replaced by the ``owner`` field. The ``owner`` field contains the name of the user, instead of it's ID. :param dict message: The client's message that executed this method. .. todo:: * To get the user's names, only one query should be made. Like: ``User.get_names(id_list)`` """ try: courses = yield Course.get_courses_from_ids( self.handler.room.courses) ids = {c['user_id'] for c in courses} names = yield { id_: User.get_name(id_) for id_ in ids} for course in courses: course['owner'] = names[ course['user_id'] ] del course['user_id'] self.pub_subs['w'].send_message( {'type': 'courses', 'courses': courses}) except AttributeError: if not hasattr(self.handler, 'room') or \ self.handler.room is None: self.handler.send_room_not_loaded_error( message) elif not hasattr(self.handler.room, 'courses'): """This should never happen again :P.""" raise else: raise
def send_room_courses(self, message): """Send current room's courses to the client. This method is subscribed to the ``courses.room.get`` message type. The ``user_id`` field of each course is replaced by the ``owner`` field. The ``owner`` field contains the name of the user, instead of it's ID. :param dict message: The client's message that executed this method. .. todo:: * To get the user's names, only one query should be made. Like: ``User.get_names(id_list)`` """ try: courses = yield Course.get_courses_from_ids( self.handler.room.courses) ids = {c['user_id'] for c in courses} names = yield {id_: User.get_name(id_) for id_ in ids} for course in courses: course['owner'] = names[course['user_id']] del course['user_id'] self.pub_subs['w'].send_message({ 'type': 'courses', 'courses': courses }) except AttributeError: if not hasattr(self.handler, 'room') or \ self.handler.room is None: self.handler.send_room_not_loaded_error(message) elif not hasattr(self.handler.room, 'courses'): """This should never happen again :P.""" raise else: raise
def send_user_courses(self, message): """Send current user's courses to the client. This method is subscribed to the ``courses.user.get`` message type. :param dict message: The client's message that executed this method. """ try: courses = yield Course.get_user_courses(self.handler.user) self.pub_subs['w'].send_message({ 'type': 'courses', 'courses': courses }) except AttributeError: if not hasattr(self.handler, 'user'): self.handler.send_user_not_loaded_error(message) else: raise
def send_user_courses(self, message): """Send current user's courses to the client. This method is subscribed to the ``courses.user.get`` message type. :param dict message: The client's message that executed this method. """ try: courses = yield Course.get_user_courses( self.handler.user) self.pub_subs['w'].send_message( {'type': 'courses', 'courses': courses}) except AttributeError: if not hasattr(self.handler, 'user'): self.handler.send_user_not_loaded_error( message) else: raise
def startSession(self, message): """Start a user session .. todo:: * Add a variable that indicates the last stage that was executed successfully. So that the finally clause can clean the mess properly. """ try: yield self.load_user(message['token']) self.sub_to_user_messages() code_type, room_name, seat_id = \ yield self.load_room_code( message['room_code']) user = self.handler.user room_code = self.handler.room_code room = self.handler.room course_id = user.course_id has_course = course_id is not None was_none = (user.status == 'none') was_student = (user.status == 'seat') was_teacher = (user.status == 'room') is_none = (code_type == 'none') is_student = (code_type == 'seat') is_teacher = (code_type == 'room') distinct_room = not ( room_name is None or user.room_name is None or room_name == user.room_name ) same_seat = (seat_id == user.seat_id) and \ not distinct_room transition_data = ( has_course, was_none, was_student, was_teacher, is_none, is_student, is_teacher, distinct_room ) # Redirect to Teacher View if self.should_run_redirect_to_teacher_view( *transition_data): self.redirect_to_teacher_view( user.room_code, message) # The rest of the code is not executed. return # Room Deassign Course '''This should always run before "User Deassign Course"''' if self.should_run_room_deassign_course( *transition_data): if distinct_room: r = yield Room.get(user.room_name) else: r = room yield r.deassign_course(course_id) # User Deassign Course if self.should_run_user_deassign_course( *transition_data): yield user.deassign_course() # Logout Other Instances if self.should_run_logout_other_instances( *transition_data): self.block_logout = True self.pub_subs['d'].send_message( { 'type': self.handler.user_msg_type, 'content': { 'type': 'logout', 'reason': 'exclusiveLogin', 'user_state_at_exclusive_login': user._data, 'dont_leave_seat': same_seat, } } ) # Use Seat if self.should_run_use_seat(*transition_data) \ and (not same_seat or user.instances == 0): yield room.use_seat(room_code.seat_id) # Load Course if self.should_run_load_course( *transition_data): self.handler.course = yield Course.get( course_id) # Increase Instances yield self.handler.user.increase_instances() yield self.handler.user.store_dict( { 'status': code_type, 'room_code': message['room_code'], 'room_name': room_name, 'seat_id': seat_id, } ) except jwt.InvalidTokenError: self.handler.logout_and_close('invalidToken') except ConditionNotMetError: self.send_session_start_error( message, 'Es probable que este error se daba a que ' 'el asiento que desea registrar ya está ' 'usado.' ) except OperationFailure: self.send_session_start_error( message, 'Una operación de la base de datos ha ' 'fallado.' ) except KeyError: keys_in_message = all( map( lambda k: k in message, ('token', 'room_code') ) ) if not keys_in_message: self.handler.send_malformed_message_error( message) else: raise else: self.session_start_ok = True self.pub_subs['w'].send_message( { 'type': 'session.start.ok', 'code_type': code_type, 'course_id': user.course_id } ) finally: if not self.session_start_ok: pass
def startSession(self, message): """Start a user session .. todo:: * Add a variable that indicates the last stage that was executed successfully. So that the finally clause can clean the mess properly. """ try: yield self.load_user(message['token']) self.sub_to_user_messages() code_type, room_name, seat_id = \ yield self.load_room_code( message['room_code']) user = self.handler.user room_code = self.handler.room_code room = self.handler.room course_id = user.course_id has_course = course_id is not None was_none = (user.status == 'none') was_student = (user.status == 'seat') was_teacher = (user.status == 'room') is_none = (code_type == 'none') is_student = (code_type == 'seat') is_teacher = (code_type == 'room') distinct_room = not (room_name is None or user.room_name is None or room_name == user.room_name) same_seat = (seat_id == user.seat_id) and \ not distinct_room transition_data = (has_course, was_none, was_student, was_teacher, is_none, is_student, is_teacher, distinct_room) # Redirect to Teacher View if self.should_run_redirect_to_teacher_view(*transition_data): self.redirect_to_teacher_view(user.room_code, message) # The rest of the code is not executed. return # Room Deassign Course '''This should always run before "User Deassign Course"''' if self.should_run_room_deassign_course(*transition_data): if distinct_room: r = yield Room.get(user.room_name) else: r = room yield r.deassign_course(course_id) # User Deassign Course if self.should_run_user_deassign_course(*transition_data): yield user.deassign_course() # Logout Other Instances if self.should_run_logout_other_instances(*transition_data): self.block_logout = True self.pub_subs['d'].send_message({ 'type': self.handler.user_msg_type, 'content': { 'type': 'logout', 'reason': 'exclusiveLogin', 'user_state_at_exclusive_login': user._data, 'dont_leave_seat': same_seat, } }) # Use Seat if self.should_run_use_seat(*transition_data) \ and (not same_seat or user.instances == 0): yield room.use_seat(room_code.seat_id) # Load Course if self.should_run_load_course(*transition_data): self.handler.course = yield Course.get(course_id) # Increase Instances yield self.handler.user.increase_instances() yield self.handler.user.store_dict({ 'status': code_type, 'room_code': message['room_code'], 'room_name': room_name, 'seat_id': seat_id, }) except jwt.InvalidTokenError: self.handler.logout_and_close('invalidToken') except ConditionNotMetError: self.send_session_start_error( message, 'Es probable que este error se daba a que ' 'el asiento que desea registrar ya está ' 'usado.') except OperationFailure: self.send_session_start_error( message, 'Una operación de la base de datos ha ' 'fallado.') except KeyError: keys_in_message = all( map(lambda k: k in message, ('token', 'room_code'))) if not keys_in_message: self.handler.send_malformed_message_error(message) else: raise else: self.session_start_ok = True self.pub_subs['w'].send_message({ 'type': 'session.start.ok', 'code_type': code_type, 'course_id': user.course_id }) finally: if not self.session_start_ok: pass