class MessageSerializer(serializers.ModelSerializer): """ Message serializer. """ next_handler = injections.depends(ProgressHandler) input = serializers.SerializerMethodField() # errors = serializers.CharField(source='get_errors', read_only=True) addMessages = serializers.SerializerMethodField() nextMessagesUrl = serializers.CharField(source='get_next_url', read_only=True) class Meta: model = Message fields = ( 'id', 'input', 'addMessages', 'nextMessagesUrl', # 'errors', ) def set_group(self, obj): try: getattr(self, 'qs') except AttributeError: self.qs = [obj] if obj.timestamp: current = obj for message in obj.chat.message_set.filter( timestamp__gt=obj.timestamp): if self.next_handler.group_filter(current, message): current = message self.qs.append(message) def get_input(self, obj): """ Getting description for next message. """ self.set_group(obj) input_data = { 'type': obj.get_next_input_type(), 'url': obj.get_next_url(), 'options': obj.get_options(), 'includeSelectedValuesFromMessages': [i.id for i in self.qs if i.contenttype == 'uniterror'] } if not obj.chat.next_point: input_data['html'] = ' ' return InputSerializer().to_representation(input_data) def get_addMessages(self, obj): self.set_group(obj) return InternalMessageSerializer(many=True).to_representation(self.qs)
class TwilioGateway: executor = injections.depends(ThreadPoolExecutor) def __init__(self, loop, account_id, auth_token): self.loop = loop self.account_id = account_id self.auth_token = auth_token self.client = Client(self.account_id, self.auth_token) @run_in_executor() def _send_sms(self, message, callback=None): self.client.messages.create( body=message, from_="+13392007215", status_callback=callback, to="+380974219029", ) async def send_sms(self, message, callback=None): return await self._send_sms(message, callback)
class UsersHandler: elastic = injections.depends(aioelasticsearch.Elasticsearch) index = "users" doc_type = "document" async def search(self, request): q = request.query.get("query") query = {"query": {"match_all": {}}} if q is not None: query = {"query": {"match": {"name": q}}} resp = await self.elastic.search( index=self.index, doc_type=self.doc_type, body=query ) if not resp: raise web.HTTPNotFound users = [doc["_source"] for doc in resp["hits"]["hits"]] return web.json_response({"users": UsersOutputTrafaret(users)})
class B(object): c = di.depends(object, 'c')
class A(object): b = di.depends(object, 'b') y = di.depends(Y, 'y')
class Cache(Base): processor = di.depends(Base, 'processor')
class Processor(Base): cache = di.depends(Base, 'cache')
class Source: value = di.depends(self.Consumer, 'consumer') def __injected__(self): assert self.value.value is 'John'
class MessagesView(ValidateMixin, generics.RetrieveUpdateAPIView, viewsets.GenericViewSet): """ GET or UPDATE one message. """ parser_classes = (JSONParser, ) next_handler = injections.depends(ProgressHandler) serializer_class = MessageSerializer queryset = Message.objects.all() authentication_classes = (SessionAuthentication, ) permission_classes = (IsAuthenticated, IsOwner) def roll_fsm_forward(self, chat, message): """ This method should be used when we want to roll fsm forward to the next serialized message and return it. :param chat: Chat instance :param message: Message :return: Response with serialized message """ chat.next_point = self.next_handler.next_point(current=message.content, chat=chat, message=message, request=self.request) chat.save() message.chat = chat serializer = self.get_serializer(message) return Response(serializer.data) def retrieve(self, request, *args, **kwargs): message = self.get_object() chat_id = self.request.GET.get('chat_id') try: chat = self.validate_and_get_chat(chat_id) except ValidationError as e: return Response({'errors': str(e)}) self.check_object_permissions(self.request, chat) next_point = chat.next_point if (message.contenttype in ['response', 'uniterror'] and message.content_id and next_point == message): return self.roll_fsm_forward(chat, message) if not message.chat or message.chat != chat or message.timestamp: serializer = self.get_serializer(message) return Response(serializer.data) if message and message.kind == 'add_faq' and message.sub_kind == 'add_faq': return self.roll_fsm_forward(chat, message) # Important for resolving additional messages if message and message.kind not in ('button', 'faqs'): if not ('additional' not in chat.state.fsmNode.funcName and message.kind == 'response'): # Set next message for user if not message.timestamp: message.timestamp = timezone.now() message.save() chat.next_point = self.next_handler.next_point( current=message.content, chat=chat, message=message, request=self.request) chat.save() message.chat = chat if message and message.kind == 'faqs': message.timestamp = timezone.now() message.save() serializer = self.get_serializer(message) return Response(serializer.data) def update(self, request, *args, **kwargs): chat_id = self.request.data.get('chat_id') try: chat = self.validate_and_get_chat(chat_id) except ValidationError as e: return Response({'errors': str(e)}) self.check_object_permissions(self.request, chat) message = self.get_object() if (message.input_type == 'text' and not self.request.data.get('text', '').strip() and not message.lesson_to_answer.lesson.sub_kind == Lesson.CANVAS): return Response({'error': 'Empty response. Enter something!'}) # run validation for numbers if message.lesson_to_answer and message.lesson_to_answer.lesson.sub_kind == 'numbers': try: float(self.request.data.get('text')) except ValueError: return Response({'error': 'Not correct value!'}) # Consider to move it to a backgrount task update_activity(chat_id) return super(MessagesView, self).update(request, *args, **kwargs) def perform_update(self, serializer): chat_id = self.request.data.get('chat_id') message = self.get_object() node = message.chat.state.fsmNode chat = Chat.objects.get(id=chat_id, user=self.request.user) activity = chat.state and chat.state.activity def is_in_node(node: str) -> bool: return message.chat.state.fsmNode.name == node # Check if message is not in current chat if not message.chat or message.chat != chat: return # Do procced the user response in the FSMNode if hasattr(node._plugin, 'handler'): node._plugin.handler(message, chat, self.request, self.next_handler) return if is_chat_add_faq(message) and is_in_node('GET_NEW_FAQ'): message.text = self.request.data.get('option', 'no') message.save() chat.last_modify_timestamp = timezone.now() chat.save() if message.input_type == 'text' and not message.sub_kind == 'add_faq': message.chat = chat text = self.request.data.get('text') if message.lesson_to_answer.sub_kind == Lesson.EQUATION: text = text.strip("$") text = '.. math:: ' + text resp = StudentResponse(text=text) # convert base64 attachment string to django File data_attachment = self.request.data.get('attachment') if data_attachment and data_attachment.startswith('data:image'): format, image_string = data_attachment.split(';base64,') extension = format.split('/')[-1].split('+')[0] name = '{}-{}.{}'.format('canvas', key_secret_generator(), extension) resp.attachment = ContentFile(base64.b64decode(image_string), name=name) if not message.content_id: resp.lesson = message.lesson_to_answer.lesson resp.unitLesson = message.lesson_to_answer resp.course = message.chat.enroll_code.courseUnit.course resp.author = self.request.user resp.activity = activity resp.is_test = chat.is_test resp.is_preview = chat.enroll_code.isPreview resp.sub_kind = resp.lesson.sub_kind else: resp = message.content resp.text = text resp.is_trial = chat.is_trial resp.save() if not message.timestamp: message.content_id = resp.id chat.next_point = message chat.last_modify_timestamp = timezone.now() chat.save() serializer.save(content_id=resp.id, timestamp=timezone.now(), chat=chat) else: serializer.save() message_is_response = message.contenttype == 'response' lesson_has_sub_kind = message.lesson_to_answer and message.lesson_to_answer.sub_kind content_is_not_additional = not message.content and not message.is_additional mc_selfeval = None if (message_is_response and lesson_has_sub_kind and content_is_not_additional) or ( message_is_response and message.lesson_to_answer and message.lesson_to_answer.sub_kind == 'choices' and not content_is_not_additional): resp_text = '' if message.lesson_to_answer.sub_kind == Lesson.MULTIPLE_CHOICES: selected_items = self.request.data.get('selected') try: selected = selected_items[str(message.id)]['choices'] except KeyError: # here request.data is like {"option":1,"chat_id":9,"selected":{"116":{"choices":[0]}}} selected_msg_ids = list( self.request.data.get('selected').keys()) # selected_messages == tuple with keys of this dict {"116":{"choices":[0]}} - it will be ("116",) msg_ids = Message.objects.filter(id__in=selected_msg_ids, chat=chat).values_list( 'id', flat=True) correct_ids = set(msg_ids).intersection( set(int(i) for i in list(selected_items.keys()))) selected_choices = [] for i in correct_ids: selected_choices.append( selected_items[str(i)]['choices']) selected = chain(*selected_choices) resp_text = '[selected_choices] ' + ' '.join( str(i) for i in selected) correct_choices = set([ _[0] for _ in message.lesson_to_answer.lesson.get_correct_choices() ]) selected_choices = set([_ for _ in chain(*selected_choices)]) if not (correct_choices - selected_choices or correct_choices ^ selected_choices): mc_selfeval = StudentResponse.CORRECT elif selected_choices & correct_choices: mc_selfeval = StudentResponse.CLOSE else: mc_selfeval = StudentResponse.DIFFERENT resp = StudentResponse(text=resp_text) # tes, preview flags resp.is_test = chat.is_test resp.selfeval = mc_selfeval or None resp.is_preview = chat.enroll_code.isPreview resp.is_trial = chat.is_trial resp.kind = message.lesson_to_answer.kind resp.sub_kind = message.lesson_to_answer.sub_kind resp.lesson = message.lesson_to_answer.lesson resp.unitLesson = message.lesson_to_answer resp.course = message.chat.enroll_code.courseUnit.course resp.author = self.request.user resp.activity = activity resp.save() if not message.timestamp: serializer.save(content_id=resp.id, timestamp=timezone.now(), chat=chat, response_to_check=resp) else: serializer.save() return if (is_in_node('GET_NEW_FAQ_TITLE') or is_in_node('GET_NEW_FAQ_DESCRIPTION')) \ and message_is_response and message.sub_kind == 'add_faq': text = self.request.data.get('text') faq_request = message.content if is_in_node('GET_NEW_FAQ_TITLE'): faq_request.title = text else: faq_request.text = text faq_request.save() faq_request.notify_instructors() message.text = text message.save() if is_in_node('GET_FOR_FAQ_ANSWER'): message.text = self.request.data.get('option', 'help') message.save() if is_in_node('GET_UNDERSTANDING'): message.text = self.request.data.get('option', 'no') message.save() if message.input_type == 'options' and message.kind != 'button': if (message.contenttype == 'uniterror' and 'selected' in self.request.data): # user selected error model message.chat = chat try: selected = self.request.data.get('selected')[str( message.id)]['errorModel'] except KeyError: selected = [] uniterror = message.content uniterror.save_response(user=self.request.user, response_list=selected) message.text = message.get_html() message.save() if not message.chat.is_live: get_additional_messages(uniterror.response, chat, selected) chat.next_point = self.next_handler.next_point( current=message.content, chat=chat, message=message, request=self.request) chat.last_modify_timestamp = timezone.now() chat.save() serializer = self.get_serializer(message, data=self.request.data) serializer.is_valid() serializer.save(chat=chat) elif (message.kind == 'add_faq' and message.sub_kind == 'add_faq') or \ (message.kind == 'get_faq_answer' and message.sub_kind == 'get_faq_answer') or \ (message.kind == 'ask_faq_understanding'): pass elif (message.contenttype == 'unitlesson' and message.kind == 'faqs' and 'selected' in self.request.data): message.chat = chat try: selected = self.request.data.get('selected')[str( message.id)]['faqModel'] except KeyError: selected = [] if selected: c_faq_data().update_one( { "chat_id": chat.id, "ul_id": message.content.id }, { "$set": { "faqs": { str(faq_id): { 'status': { "done": False } } for faq_id in selected } } }) # Save presented in message FAQs to avoid futher bugs in wrong dadta selection message.text = message.get_html() message.save() chat.next_point = self.next_handler.next_point( current=message.content, chat=chat, message=message, request=self.request) chat.last_modify_timestamp = timezone.now() chat.save() serializer = self.get_serializer(message, data=self.request.data) serializer.is_valid() serializer.save(chat=chat) elif message.contenttype == 'NoneType' and message.kind == 'abort': # user selected abort model message.chat = chat try: selected = self.request.data.get('selected')[str( message.id)]['errorModel'] except KeyError: selected = [] if not message.chat.is_live and selected: get_help_messages(chat) chat.next_point = self.next_handler.next_point( current=message.content, chat=chat, message=message, request=self.request) chat.last_modify_timestamp = timezone.now() chat.save() serializer.save(chat=chat) elif message.content_id and not message.student_error: # confidence and selfeval message.chat = chat opt_data = self.request.data.get('option') resp = message.content if chat.state and chat.state.fsmNode.node_name_is_one_of( 'GET_CONFIDENCE', 'ADDITIONAL_GET_CONFIDENCE'): resp.confidence = opt_data text = resp.get_confidence_display() else: resp.selfeval = opt_data text = resp.get_selfeval_display() # FIX if response was correct - user will not go to `else` section and response status should be set if not resp.is_locked: resp.status = EVAL_TO_STATUS_MAP.get(opt_data) message.text = text resp.save() chat.next_point = message chat.last_modify_timestamp = timezone.now() chat.save() serializer.save(content_id=resp.id, chat=chat, text=text) else: # message.chat = chat selfeval = self.request.data.get('option') resp = message.student_error resp.status = selfeval resp.save() # CRITICAL note - do not override response status # pass status to main response ONLY in case of absence the status at all # is_locked status is setted in TRANSITION node in chat FSM if not resp.response.is_locked: resp.response.status = selfeval resp.response.save() chat.next_point = message chat.last_modify_timestamp = timezone.now() chat.save() message.text = selfeval message.save() serializer.save(text=selfeval, chat=chat) if message.kind == 'button' and not (message.content_id and message.content and message.content.sub_kind): chat.last_modify_timestamp = timezone.now() chat.next_point = self.next_handler.next_point( current=message.content, chat=chat, message=message, request=self.request, ) chat.save()
class Z(object): x = di.depends(object, 'x')
class User: value = di.depends(self.Consumer, 'consumer')
class SmsHandler: twilio_gateway = injections.depends(TwilioGateway) async def send_sms(self, request): await self.twilio_gateway.send_sms("test message") return web.json_response({"status": "ok"})
class ChatInitialView(LoginRequiredMixin, View): """ Entry point for Chat UI. """ next_handler = injections.depends(ProgressHandler) template_name = 'chat/main_view.html' tester_mode = False @staticmethod def get_back_url(*args, **kwargs): """ Return link to back page - by default - lms course page. """ return "Course", reverse('lms:course_view', kwargs=dict(course_id=kwargs['courseUnit'].course.id)) @staticmethod def get_enroll_code_object(enroll_key): """ Return EnrollUnitCode object. :param enroll_key: enroll code :return: EnrollUnitCode instance """ return get_object_or_404(EnrollUnitCode, enrollCode=enroll_key, isPreview=False) @staticmethod def get_will_learn_need_know(unit, courseUnit): """ Steps to define Concepts for Will learn and Need to know: `/ct/teach/courses/:id/units/:id/` `/ct/teach/courses/:id/units/:id/lessons/` `/ct/teach/courses/:id/units/:id/lessons/:id/` `/ct/teach/courses/:id/units/:id/lessons/:id/concepts/` `Will learn` * We want all Concepts that Defines or Tests Understanding of Lesson * Choose Defines or Test for Concept `Need to know` * We want all Concepts that Assumes a Lesson * Choose Assumes for Concept """ will_learn = set() need_to_know = set() for unit_lesson in unit.get_exercises(): # QuerySet for "You will learn" and "Need to know" section containers_with_querysets = ( (will_learn, ConceptLink.objects.filter( Q(lesson=unit_lesson.lesson), (Q(relationship=ConceptLink.DEFINES) | Q(relationship=ConceptLink.TESTS))) if unit_lesson.unit.is_show_will_learn else ()), (need_to_know, ConceptLink.objects.filter( lesson=unit_lesson.lesson, relationship=ConceptLink.ASSUMES)) ) for contaner, qs in containers_with_querysets: for concept_link in qs: title = concept_link.concept.title if concept_link.lesson.url: url = concept_link.lesson.url else: ul = UnitLesson.objects.filter( lesson__concept=concept_link.concept ).values('id').first() if ul: url = reverse( 'ct:study_concept', args=(courseUnit.course.id, unit.id, ul['id']) ) if url: contaner.add((title, url)) return will_learn, need_to_know def get_or_init_chat(self, enroll_code, chat_id): """Get chat by id. Logic of this method is: * try to cast recieved ID to int * if gets an error while casting: * set i_chat_id = 0 if ValueError * set i_chat_id = None if TypeError * if i_chat_id: * try to get chat by id * if i_chat_id is None: * restore last session * if i_chat_id == 0: * create new chat :return i_chat_id and chat """ chat = None courseUnit = enroll_code.courseUnit try: # try to convert chat_id to int i_chat_id = int(chat_id) except ValueError: # if error - set i_chat_id to zero - it means create new chat i_chat_id = 0 except TypeError: i_chat_id = None if i_chat_id: # chat_id is passed - restore chat by id chat = self.get_chat(self.request, enroll_code, user=self.request.user, id=i_chat_id) elif i_chat_id is None: # chat_id not passed - restore last session chat = self.get_chat(self.request, enroll_code, user=self.request.user) elif i_chat_id == 0 and enroll_code: # create new session chat = self.create_new_chat(self.request, enroll_code, courseUnit) if chat and not chat.state: chat.next_point = None chat.save() return chat, i_chat_id @staticmethod def check_course_not_published_and_user_is_not_instructor(request, courseUnit): """ This method checks that course is not published and user is not instructor. :param request: request :param courseUnit: course unit :return: True | False """ return ( not courseUnit.is_published() and not User.objects.filter( id=request.user.id, role__role=Role.INSTRUCTOR, role__course=courseUnit.course ).exists() ) @staticmethod def user_enrolled(request, courseUnit): return Role.objects.filter( user=request.user.id, course=courseUnit.course, role=Role.ENROLLED ) def create_new_chat(self, request, enroll_code, courseUnit, **kwargs): # TODO user_trial_mode = self.define_user_trial_mode(request, courseUnit) defaults = dict( user=request.user, enroll_code=enroll_code, instructor=courseUnit.course.addedBy, is_preview=False, is_trial=False ) defaults.update(kwargs) chat = Chat(**defaults) chat.save() return chat def define_user_trial_mode(self, request, course_unit): """ Define trial mode for enrolled user depending on course's trial mode settings If mode still is undefined get percent of user's trial mode and if count of them is less than 50% set trial mode randomly, Arguments: request (obj): Django Request course_unit (obj): Model object Return (bool): Existing or newly added trial mode """ user = request.user user_enrolled = self.user_enrolled(request, course_unit).first() trial_mode = False if user_enrolled: # if user's role exists # course is trial and role.trial_mode has been set if course_unit.course.trial and user_enrolled.trial_mode is None: # get users enrolled to this course enrolled_users = Role.objects.filter( course_id=course_unit.course.id, role=Role.ENROLLED ) # count the percent of users in trial mode trial_mode_prsnt = float(enrolled_users.filter(trial_mode=True).count()) / enrolled_users.count() * 100 roles_to_update = Role.objects.filter( user=user.id, role__in=[Role.ENROLLED, Role.SELFSTUDY], course_id=course_unit.course.id) # if the percent is not exceeded get random value for trial mode if trial_mode_prsnt < 50: # hardcoded but can be implemented for adjusting from admin trial_mode = random.choice([True, False]) roles_to_update.update(trial_mode=trial_mode) else: trial_mode = bool(user_enrolled.trial_mode) # course is not trial or role has already been set return trial_mode @staticmethod def check_unitlessons_with_order_null_exists(unit): return unit.unitlesson_set.filter(order__isnull=False).exists() @staticmethod def get_chat(request, enroll_code, **kwargs): kw = dict( enroll_code=enroll_code, user=request.user, ) kw.update(kwargs) return Chat.objects.filter(**kw).first() def get_chat_sessions(self, request, enroll_code, courseUnit): return Chat.objects.filter( enroll_code=enroll_code, user=request.user, instructor=courseUnit.course.addedBy, is_live=False, is_test=self.tester_mode, is_preview=False ).annotate( not_finished=Case( When(state_id__isnull=True, then=0), When(state_id__isnull=False, then=1), default=0, output_field=IntegerField()) ).order_by('-not_finished', '-last_modify_timestamp') def get(self, request, enroll_key, chat_id=None): enroll_code = self.get_enroll_code_object(enroll_key) courseUnit = enroll_code.courseUnit unit = courseUnit.unit if not self.check_unitlessons_with_order_null_exists(unit): return render( request, 'lti/error.html', {'message': 'There are no Lessons to display for that Courselet.'} ) if self.check_course_not_published_and_user_is_not_instructor(request, courseUnit): return render( request, 'lti/error.html', {'message': 'This Courselet is not published yet or you have no permisions to open it.'} ) if not self.user_enrolled(request, courseUnit): enrolling = Role.objects.get_or_create(user=request.user, course=courseUnit.course, role=Role.SELFSTUDY)[0] enrolling.role = Role.ENROLLED enrolling.save() # new chat will be created only if chat_id is 0 chat, i_chat_id = self.get_or_init_chat(enroll_code, chat_id) lessons = unit.get_exercises() if chat and chat.is_live: lessons = Message.objects.filter( chat=chat, contenttype='unitlesson', kind='orct', type='message', owner=request.user, ) will_learn, need_to_know = self.get_will_learn_need_know(unit, courseUnit) try: instructor_icon = courseUnit.course.addedBy.instructor.icon_url except AttributeError: instructor_icon = '' chat_sessions = self.get_chat_sessions(request, enroll_code, courseUnit) back_url_name, back_url = self.get_back_url(**locals()) last_history = chat_sessions.filter(state__isnull=True, progress=100).order_by('id').last() updated_thread_id = None if last_history: updated_thread_id = get_updated_thread_id(last_history) return render( request, self.template_name, { 'chat_sessions_exists': len(chat_sessions), # mark for frontend 'chat_sessions': chat_sessions, # .exclude(id=chat.id), # TODO: UNCOMMENT this line to exclude current chat from sessions 'most_recent_complete_session': last_history, 'updated_thread_id': updated_thread_id or -1, 'chat': chat, 'chat_id': i_chat_id, 'course': courseUnit.course, 'instructor_icon': instructor_icon, 'unit': unit, 'img_url': unit.img_url, 'small_img_url': unit.small_img_url, 'will_learn': will_learn, 'need_to_know': need_to_know, 'lessons': lessons, 'lesson_cnt': len(lessons), 'duration': len(lessons) * 3, 'fsmstate': chat.state if chat else None, 'enroll_code': enroll_key, # 'next_point': next_point, 'back_url': back_url, 'back_url_name': back_url_name } )
class X(object): a = di.depends(object, 'a')
class Girl: father = di.depends(User, 'user')
class Consumer: value = di.depends(str, 'name') def hello(self): return "Hello {}!".format(self.value)
class Consumer: a = di.depends(int) b = di.depends(int)
class MessageSerializer(serializers.ModelSerializer): """ Message serializer. """ next_handler = injections.depends(ProgressHandler) input = serializers.SerializerMethodField() # errors = serializers.CharField(source='get_errors', read_only=True) addMessages = serializers.SerializerMethodField() nextMessagesUrl = serializers.CharField(source='get_next_url', read_only=True) class Meta: model = Message fields = ( 'id', 'input', 'addMessages', 'nextMessagesUrl', # 'errors', ) def set_group(self, obj): try: getattr(self, 'qs') except AttributeError: self.qs = [obj] if obj.timestamp: current = obj for message in obj.chat.message_set.filter( timestamp__gt=obj.timestamp): if self.next_handler.group_filter(current, message): current = message self.qs.append(message) def get_input(self, obj): """ Getting description for next message. """ self.set_group(obj) incl_msg = [] sub_kind = None for i in self.qs: if i.contenttype == 'uniterror' or i.kind == 'abort': incl_msg.append(i.id) if i.contenttype == 'unitlesson' and i.content: if i.content.lesson.sub_kind == 'choices': sub_kind = 'choices' incl_msg.append(i.id) if i.content.sub_kind == 'numbers': sub_kind = 'numbers' if i.content.lesson.sub_kind == 'equation': sub_kind = 'equation' elif i.content.lesson.sub_kind == 'canvas': sub_kind = 'canvas' # Add UnitLesson id for JS to check during selection validation if i.contenttype == 'unitlesson' and i.kind == 'faqs': incl_msg.append(i.id) input_data = { 'type': obj.get_next_input_type(), 'url': obj.get_next_url(), 'options': obj.get_options(), 'doWait': obj.chat.state.fsmNode.name.startswith('WAIT_') if obj.chat.state else False, 'includeSelectedValuesFromMessages': incl_msg, } if i.contenttype == 'unitlesson': if sub_kind == 'numbers': input_data[ 'html'] = '<input type="number" name="{}" value="{}">'.format( "text", 0, ) elif sub_kind == 'canvas': input_data['html'] = '<input type="hidden" />' input_data['subType'] = sub_kind if input_data['doWait']: input_data['html'] = ' ' elif not obj.chat.next_point: chat_id = obj.chat.enroll_code.courseUnit.course.id course_url = reverse('lms:course_view', kwargs={'course_id': chat_id}) html = f""" <button class="btn chat-option" data-option-value="close-courselet" onclick="window.location.href='{course_url}'"> Close courselet </button> """ if settings.SHOW_CLOSE_BTN and obj.chat.resources_is_done( ) else ' ' input_data['html'] = html return InputSerializer().to_representation(input_data) def get_addMessages(self, obj): self.set_group(obj) return InternalMessageSerializer(many=True).to_representation(self.qs)
class ChatInitialView(View): """ Entry point for Chat UI. """ next_handler = injections.depends(ProgressHandler) @method_decorator(login_required) def get(self, request, enroll_key): enroll_code = get_object_or_404(EnrollUnitCode, enrollCode=enroll_key) courseUnit = enroll_code.courseUnit unit = courseUnit.unit if not unit.unitlesson_set.filter(order__isnull=False).exists(): return render(request, 'lti/error.html', { 'message': 'There are no Lessons to display for that Courselet.' }) if (not courseUnit.is_published() and not User.objects.filter( id=request.user.id, role__role=Role.INSTRUCTOR, role__course=courseUnit.course).exists()): return render(request, 'lti/error.html', {'message': 'This Courselet is not published yet.'}) if not Role.objects.filter(user=request.user.id, course=courseUnit.course, role=Role.ENROLLED): enrolling = Role.objects.get_or_create(user=request.user, course=courseUnit.course, role=Role.SELFSTUDY)[0] enrolling.role = Role.ENROLLED enrolling.save() chat = Chat.objects.filter(enroll_code=enroll_code, user=request.user).first() if not chat and enroll_key: chat = Chat(user=request.user, enroll_code=enroll_code, instructor=courseUnit.course.addedBy) chat.save(request) if chat.message_set.count() == 0: next_point = self.next_handler.start_point(unit=unit, chat=chat, request=request) else: next_point = chat.next_point lessons = unit.get_exercises() will_learn = set() need_to_know = set() for unit_lesson in unit.get_exercises(): # QuerySet for "You will learn" and "Need to know" section containers_with_querysets = ( (will_learn, ConceptLink.objects.filter( Q(lesson=unit_lesson.lesson), (Q(relationship=ConceptLink.DEFINES) | Q(relationship=ConceptLink.TESTS)))), (need_to_know, ConceptLink.objects.filter(lesson=unit_lesson.lesson, relationship=ConceptLink.ASSUMES))) for contaner, qs in containers_with_querysets: for concept_link in qs: title = concept_link.concept.title if concept_link.lesson.url: url = concept_link.lesson.url else: ul = UnitLesson.objects.filter( lesson__concept=concept_link.concept).values( 'id').first() if ul: url = reverse('ct:study_concept', args=(courseUnit.course.id, unit.id, ul['id'])) if url: contaner.add((title, url)) return render( request, 'chat/main_view.html', { 'chat_id': chat.id, 'course': courseUnit.course, 'unit': unit, 'img_url': unit.img_url, 'small_img_url': unit.small_img_url, 'will_learn': will_learn, 'need_to_know': need_to_know, 'chat_id': chat.id, 'lessons': lessons, 'lesson_cnt': len(lessons), 'duration': len(lessons) * 3, 'next_point': next_point, 'fsmstate': chat.state, })