Пример #1
0
class RedisForCourse:
    """ 封装有关课程的数据库操作

        key format: STATUS:COURSE:COURSE_ID:xxx
        存储的是一个lesson_id
        表示当前课程最近一堂课的lesson_id
    """
    __PRIMARY_KEY = 'COURSE_ID'
    __TABLE_NAME = 'COURSE'
    __PREFIX = REDIS_DB_NAME + ':' + __TABLE_NAME + ':' + __PRIMARY_KEY

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

    def updateLesson(self, course_id, lesson_id):
        """ 插入一条课程状态记录

        :param course_id: 课程唯一标识
        :param lesson_id: 课程下课堂唯一标识
        :return:
        """
        # format: STATUS:COURSE:COURSE_ID:xxx
        key = self.__PREFIX + ':' + str(course_id)
        self.__conn.set(key, lesson_id)

    def getLastlyLessonID(self, course_id):
        """ 获取课程最近一堂课的lesson_id

        :param course_id: 课程唯一标识
        :return:
        """
        # format: STATUS:COURSE:COURSE_ID:xxx
        key = self.__PREFIX + ':' + str(course_id)

        return self.__conn.get(key)
class RedisForOnlineList:
    """ 封装有关课堂在线列表的数据库操作

        key format: STATUS:ONLINE_LIST:ID:(lesson_id)_(uid)
        存储的是一个uid
        这个key的用法实际上并不是很好,但是能实现需求
    """
    # 主键是由lesson_id与uid组成,中间通过下划线连接
    __PRIMARY_KEY = 'ID'
    __TABLE_NAME = 'ONLINE_LIST'
    __PREFIX = REDIS_DB_NAME + ':' + __TABLE_NAME + ':' + __PRIMARY_KEY

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

    def refresh(self, lesson_id, uid):
        """ 刷新用户状态,即重置key的存活时间

        :param lesson_id: 课程下课堂唯一标识
        :param uid: 用户唯一标识
        :return:
        """
        # format: STATUS:ONLINE_LIST:ID:(lesson_id)_(uid)
        key = self.__PREFIX + ':' + str(lesson_id) + '_' + str(uid)

        self.__conn.setex(name=key, value=uid, time=5)

    def getOnlineList(self, lesson_id):
        """ 获取该课堂在线的uid列表

        :param lesson_id: 课程下课堂唯一标识
        :return:
        """
        online_list = []
        key_list = self.__conn.keys(self.__PREFIX + ':' + str(lesson_id) +
                                    '_*')
        for key in key_list:
            online_list.append(self.__conn.get(key))

        return online_list
Пример #3
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)
Пример #4
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)
Пример #5
0
 def __init__(self):
     self.__conn = Redis().conn
Пример #6
0
class RedisForConc:
    """ 封装有关专注度记录的数据库操作

        每位用户的记录在redis中以list形式存储
        一堂课的所有详细记录都将会存储在这个list中
        仅通过一个key(format: STATUS:CONC:LESSON_ID:xxx)即可以访问到该课的所有记录
        或通过一个key(format: STATUS:CONC:ID:(lesson_id)_(uid))即可以访问到该用户的记录
        这个key的用法实际上并不是很好,但是能实现需求
    """
    __PRIMARY_KEY = 'LESSON_ID'
    __PRIMARY_KEY_ID = 'ID'

    __CONC = 'CONC'

    __PREFIX = REDIS_DB_NAME + ':' + __CONC + ':' + __PRIMARY_KEY
    __PREFIX_ID = REDIS_DB_NAME + ':' + __CONC + ':' + __PRIMARY_KEY_ID

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

    def addConcRecord(self, uid, course_id, lesson_id, begin_timestamp,
                      end_timestamp, conc_score):
        """ 插入一条最终记录

        :param uid: 用户唯一标识
        :param course_id: 课程唯一标识
        :param lesson_id: 课程下课堂唯一标识
        :param begin_timestamp: 该条记录生成依据的起始时间
        :param end_timestamp: 该条记录生成依据的结束时间
        :param conc_score: 专注度评分
        :return:
        """
        record_data = {
            'uid': uid,
            'course_id': course_id,
            'lesson_id': lesson_id,
            'begin_timestamp': begin_timestamp,
            'end_timestamp': end_timestamp,
            'conc_score': conc_score
        }
        # format: STATUS:CONC:LESSON_ID:xxx
        key = self.__PREFIX + ':' + str(lesson_id)
        # redis的list中不能直接存储data类型
        # 需先data转换为str
        self.__conn.lpush(key, json.dumps(record_data))
        # format: STATUS:CONC:ID:(lesson_id)_(uid)
        key = self.__PREFIX_ID + ':' + str(lesson_id) + '_' + str(uid)
        self.__conn.lpush(key, json.dumps(record_data))

    def getConcRecords(self, lesson_id):
        """ 获取该课程下课堂(lesson)的专注度信息

        :param lesson_id: 课程下课堂唯一标识
        :return:
            json格式数据
        """
        # format: STATUS:CONC:LESSON_ID:xxx
        key = self.__PREFIX + ':' + str(lesson_id)
        data_list = []
        str_list = self.__conn.lrange(key, 0, -1)
        for data_str in str_list:
            data_list.append(json.loads(data_str))

        return data_list

    def getLastConcRecordByUid(self, lesson_id, uid):
        """ 获取该用户的最新一条专注度信息

        :param lesson_id: 课程下课堂唯一标识
        :param uid: 用户唯一标识
        :return:
            json格式数据
        """
        # format: STATUS:CONC:ID:(lesson_id)_(uid)
        key = self.__PREFIX_ID + ':' + str(lesson_id) + '_' + str(uid)

        record = self.__conn.lindex(key, -1)
        if record is not None:
            return json.loads(self.__conn.lindex(key, 0))
        else:
            return None
Пример #7
0
class RedisForCourseStatus:
    """ 封装有关课程的各种状态的数据库操作

        key format: STATUS:COURSE_STATUS:COURSE_ID:xxx
        存储的是一个值CourseStatus(参考edu.py)
    """
    __PRIMARY_KEY = 'COURSE_ID'
    __TABLE_NAME = 'COURSE_STATUS'
    __PREFIX = REDIS_DB_NAME + ':' + __TABLE_NAME + ':' + __PRIMARY_KEY

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

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

        :param course_id: 课程唯一标识
        :return:
        """
        # format: STATUS:COURSE_STATUS:COURSE_ID:xxx
        key = self.__PREFIX + ':' + str(course_id)
        self.__conn.set(key, CourseStatus.OffLine)

    def getCourseStatus(self, course_id):
        """ 获取当前课程状态

        :param course_id: 课程唯一标识
        :return:
        """
        # format: STATUS:COURSE_STATUS:COURSE_ID:xxx
        key = self.__PREFIX + ':' + str(course_id)
        if not self.__conn.exists(key):
            self.createCourse(course_id=course_id)

        return int(self.__conn.get(key))

    def offLine(self, course_id):
        """ 课堂结束

        :return:
        """
        # format: STATUS:LESSON_STATUS:ID:xxx
        key = self.__PREFIX + ':' + str(course_id)
        self.__conn.set(key, CourseStatus.OffLine)

    def onLine(self, course_id):
        """ 正在上课

        :return:
        """
        # format: STATUS:LESSON_STATUS:ID:xxx
        key = self.__PREFIX + ':' + str(course_id)
        self.__conn.set(key, CourseStatus.OnLine)

    def cantJoinIn(self, course_id):
        """ 课堂不可中途加入

        :return:
        """
        # format: STATUS:LESSON_STATUS:ID:xxx
        key = self.__PREFIX + ':' + str(course_id)
        self.__conn.set(key, CourseStatus.CantJoinIn)

    def waiting(self, course_id):
        """ 在房间等待中,未开始上课

        :return:
        """
        # format: STATUS:LESSON_STATUS:ID:xxx
        key = self.__PREFIX + ':' + str(course_id)
        self.__conn.set(key, CourseStatus.Waiting)
Пример #8
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')
Пример #9
0
class RedisForUserStatus:
    """ 封装有关用户的各种状态的数据库操作

        key format: STATUS:USER_STATUS:UID:xxx
        存储的是一个值UserStatus(参考edu.py)
    """
    __PRIMARY_KEY = 'UID'
    __TABLE_NAME = 'USER_STATUS'
    __PREFIX = REDIS_DB_NAME + ':' + __TABLE_NAME + ':' + __PRIMARY_KEY

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

    def signUp(self, uid):
        """ 用户注册

        :param uid: 用户唯一标识
        :return:
        """
        # format: STATUS:USER_STATUS:UID:xxx
        key = self.__PREFIX + ':' + str(uid)
        self.__conn.set(key, UserStatus.Free)

    def getUserStatus(self, uid):
        """ 获取当前课程状态

        :param uid: 用户唯一标识
        :return:
        """
        # format: STATUS:USER_STATUS:UID:xxx
        key = self.__PREFIX + ':' + str(uid)
        if not self.__conn.exists(key):
            self.signUp(uid=uid)

        return int(self.__conn.get(key))

    def free(self, uid):
        """ 空闲

        :param uid: 用户唯一标识
        :return:
        """
        # format: STATUS:User_STATUS:UID:xxx
        key = self.__PREFIX + ':' + str(uid)
        self.__conn.set(key, UserStatus.Free)

    def inRoom(self, uid):
        """ 在房间中

        :param uid: 用户唯一标识
        :return:
        """
        # format: STATUS:LESSON_STATUS:UID:xxx
        key = self.__PREFIX + ':' + str(uid)
        self.__conn.set(key, UserStatus.InRoom)

    def inClass(self, uid):
        """ 在课堂中

        :param uid: 用户唯一标识
        :return:
        """
        # format: STATUS:LESSON_STATUS:UID:xxx
        key = self.__PREFIX + ':' + str(uid)
        self.__conn.set(key, UserStatus.InClass)