コード例 #1
0
class OutgoingCalls(db.Model):

    __tablename__ = 'outgoing_calls'

    id = db.Column(db.Integer, primary_key=True)
    contact_id = db.Column(db.Integer, db.ForeignKey('student_contacts.id'))
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
コード例 #2
0
class QuestionOptions(db.Model):

    __tablename__ = 'question_options'

    id = db.Column(db.Integer, primary_key=True)
    en_text = db.Column(db.Unicode(2000, collation='utf8mb4_unicode_ci'))
    hi_text = db.Column(db.Unicode(2000, collation='utf8mb4_unicode_ci'))
    question_id = db.Column(db.Integer, db.ForeignKey('questions.id'))
    correct = db.Column(db.Boolean, default=False)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)

    @staticmethod
    def create_option(**kwargs):
        """
        Staticmethod to create option for a specific question_id in the database
        Params:
            `en_text` : english text of the option, required, str
            `hi_text` : hindi text of the option, required, str
            `question_id` : id of the question of the options, required, int
            `correct` = False, bool
        Return QuestionOptions instance
        """
        question_option = QuestionOptions(**kwargs)
        db.session.add(question_option)

        return question_option
コード例 #3
0
class StudentContact(db.Model):

    __tablename__ = 'student_contacts'

    id = db.Column(db.Integer, primary_key=True)
    contact = db.Column(db.String(10))
    main_contact = db.Column(db.Boolean, default=False)
    student_id = db.Column(db.Integer, db.ForeignKey('students.id'))
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    incoming_calls = db.relationship('IncomingCalls',
                                     backref='contact',
                                     cascade='all, delete-orphan',
                                     lazy='dynamic')
    outgoing_calls = db.relationship('OutgoingCalls',
                                     backref='contact',
                                     cascade='all, delete-orphan',
                                     lazy='dynamic')
    outgoing_messages = db.relationship('OutgoingSMS',
                                        backref='contact',
                                        cascade='all, delete-orphan',
                                        lazy='dynamic')

    def send_sms(self, message, sms_type):
        """
            For sending the message to number associtated with this instance using exotel api.

            Params:
                `message` : Contains the message that need to be sent str required
                `sms_type` : Sending SMS Type

            Usage: student_contact.send_sms(message)

        """
        exotel.sms(app.config.get("EXOTEL_SMS_NUM"), self.contact, message)

        # recording the outgoing sms in chanaya
        outgoing_sms = OutgoingSMS(contact_id=self.id,
                                   type=sms_type,
                                   text=message)
        db.session.add(outgoing_sms)
        db.session.commit()

    @staticmethod
    def create(contact, student_id, main_contact=False):
        """
            Function is used for creating a new student_contact record for the student_id.

            Params:
                `contact` : '7896121314' Student mobile number
                `student_id`: '21' Student id
                `main_contact`: True(default is False) True if we can call on this number to connect with the student else False.
        """

        student_contact = StudentContact(contact=contact,
                                         student_id=student_id,
                                         main_contact=main_contact)
        db.session.add(student_contact)
        db.session.commit()
コード例 #4
0
class OutgoingSMS(db.Model):

    __tablename__ = 'outgoing_sms'

    id = db.Column(db.Integer, primary_key=True)
    contact_id = db.Column(db.Integer, db.ForeignKey('student_contacts.id'))
    type = db.Column(db.Enum(app.config['OUTGOING_SMS_TYPE']), nullable=False)
    text = db.Column(db.String(1000), nullable=False)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
コード例 #5
0
class QuestionAttempts(db.Model):

    __tablename__ = 'attempts'

    id = db.Column(db.Integer, primary_key=True)
    enrolment_key_id = db.Column(db.Integer,
                                 db.ForeignKey('enrolment_keys.id'),
                                 nullable=False)
    question_id = db.Column(db.Integer,
                            db.ForeignKey('questions.id'),
                            nullable=False)
    question = db.relationship('Questions')
    selected_option_id = db.Column(
        db.Integer, db.ForeignKey('question_options.id'))  #to store mcq answer
    answer = db.Column(db.String(10))  #to store integer value
    created_at = db.Column(db.DateTime, default=datetime.utcnow)

    @staticmethod
    def create_attempts(questions_attempts, enrollment):
        """
            Create the answer attempt made for each enrollment key generated.

            Params:
                    `enrollment` = EnrolmentKey instance,
                    `question_attempted`: [
                        {
                            'question_id' : 23,
                            'selected_option_id' : 19,
                        },
                        {
                            'question_id' : 23,
                            'answer': '216'
                        }
                    ]
        """
        # recording the answer
        for question_attempt in questions_attempts:
            # each attempts for test are for the single enrollment key
            question_attempt['enrolment_key_id'] = enrollment.id
            if not question_attempt.get('selected_option_id'):
                question_attempt['selected_option_id'] = None
            attempt = QuestionAttempts(**question_attempt)
            db.session.add(attempt)
        db.session.commit()
コード例 #6
0
class StudentStageTransition(db.Model):

    __tablename__ = 'stage_transitions'

    id = db.Column(db.Integer, primary_key=True)
    from_stage = db.Column(db.String(100), nullable=False)
    to_stage = db.Column(db.String(100), nullable=False)
    notes = db.Column(db.String(1000))
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    student_id = db.Column(db.Integer, db.ForeignKey('students.id'))
    student = db.relationship("Student")
コード例 #7
0
class IncomingCalls(db.Model):

    __tablename__ = 'incoming_calls'

    id = db.Column(db.Integer, primary_key=True)
    contact_id = db.Column(db.Integer, db.ForeignKey('student_contacts.id'))
    call_type = db.Column(db.Enum(app.config['INCOMING_CALL_TYPE']),
                          nullable=False)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)

    @staticmethod
    def create(student_contact, call_type):
        """
            Helps to record all the incoming call made by a students phone number.
            Params:
                `student_contact` : StudentContact instance,
                `call_type`: 'RQC' ['EKG', 'RQC', 'INTERESTED']
        """

        incoming_call = IncomingCalls(contact_id=student_contact.id,
                                      call_type=call_type)
        db.session.add(incoming_call)
        db.session.commit()
コード例 #8
0
class EnrolmentKey(db.Model):

    __tablename__ = 'enrolment_keys'

    id = db.Column(db.Integer, primary_key=True)
    key = db.Column(db.String(6), unique=True)
    test_start_time = db.Column(db.DateTime, nullable=True)
    test_end_time = db.Column(db.DateTime, nullable=True)
    student_id = db.Column(db.Integer, db.ForeignKey('students.id'))
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    question_set_id = db.Column(db.Integer, db.ForeignKey('sets.id'))
    score = db.Column(db.Integer, nullable=True)

    attempts = db.relationship('QuestionAttempts',
                               backref='enrollment',
                               cascade='all, delete-orphan',
                               lazy='dynamic')

    question_set = db.relationship("QuestionSet",
                                   back_populates="enrolment_key")

    @staticmethod
    def generate_key(student_id):
        """
            The method helps to generate a unique enrollment key for the student_id provided
            and add it to student record.
            Params:
                `student_id`: int
            Return enrollment (object associated to the student_id)
        """
        # generating a new enrollment key
        ALPHABETS, NUMBERS = string.ascii_uppercase, string.digits
        enrollment_key = "".join([
            random.choice(ALPHABETS) for x in range(3)
        ]) + "".join([random.choice(NUMBERS) for x in range(3)])
        # checking if the enrollment key already exist or not
        while EnrolmentKey.query.filter_by(key=enrollment_key).first():
            enrollment_key = "".join([
                random.choice(ALPHABETS) for x in range(3)
            ]) + "".join([random.choice(NUMBERS) for x in range(3)])
        # record the  enrollment key in the database
        enrollment = EnrolmentKey(student_id=student_id, key=enrollment_key)
        db.session.add(enrollment)
        db.session.commit()

        return enrollment

    def calculate_test_score(self):
        """
            Test Score Calulcation.

            The method calculate marks for all the questions attempted by each enrollment key(Student).
            The marks realted to each question are in CONFIG file based on question difficulty level.

            Update the marks to the score column in the enrollment.
        """

        attempts = self.attempts.all()
        # get marks config
        marks_config = app.config['QUESTION_CONFIG']['marks_config']

        score = 0
        # iterate over each question
        for attempt in attempts:
            question = attempt.question
            is_correct = False
            # for mcq check if the id which is select is correct = True or not
            if question.type.value == 'MCQ':
                selected_option_id = attempt.selected_option_id
                # for integer_answer strip both attempt answer and answer in the db and check if both are equal or not
                option = QuestionOptions.query.get(selected_option_id)
                if option.correct:
                    is_correct = True
            else:
                option = question.options.first()
                correct_answer = option.en_text.strip()
                student_answer = attempt.answer.strip()

                if correct_answer == student_answer:
                    is_correct = True

            # if the flag is true include the score in the score variable
            if is_correct:
                question_difficulty = question.difficulty.value
                mark = marks_config[question_difficulty]
                score += mark
        print(score)

        self.score = score
        db.session.add(self)
        db.session.commit()

        if self.score < app.config['MINIMUM_PASSING_SCORE']:
            outgoing_sms = app.config['OUTGOING_SMS']['ETF']
        else:
            outgoing_sms = app.config['OUTGOING_SMS']['ETP']

        message = outgoing_sms['message']
        sms_type = app.config['OUTGOING_SMS_TYPE'](outgoing_sms['sms_type'])
        student = self.student

        student.send_sms_to_all_numbers(message, sms_type)

    def get_question_set(self):
        """
            Generate a question set corresponding to this enrolment key and return
            the question set instanceself.

            Note: Also runs the start_test method on the instance.
        """
        self.start_test()
        question_set, questions = QuestionSet.create_new_set()
        self.question_set_id = question_set.id
        db.session.add(self)
        db.session.commit()
        return question_set, questions

    def start_test(self):
        """
            Marks the `test_start_time` parameter of the enrolment key.
            Also marks the `test_end_time` as `test_start_time` + the time allowed for the test.
        """
        current_datetime = datetime.now()
        self.test_start_time = current_datetime

    def end_test(self):
        """
            This records the end time of the test in `test_end_time` attribute.
        """
        self.test_end_time = datetime.now()
        db.session.add(self)
        db.session.commit()

    def is_valid(self):
        """
            The method checks if the key is been used or not
            if it is not used then the key is valid

            No params
            Usage:
                enrollment.is_valid()
            Return Boolean value
        """
        current_datetime = datetime.now()
        # if the test hasn't started of the key it is valid
        if not self.test_start_time:
            return True
        expired_datetime = self.test_start_time + timedelta(
            seconds=app.config['TEST_DURATION'])
        # if the test has end for the enrollment key then it is not valid
        if expired_datetime and expired_datetime <= current_datetime:
            return False
            #if the test is ongoing then it is valid
        elif expired_datetime > current_datetime:
            return True

    def is_test_ended(self):
        """
            Checks if the enrollment mkey has been used to give the test or not.
            No Params
            Usage:
                enrollment.is_test_ended()
            Returns True if the test has ended else False.
        """
        if self.test_end_time:
            return True
        return False

    def in_use(self):
        """
            Check if the enrollment key is already in used or not.
            No Params
            Usage:
                enrollment.in_use()
            Return Boolean(True when it is being used else False)

        """
        current_datetime = datetime.now()

        # if it is not used
        if not self.test_start_time:
            return False
        expired_datetime = self.test_start_time + timedelta(
            seconds=app.config['TEST_DURATION'])
        # on being used
        if expired_datetime > current_datetime:
            return True

        return False