Beispiel #1
0
class RedisForLessonStatus:
    """ 封装有关课堂的各种状态的数据库操作

        key format: STATUS:LESSON_STATUS:LESSON_ID:xxx
        存储的是一个map
            |- lesson_id
            |- chat_status
    """
    __PRIMARY_KEY = 'LESSON_ID'
    __TABLE_NAME = 'LESSON_STATUS'
    __PREFIX = REDIS_DB_NAME + ':' + __TABLE_NAME + ':' + __PRIMARY_KEY

    def __init__(self):
        self.__conn = Redis().conn

    def createLesson(self, lesson_id):
        """ 插入一条课堂状态记录

        :param lesson_id: 课程下课堂唯一标识
        :return:
        """
        # format: STATUS:LESSON_STATUS:LESSON_ID:xxx
        key = self.__PREFIX + ':' + str(lesson_id)
        record_data = {
            'lesson_id': lesson_id,
            'course_status': CourseStatus.Waiting,
            'chat_status': ChatStatus.Free
        }
        self.__conn.hmset(key, record_data)

    def endLesson(self, lesson_id):
        """ 删除课堂状态记录

        :param lesson_id: 课程下课堂唯一标识
        :return:
        """
        # format: STATUS:LESSON_STATUS:LESSON_ID:xxx
        key = self.__PREFIX + ':' + str(lesson_id)
        self.__conn.delete(key)
Beispiel #2
0
class RedisForDetails:
    """ 封装有关每帧检测数据记录的数据库操作

        每位用户的记录在redis中以list形式存储
        一堂课的所有详细记录都将会存储在这个list中

        key format: STATUS:CONC_DETAILS:ID:(lesson_id)_(uid)
        key format: STATUS:CONC_USEFUL_DETAILS:ID:(lesson_id)_(uid)
        这个key的用法实际上并不是很好,但是能实现需求
    """
    __PRIMARY_KEY = 'ID'

    __DETAILS = 'CONC_DETAILS'
    __USEFUL_DETAILS = 'CONC_USEFUL_DETAILS'

    __DETAILS_PREFIX = REDIS_DB_NAME + ':' + __DETAILS + ':' + __PRIMARY_KEY
    __USEFUL_DETAILS_PREFIX = REDIS_DB_NAME + ':' + __USEFUL_DETAILS + ':' + __PRIMARY_KEY

    def __init__(self):
        self.__conn = Redis().conn

    def addDetail(self, is_succeed, uid, course_id, lesson_id, timestamp,
                  emotion, is_blinked, is_yawned, h_angle, v_angle):
        """ 插入一条详细记录

            详细记录是生成最终专注度记录的依据
            每10条详细记录可用于生成1条最终记录
        :param is_succeed: 是否成功识别到图像中的人脸(该条记录是否有用)
        :param uid: 用户唯一标识
        :param course_id: 课程唯一标识
        :param lesson_id: 课程下课堂唯一标识
        :param timestamp: 该条记录的时间戳(指的是图像截取的时间,而非记录生成的时间)
        :param emotion: 表情
        :param is_blinked: 是否有眨眼
        :param is_yawned: 是否有打哈欠
        :param h_angle: 头部的水平转动角度
        :param v_angle: 头部的垂直转动角度
        :return:
        """
        # format: STATUS:CONC_DETAILS:ID:(lesson_id)_(uid)
        key = self.__DETAILS_PREFIX + ':' + str(lesson_id) + '_' + str(uid)
        record_data = {
            'is_succeed': is_succeed,
            'uid': uid,
            'course_id': course_id,
            'lesson_id': lesson_id,
            'timestamp': timestamp,
            'emotion': emotion,
            'is_blinked': is_blinked,
            'is_yawned': is_yawned,
            'h_angle': h_angle,
            'v_angle': v_angle
        }
        # redis的list中不能直接存储data类型
        # 需先data转换为str
        self.__conn.lpush(key, json.dumps(record_data))

    def addUsefulDetail(self, is_succeed, uid, course_id, lesson_id, timestamp,
                        emotion, is_blinked, is_yawned, h_angle, v_angle):
        """ 插入一条能用于生成最终记录的详细记录

        :param is_succeed: 是否成功识别到图像中的人脸(该条记录是否有用)
        :param uid: 用户唯一标识
        :param course_id: 课程唯一标识
        :param lesson_id: 课程下课堂唯一标识
        :param timestamp: 该条记录的时间戳(指的是图像截取的时间,而非记录生成的时间)
        :param emotion: 表情
        :param is_blinked: 是否有眨眼
        :param is_yawned: 是否有打哈欠
        :param h_angle: 头部的水平转动角度
        :param v_angle: 头部的垂直转动角度
        :return:
            满10条记录后会返回True,以及10条json格式数据列表
            否则返回False,以及返回[]
        """
        # format: STATUS:CONC_USEFUL_DETAILS:ID:(lesson_id)_(uid)
        key = self.__USEFUL_DETAILS_PREFIX + ':' + str(lesson_id) + '_' + str(
            uid)
        record_data = {
            'is_succeed': is_succeed,
            'uid': uid,
            'course_id': course_id,
            'lesson_id': lesson_id,
            'timestamp': timestamp,
            'emotion': emotion,
            'is_blinked': is_blinked,
            'is_yawned': is_yawned,
            'h_angle': h_angle,
            'v_angle': v_angle
        }
        # redis的list中不能直接存储data类型
        # 需先data转换为str
        #
        # 满10条记录后会返回True
        if self.__conn.lpush(key, json.dumps(record_data)) >= 10:
            return True
        else:
            return False

    def getUsefulDetails(self, lesson_id, uid):
        """ 获取并清空可用的十条详细记录

        :param lesson_id: 课程下课堂唯一标识
        :param uid: 用户唯一标识
        :return:
            json格式数据
        """
        # format: STATUS:CONC_USEFUL_DETAILS:ID:(lesson_id)_(uid)
        key = self.__USEFUL_DETAILS_PREFIX + ':' + str(lesson_id) + '_' + str(
            uid)
        data_list = []
        str_list = self.__conn.lrange(key, 0, 9)
        for data_str in str_list:
            data_list.append(json.loads(data_str))
        self.__conn.delete(key)

        return data_list

    def clear(self, lesson_id, uid):
        """ 清除用户有关key

        :param lesson_id: 课程下课堂唯一标识
        :param uid: 用户唯一标识
        :return:
        """
        key_1 = self.__USEFUL_DETAILS_PREFIX + ':' + str(
            lesson_id) + '_' + str(uid)
        key_2 = self.__DETAILS_PREFIX + ':' + str(lesson_id) + '_' + str(uid)
        self.__conn.delete(key_1, key_2)
Beispiel #3
0
class RedisForInLesson:
    """ 封装有关用户上课情况的数据库操作

        key format: STATUS:IN_LESSON:UID:xxx
        存储的是一个map
            |- uid
            |- course_id
            |- lesson_id

        key format: STATUS:LESSON_USER:LESSON_ID:xxx
        存储的是一个set,存储用户的uid
    """
    __IN_LESSON_PRIMARY_KEY = 'UID'
    __IN_LESSON_TABLE_NAME = 'IN_LESSON'
    __IN_LESSON_PREFIX = REDIS_DB_NAME + ':' + __IN_LESSON_TABLE_NAME + ':' + __IN_LESSON_PRIMARY_KEY

    __LESSON_USER_PRIMARY_KEY = 'LESSON_ID'
    __LESSON_USER_TABLE_NAME = 'LESSON_USER'
    __LESSON_USER_PREFIX = REDIS_DB_NAME + ':' + __LESSON_USER_TABLE_NAME + ':' + __LESSON_USER_PRIMARY_KEY

    def __init__(self):
        self.__conn = Redis().conn

    def joinLesson(self, uid, course_id, lesson_id):
        """ 插入一条用户上课记录

            当用户退出该课堂的话
            需要删除该条记录
        :param uid: 用户唯一标识
        :param course_id: 课程唯一标识
        :param lesson_id: 课程下课堂唯一标识
        :return:
        """
        # format: STATUS:LESSON_STATUS:UID:xxx
        key = self.__IN_LESSON_PREFIX + ':' + str(uid)
        record_data = {
            'uid': uid,
            'course_id': course_id,
            'lesson_id': lesson_id
        }
        self.__conn.hmset(key, record_data)

        # format: STATUS:LESSON_USER:LESSON_ID:xxx
        key = self.__LESSON_USER_PREFIX + ':' + str(lesson_id)
        self.__conn.sadd(key, str(uid))

    def quitLesson(self, uid):
        """ 用户退出当前课堂

            把该key删除
        :param uid: 用户唯一标识
        :return:
        """
        # format: STATUS:LESSON_STATUS:UID:xxx
        key = self.__IN_LESSON_PREFIX + ':' + str(uid)
        lesson_id = self.getLessonID(uid=str(uid))
        self.__conn.delete(key)

        # format: STATUS:LESSON_USER:LESSON_ID:xxx
        key = self.__LESSON_USER_PREFIX + ':' + str(lesson_id)
        self.__conn.srem(key, str(uid))

    def getLessonUsersUID(self, lesson_id):
        """ 获取参与该课的所有用户ID

        :param lesson_id: 课程下课堂唯一标识
        :return:
        """
        # format: STATUS:LESSON_USER:LESSON_ID:xxx
        key = self.__LESSON_USER_PREFIX + ':' + str(lesson_id)
        uid_arr = self.__conn.smembers(key)

        return uid_arr

    def isInLesson(self, uid):
        """ 查询用户是否在上课

        :param uid: 用户唯一标识
        :return: True - 在课室中/正在上课(即Waiting或Online状态)
                 False - 空闲状态
        """
        # format: STATUS:LESSON_STATUS:UID:xxx
        key = self.__IN_LESSON_PREFIX + ':' + str(uid)

        return self.__conn.hexists(key)

    def getLessonID(self, uid):
        """ 获取该用户当前课堂的id

        :param uid: 用户唯一标识
        :return: id - 存在(在课室中/正在上课)
                 None - 不存在(空闲状态)
        """
        # format: STATUS:LESSON_STATUS:UID:xxx
        key = self.__IN_LESSON_PREFIX + ':' + str(uid)

        return self.__conn.hget(key, 'lesson_id')