• CSIC_716_20191224【python基础结课作业--仿优酷练习】


    需  求:
    ********管理员界面********

    1 注册
    2 登录
    3 上传视频
    4 删除视频
    5 发布公告


    ********普通用户界面********
    1 注册
    2 登录
    3 冲会员
    4 查看视频
    5 下载免费视频
    6 下载收费视频
    7 查看下载记录
    8 查看公告
    q.退出




    软件开发目录:

     




    服务端Server
    1 # _*_ coding: gbk _*_
    2 # @Author: Wonder
    3 import os
    4 BASE_PATH = os.path.dirname(os.path.dirname(__file__))
    5 MOVIE_DIR_PATH = os.path.join(BASE_PATH,'movie')
    6 
    7 IP = '127.0.0.1'
    8 PORT = 9527
    settings.py
    # _*_ coding: gbk _*_
    # @Author: Wonder
    from orm_control.orm import Models, StringField, IntegerField
    import datetime
    '''
    每个字段的四个属性name, field_type, is_primary, default   
    其中field_type、is_primary、default都有默认值
    '''
    '''
    # 用户表类: id、用户名、密码、用户类型、是否为VIP、注册时间 
    # 电影表类: id、电影名字、电影大小、电影md5值、电影是否免费、电影是否删除、上传时间、上传用户的id
    # 公告表类: id、公告标题, 公告内容、发布时间、发布用户id
    # 下载记录表: id、下载电影的id、下载用户的id、下载时间
    '''
    
    
    class User(Models):
        '''
        # 用户表类: id、用户名、密码、用户类型、是否为VIP、注册时间
        '''
        u_id = IntegerField(name='u_id', is_primary=True)
        username = StringField(name='username')
        password = StringField(name='password')
        user_type = IntegerField(name='user_type',)  # 此处 0为普通用户,1 为管理员,默认值为
        is_vip = IntegerField(name='is_vip')  # 此处 0 为普通用户,1 为VIP
        reg_time = StringField(name='reg_time')  # 每个字段的默认值,可以在这些个性化的类中进行设置
    
    
    class Movie(Models):
        '''
        # 电影表类: id、电影名字、电影大小、电影md5值、电影是否免费、电影是否删除、上传时间、上传用户的id
        '''
        m_id = IntegerField(name='m_id', is_primary=True)
        name = StringField(name='name')
        size = IntegerField(name='size')
        md5 = StringField(name='md5')
        is_free = IntegerField(name='is_free')  #默认0是免费,1 是收费
        is_del = IntegerField(name='is_del')
        up_time = StringField(name='movie_name')
        u_id = IntegerField(name='movie_name')
    
    
    class Notice(Models):
        '''
        id、公告标题, 公告内容、发布时间、发布用户id
        '''
        n_id = IntegerField(name='n_id', is_primary=True)
        title = StringField(name='title')
        content = StringField(name='content')
        release_time = StringField(name='release_time')
        u_id = IntegerField(name='u_id')
    
    
    class Record(Models):
        '''
        # 下载记录表: id、下载电影的id、下载用户的id、下载时间
        '''
        r_id = IntegerField(name='r_id', is_primary=True)
        m_id = IntegerField(name='m_id')
        u_id = IntegerField(name='u_id')
        down_time = StringField(name='down_time')
    
    
    if __name__ == '__main__':
        import  time
        # user_obj = User(
        #                  username='张五',  # id是不用传值的,因为在数据库中实现了自增
        #                  password ='1234',
        #                  user_type=1,
        #                  is_vip=0,
        #                  reg_time=time.strftime('%Y-%m-%d %X')
        #                 )
        # user_obj.insert_data()
        # res = User.select_data()   # [ 字典、]
        # print(res)
    
        user_obj = User.select_data(u_id=1)[0]  # 这里注意,是个字典套对象,要注意取值
        user_obj.username = '张九'
        user_obj.update_data()
    
        res = User.select_data()  # [ 字典(对象)、]  这里的对象就是字典,一个特殊的对象,类dict的对象。
        print(res)
    models.py
    # _*_ coding: gbk _*_
    # @Author: Wonder
    import os
    import uuid
    from conf import settings
    from lib import common
    import time
    from db.models import Notice, Movie
    
    
    @common.login_auth
    def check_movie_interface(dic, conn, addr):
        md5 = dic.get('movie_md5')
        movie_list = Movie.select_data(md5=md5)
        if movie_list:
            back_dic = {
                'flag': False,
                'msg': '电影已存在'
            }
        else:
            back_dic = {
                'flag': True,
            }
        common.send_data(back_dic, conn)
    
    
    @common.login_auth
    def upload_movie_interface(dic, conn, addr):
        movie_size = dic.get('movie_size')
        movie_name = str(uuid.uuid4()).replace('-', '_') + dic.get('movie_name')  # 为了保证名字不同的电影重名时,能保存
        movie_path = os.path.join(settings.MOVIE_DIR_PATH, movie_name)
        temp_size = 0
        with open(movie_path, 'wb') as f:
            while temp_size < movie_size:
                data = conn.recv(1024)
                f.write(data)
                temp_size += len(data)
    
        back_dic = {
            'msg': '传完了'
        }
    
        mv_obj = Movie(
            name=movie_name,
            size=movie_size,
            md5=dic.get('movie_md5'),
            is_free=dic.get('is_free'),
            up_time=time.strftime('%Y-%m-%d %X'),
            u_id=dic.get('u_id'),
        )
        print(1)
        mv_obj.insert_data()
        print(2)
        common.send_data(back_dic, conn)
    
    
    @common.login_auth
    def del_mv_interface(dic, conn, addr):
        movie_name = dic.get('mv_name')
        mv_obj = Movie.select_data(name=movie_name)[0]
        mv_obj.is_del = 1
        mv_obj.update_data()
        back_dic = {
            'msg': f'{mv_obj.name}已删除'
        }
        print('看一眼')
        common.send_data(back_dic, conn)
    
    
    @common.login_auth
    def relaese_notice_interface(dic, conn, addr):
        notice_obj = Notice(
            title=dic.get('title'),
            content=dic.get('content'),
            release_time=time.strftime('%Y-%m-%d %X'),
            u_id=dic.get('u_id')
    
        )
        print(notice_obj)
        notice_obj.insert_data()
        back_dic = {'msg': '公告发布成功'}
        common.send_data(back_dic, conn)
    admin_interface
    # _*_ coding: gbk _*_
    # @Author: Wonder
    from db.models import User
    from user_data import session
    from lib import common
    import time
    from db.models import User,  Movie
    # from tcp_server.server import mutex
    from threading import Lock
    # mutex = Lock()
    
    
    # 注册接口
    def register_interface(dic, conn, addr):
        username = dic.get('username')
        user_type = dic.get('user_type')
        user_list = User.select_data(username=username)
        if user_list:
            send_dic = {
                'flag': False, 'msg': '用户已存在'
            }
        else:
            user_obj = User(
                username=username,
                user_type=user_type,
                password=common.get_md5(dic.get('password')),
                reg_time=time.strftime('%Y-%m-%d %X'),
            )
            user_obj.insert_data()
            send_dic = {
                'flag': True, 'msg': '注册成功'
            }
        common.send_data(send_dic, conn)
    
    
    # 登录接口   核对登录密码,更新session文件
    def login_interface(dic, conn, addr):
        username = dic.get('username')
        user_list = User.select_data(username=username)
        if not user_list:
            dic = {
                'flag': False, 'msg': '用户不存在'
            }
            common.send_data(dic, conn)
        else:
            input_pwd = common.get_md5(dic.get('password'))
            input_type = dic.get('user_type')
            record_pwd = user_list[0].get('password')
            record_type = user_list[0].get('user_type')
            if not input_pwd == record_pwd:
                dic = {
                    'flag': False, 'msg': '用户名或密码不正确'
                }
                common.send_data(dic, conn)
            elif not input_type == record_type:
                print('传来的',input_type)
                print('系统的',record_type)
    
                dic = {
                    'flag': False, 'msg': '非法用户'
                }
                common.send_data(dic, conn)
    
            else:
                u_id = user_list[0].get('u_id')
                is_vip = user_list[0].get('is_vip')
                new_session = common.get_session()
                # mutex.locked()
                session.user_info[addr] = [new_session, u_id]
                # mutex.release()
    
                dic = {
                    'flag': True,
                    'msg': '登录成功',
                    'session': new_session,
                    'u_id': u_id,
                    'is_vip': is_vip
                }
                # print('服务端的session',dic)
                common.send_data(dic, conn)
    
    
    # 查看没有被删除的所有电影
    @common.login_auth
    def check_nodel_movie_interface(dic, conn, addr):
        # 查出来可以删除的电影 is_del=0
        mv_obj_list = Movie.select_data()
    
        if not mv_obj_list:
            dic = {
                'flag': False,
                'msg': '没有电影'
            }
        else:
            mv_name_list = [i for i in mv_obj_list if i.is_del == 0]  # 找出所有没有删除的
            free_mv_list = [i.name for i in mv_name_list if i.is_free == 0]  # 找出没删除的  免费 的 名字
            # print('免费的电影', free_mv_list)
            pay_mv_list = [i.name for i in mv_name_list if i.is_free == 1]  # 找出没删除   付费的 的名字
            # print('收费的电影', pay_mv_list)
            if dic.get('select_type') == 'all':
                mv_list = free_mv_list
                mv_list.extend(pay_mv_list)
            elif dic.get('select_type') == 'free':
                mv_list = free_mv_list
            else:
                mv_list = pay_mv_list
    
            if not mv_list:
                dic = {
                    'flag': False,
                    'msg': '没有电影'
                }
            else:
                dic = {
                    'flag': True,
                    'mv_list': mv_list
                }
        common.send_data(dic, conn)
    common_interface
    # _*_ coding: gbk _*_
    # @Author: Wonder
    import os
    import time
    from db.models import User, Record, Movie, Notice
    from conf.settings import MOVIE_DIR_PATH
    from lib import common
    
    
    # 充值会员接口
    @common.login_auth
    def paymember_interface(dic, conn, addr):
        print('开始充钱啦')
        user_obj = User.select_data(
            u_id=dic.get('u_id')
        )[0]
        print(user_obj)
        user_obj.is_vip = 1
        user_obj.update_data()
        back_dic = {
            'msg': '充值成功'
        }
        common.send_data(back_dic, conn)
    
    
    # 下载电影接口
    @common.login_auth
    def download_mv_interface(dic, conn, addr):
        mv_name = dic.get('mv_name')
        # 打开服务器端供下载的文件夹
        file_path = os.path.join(MOVIE_DIR_PATH, mv_name)
        mv_size = os.path.getsize(file_path)
    
        back_dic = {
            'mv_size': mv_size
        }
    
        # 下载完了之后,还要将下载记录插入到下载表中
        mv_obj = Movie.select_data(name=mv_name)  # 在此处通过名字取值,会增加数据库负担
        m_id = mv_obj[0].m_id  #单个一定要指定0,否则不执行
        rec_obj = Record(
            m_id=m_id,
            u_id=dic.get('u_id'),  # 装饰器给加进去的
            down_time=time.strftime('%Y-%m-%d %X')
        )
        rec_obj.insert_data()
        common.send_data(back_dic, conn, file_path)  # 将报头和内容进行整合
    
    #查看下载记录
    @common.login_auth
    def check_record_interface(dic, conn, addr):
        u_id = dic.get('u_id')
        record_obj = Record.select_data(u_id=u_id)
        if not record_obj:
            back_dic = {
                'flag': False,
                'msg': '没有下载记录'
            }
        else:
            movie_id_list = [i.m_id for i in record_obj]  # 将电影的id取出来
            mv_obj = Movie.select_data()
            movie_list = [i.name for i in mv_obj if i.m_id in movie_id_list] # 取出名字
            back_dic = {
                'flag': True,
                'mv_list': movie_list
            }
        common.send_data(back_dic, conn)
    
    # 查看下载记录
    @common.login_auth
    def check_notice_interface(dic, conn, addr):
        notice_obj = Notice.select_data()
        if not notice_obj:
            back_dic = {
                'flag': False,
                'msg': '没有公告'
            }
        else:
            notice_list = [f'标题{i.title},内容{i.content}' for i in notice_obj]
            back_dic = {
                'flag': True,
                'notice_list': notice_list
            }
        common.send_data(back_dic, conn)
    user_interface
    # _*_ coding: gbk _*_
    # @Author: Wonder
    import json
    import struct
    from hashlib import md5
    import uuid
    from user_data import session
    # from tcp_server.server import mutex
    from  threading import Lock
    # mutex = Lock()
    
    # 发数据
    def send_data(dic, conn, path=None):
        send_dic = json.dumps(dic).encode('utf-8')
        send_head = struct.pack('i', len(send_dic))
        conn.send(send_head)
        conn.send(send_dic)
        if path:
            with open(path, 'rb') as f:
                for line in f:
                    conn.send(line)
    
    
    # md5进行加密
    def get_md5(pwd):
        md5_obj = md5()
        md5_obj.update(pwd.encode('utf-8'))
        sal = 'youku_sys'
        md5_obj.update(sal.encode('utf-8'))
        return md5_obj.hexdigest()
    
    
    # 获取一个session随机字符串
    def get_session():
        rand_str = str(uuid.uuid4())
        return get_md5(rand_str)
    
    
    # 登录 验证装饰器
    def login_auth(func):  # 将用户id添加到字典中
        def inner(*args, **kwargs):  # *args (dic,conn ,addr)
            print('进入装饰器啦------------')
            recv_dic = args[0]
    
            conn = args[1]
    
            client_session = recv_dic.get('cookies')
            addr = args[2]
            # print('打印一下文件中是否有内容',session.user_info)
            # mutex.locked()
            server_session = session.user_info.get(addr)
            # mutex.release()
    
            if server_session:
                if client_session == server_session[0]:
                    recv_dic['u_id'] = server_session[1]
                    res = func(*args, **kwargs)
                    return res
                else:
                    dic = {
                        'flag': False,
                        'msg': '重新登陆'
                    }
                    send_data(dic, conn)
            else:
                dic = {
                    'flag': False,
                    'msg': '******请先登陆******'
                }
                send_data(dic, conn)
    
        return inner
    
    
    if __name__ == '__main__':
        msg = get_md5('www')
        print(msg)
    common
    # _*_ coding: gbk _*_
    # @Author: Wonder
    
    from DBUtils.PooledDB import PooledDB
    import pymysql
    
    
    Pool = PooledDB(
        # creator,
        # mincached=0,
        # maxcached=0,
        # maxshared=0,
        # maxconnections=0,
        # blocking=False,
        # maxusage=None,
        # setsession=None,
        # reset=True,
        # failures=None,
        # ping=1,
    creator=pymysql,  # 使用链接数据库的模块
        maxconnections=6,  # 连接池允许的最大连接数,0和None表示不限制连接数
        mincached=2,  # 初始化时,链接池中至少创建的空闲的链接,0表示不创建
        maxcached=5,  # 链接池中最多闲置的链接,0和None不限制
        maxshared=3,
        # 链接池中最多共享的链接数量,0和None表示全部共享。
        # PS: 无用,因为pymysql和MySQLdb等模块的 threadsafety都为1,所有值无论设置为多少,_maxcached永远为0,所以永远是所有链接都共享。
        blocking=True,  # 连接池中如果没有可用连接后,是否阻塞等待。True,等待;False,不等待然后报错
        maxusage=None,  # 一个链接最多被重复使用的次数,None表示无限制
        setsession=[],  # 开始会话前执行的命令列表。如:["set datestyle to ...", "set time zone ..."]
        ping=0,
        # ping MySQL服务端,检查是否服务可用。# 如:0 = None = never, 1 = default = whenever it is requested, 2 = when a cursor is created, 4 = when a query is executed, 7 = always
        host='127.0.0.1',
        port=3306,
        user='root',
        password='1234,5678a',
        database='orm_mysql_demo',
        charset='utf8',
        autocommit=True
    
    )
    mysql_pool
    # _*_ coding: gbk _*_
    # @Author: Wonder
    
    import pymysql
    from orm_control.mysql_pool import Pool
    
    
    class MySql():  # 数据库连接用单例模式
    
        def __new__(cls, *args, **kwargs):
            if not hasattr(cls, '_instance', ):
                setattr(cls, '_instance', object.__new__(cls))
    
            return cls._instance
    
        def __init__(self):
            self.mysql_client = Pool.connection()
    
            self.cursor = self.mysql_client.cursor(
                pymysql.cursors.DictCursor)
    
        def select(self, sql, args=None):
            self.cursor.execute(sql, args)
            res = self.cursor.fetchall()
            return res
    
        def execute(self, sql, args):
            try:
                self.cursor.execute(sql, args)
            except Exception as e:
                print(e)
    
        def close(self):
            self.cursor.close()
            self.mysql_client.close()
    
    #
    
    # if __name__ == '__main__':
    #     obj1 =MySql()
    #     obj2 =MySql()
    #     obj3 =MySql()
    #     print(id(obj1))
    #     print(id(obj2))
    #     print(id(obj3))
    mysql_pro
    # _*_ coding: gbk _*_
    # @Author: Wonder
    from orm_control.mysql_pro import MySql
    
    
    class Field:
        def __init__(self, name, field_type, is_primary, default):
            self.name = name
            self.field_type = field_type
            self.is_primary = is_primary
            self.default = default
    
    
    class StringField(Field):
        def __init__(self, name, field_type='varchar(255)', is_primary=False, default=None):
            super().__init__(name, field_type, is_primary, default)
    
    
    class IntegerField(Field):
        def __init__(self, name, field_type='int', is_primary=False, default=0):
            super().__init__(name, field_type, is_primary, default)
    
    
    class OrmCtrl(type):
        def __new__(cls, class_name, class_bases, class_dict):
            if class_name == 'Models':
                return type.__new__(cls, class_name, class_bases, class_dict)
    
            # 此时筛选出来的就是继承Field产生的类,需要控制他们类的创建过程
    
            primary_key = None
            # table_name = getattr(cls, 'table_name', class_name)  # 取User类中的table_name属性(如果传就用table_name)
            table_name = class_dict.get('table_name', class_name) # 看有没有创建并传一个叫table_name的字段信息
            mappings = {}  # 字典里存放User类的字段
    
            for k, v in class_dict.items():
                if isinstance(v, Field):  # 筛选出Field的创建的对象,即User等之类的表
    
                    mappings[k] = v  # 将合格的k、v转义到mappings中
    
                    if v.is_primary:  # 表示这个字段是主键   V是一个由Field生成的对象
                        if primary_key:
                            raise TypeError('只能有一个主键')
                        primary_key = v.name
    
            if not primary_key:
                raise TypeError('必须要有主键')
    
            for k in mappings:
                class_dict.pop(k)
    
            class_dict['table_name'] = table_name
            class_dict['primary_key'] = primary_key
            class_dict['mappings'] = mappings
    
            return type.__new__(cls, class_name, class_bases, class_dict)  # 都要交给元类type进行类的创建
    
    
    class Models(dict, metaclass=OrmCtrl):
        '''
        控制实际表类对象的生成,干涉其取值方式。因为继承了字典,所以通过该类生成的对象都是字典
        '''
    
        def __getattr__(self, item):
            return self.get(item)
    
        def __setattr__(self, key, value):
            self[key] = value
    
        @classmethod
        def select_data(cls, **kwargs):
            mysql_obj = MySql()
            if not kwargs:  # 说明想查cls这张表里面的所有值
                sql = f'select * from {cls.table_name}'
                res = mysql_obj.select(sql)
    
            else:
                # kwargs-->** kwargs     a=b --> {a:b}
                # 开始取字典中的key   dict1.keys()是一个对象
                key = list(kwargs.keys())[0]
                value = kwargs.get(key)
    
                sql = f'select * from {cls.table_name} where {key} = %s'
                res = mysql_obj.select(sql, value)
    
    
            # 此时获取的两种res 都是列表套字典
            return [cls(**i) for i in res]  # 此时将列表中的字典,转化成了对象,就有了相关的属性,比如name,field_type
    
        def insert_data(self):    # obj = User(name = 'ccc')   # 此功能仅实现一次插入一条记录
            sql_obj = MySql()
            list_k = []  # 添加传来的key
            list_value = []  # 添加传来的值
            list_tag = []
            for k, v in self.mappings.items():  # kv只能在items()中取值
                list_k.append(k)  # mappings的k都是字符串,因为是user的属性名
                list_tag.append('%s')
    
                list_value.append(self.get(k, v.default))
    
            # insert into t1 (id,name) values(1,ww),(2,xx)
            sql = f'insert into {self.table_name}  (%s) values (%s)' %(
                ','.join(list_k),
                ','.join(list_tag)
            )
            sql_obj.execute(sql, list_value)
    
    
    
    
        def update_data(self):    # 更新的时候,敏感数据是更新的值,要单独传
            sql_obj = MySql()
            update_list = []  # 将要准备更新的数据,以字符串的形式  存在这里面
            update_value = []
            pk = None
            pk_value = None
    
    
            for k, v in self.mappings.items():
                if not v.is_primary:
                    update_list.append(f'{k}=%s')
                    update_value.append(self.get(k, v.default))
    
    
    
                pk = self.primary_key
                pk_value = self.get(pk)  # 主键一定是有的
    
            sql = f'update {self.table_name} set %s where %s = %s ' %(
                ','.join(update_list),
                pk,
                pk_value
            )
            print('更新的语句', sql)
            sql_obj.execute(sql, update_value)
    orm
    # _*_ coding: gbk _*_
    # @Author: Wonder
    import socket
    import struct
    import json
    from user_data.session import user_info
    from concurrent.futures import ThreadPoolExecutor
    from interface import common_interface
    from interface import admin_interface
    from interface import user_interface
    from threading import Lock
    # mutex = Lock()
    
    func_dict = {
        'register': common_interface.register_interface,
        'login': common_interface.login_interface,
        'check_movie': admin_interface.check_movie_interface,
        'upload_movie': admin_interface.upload_movie_interface,
        'check_nodel_movie': common_interface.check_nodel_movie_interface,  # 未删除的所有电影
        'del_mv': admin_interface.del_mv_interface,
        'release_notice': admin_interface.relaese_notice_interface,
        'pay_member': user_interface.paymember_interface,
        'download_mv': user_interface.download_mv_interface,
        'check_record': user_interface.check_record_interface,
        'check_notice': user_interface.check_notice_interface
    
    }
    
    pool = ThreadPoolExecutor(5)
    
    
    def connect(ip, port):
        server = socket.socket()
        server.bind((ip, port))
        server.listen(5)
        print('server start.....')
        while True:
            conn, addr = server.accept()
            pool.submit(task, conn, addr)  # 并发
    
    
    def task(conn, addr):
        while True:
            try:
                recv_data = conn.recv(4)
    
                dic_size = struct.unpack('i', recv_data)[0]
                json_dic = conn.recv(dic_size).decode('utf-8')
                recv_dic = json.loads(json_dic)
                func_type = recv_dic.get('func_type')
                if func_type in func_dict:
                    # print(recv_dic,'收到的字典')
                    func_dict.get(func_type)(recv_dic, conn, addr)
            except Exception as e:
                # print(e)
                # mutex.acquire()
                user_info.pop(str(addr))  # {str(addr) : [session,  u_id ] }
                # mutex.release()
    
                break
        conn.close()
    server
    # _*_ coding: gbk _*_
    # @Author: Wonder
    
    user_info = {}
    # {(ip:port) : [session, u_id}
    session
    # _*_ coding: gbk _*_
    # @Author: Wonder
    import sys
    from conf import settings
    from tcp_server import server
    
    sys.path.append(settings.BASE_PATH)
    
    if __name__ == '__main__':
        server.connect(settings.IP, settings.PORT)
    start

    客户端Client
    # _*_ coding: gbk _*_
    # @Author: Wonder
    import os
    
    BASE_PATH = os.path.dirname(os.path.dirname(__file__))
    DOWNLOAD_PATH = os.path.join(BASE_PATH, 'download_movie')
    UPLOAD_PATH = os.path.join(BASE_PATH, 'upload_movie')
    
    IP = '127.0.0.1'
    PORT = 9527
    settings
    # _*_ coding: gbk _*_
    # @Author: Wonder
    from lib import common
    import os
    import time
    from conf.settings import UPLOAD_PATH
    
    current_user = {
        'cookies': None
    }
    
    
    # 注册
    def register(client):
        while True:
            username = input('>>>请输入用户名').strip()
            password = input('>>>请输入密码').strip()
            re_password = input('>>>请再次输入密码').strip()
            if not password == re_password:
                print('密码不一致')
                continue
            dic = {
                'func_type': 'register',
                'username': username,
                'password': password,
                'user_type': 1
            }
    
            back_dic = common.send_and_back(dic, client)
            if back_dic.get('flag'):
                print(back_dic.get('msg'))
                break
            else:
                print(back_dic.get('msg'))
    
                choice = input('>>>是否继续注册,q退出').strip()
                if choice == 'q':
                    break
                else:
                    continue
    
    
    # 登录
    def login(client):
        while True:
            username = input('>>>请输入用户名').strip()
            password = input('>>>请输入密码').strip()
            send_dic = {
                'func_type': 'login',
                'username': username,
                'password': password,
                'user_type': 1
    
    
            }
            back_dic = common.send_and_back(send_dic, client)
            print(back_dic, '客户端的')
            if back_dic.get('flag'):
                cookies = back_dic.get('session')
                current_user['cookies'] = cookies
                msg = back_dic.get('msg')
                print(msg)
                break
            else:
                print(back_dic.get('msg'))
    
                choice = input('>>>是否继续登录,q退出').strip()
                if choice == 'q':
                    break
                else:
                    continue
    
    
    # 上传电影
    def upload_mv(client):
        # 上传电影
        # 电影目录
        while True:
    
            movie_list = os.listdir(UPLOAD_PATH)
            if not movie_list:
                print('无可上传电影')
                break
            else:
                flag, msg = common.show_and_choice(movie_list)
                if not flag:
                    print(msg)
                    continue
                else:
                    movie_path = os.path.join(UPLOAD_PATH, msg)
    
                    movie_size = os.path.getsize(movie_path)
                    # 先判断电影在不在(先取所有的内容,后面优化定点取值)
                    movie_md5 = common.get_movie_md5(movie_path)
    
                    dic1 = {
                        'func_type': 'check_movie',
                        'movie_md5': movie_md5,
                        'cookies': current_user.get('cookies')
                    }
    
                    print('组织的字典', dic1)
    
                    back_dic = common.send_and_back(dic1, client)
                    print('收到的字典', back_dic)
                    if not back_dic.get('flag'):
                        print(back_dic.get('msg'))
                        break
                    else:
                        # 开始上传啦
                        choice = input('>>>选择是否收费,y收费,任意键免费').strip()
                        if choice == 'y':
                            is_free = 1
                        else:
                            is_free = 0
                        dic = {
                            'func_type': 'upload_movie',
                            'movie_name': msg,
                            'movie_size': movie_size,
                            'movie_md5': movie_md5,
                            'is_free': is_free,
                            'cookies': current_user.get('cookies')
                        }
                        back_dic = common.send_and_back(dic, client, path=movie_path)
                        print(back_dic.get('msg'))
                        break
    
    
    # 删除电影
    def delete_mv(client):
        # 获取电影列表
        while True:
            dic = {
                'func_type': 'check_nodel_movie',
                'cookies': current_user.get('cookies'),
                'select_type': 'all'
            }
            back_dic = common.send_and_back(dic, client)
            print('返回的报头', back_dic)
            if not back_dic.get('flag'):
                print(back_dic.get('msg'))
                break
            else:
                mv_list = back_dic.get('mv_list')
                print('可删除的列表', mv_list)
                flag, msg = common.show_and_choice(mv_list)
                if not flag:
                    print(msg)
                    break
                else:
                    del_mv_name = msg
    
                dic2 = {
                    'func_type': 'del_mv',
                    'cookies': current_user.get('cookies'),
                    'mv_name': del_mv_name
                }
                print(dic2)
                back_dic = common.send_and_back(dic2, client)
                print(back_dic.get('msg'))
                break
    
    
    # 发布公告
    def announce(client):
        title = input('>>>请输入公告标题').strip()
        content = input('>>请输入公告内容').strip()
        dic = {
            'func_type': 'release_notice',
            'title': title,
            'content': content,
            'cookies': current_user.get('cookies')
        }
        back_dict = common.send_and_back(dic, client)
        print(back_dict.get('msg'))
    
    
    
    
    def run(client):
        func_dict = {
            '1': register,
            '2': login,
            '3': upload_mv,
            '4': delete_mv,
            '5': announce,
        }
        while True:
            print('''
            ********管理员界面********
                    1 注册
                    2 登录
                    3 上传视频
                    4 删除视频
                    5 发布公告
    
                   任意键退出        
            ''')
            choice = input('>>>请选择功能').strip()
            if choice in func_dict:
                func_dict.get(choice)(client)
            else:
                print('告辞')
                break
    admin_view
    # _*_ coding: gbk _*_
    # @Author: Wonder
    from core import admin_view, user_view
    from tcp_client.client import connect
    
    
    def run():
        func_dict = {
            '1': admin_view,
            '2': user_view
        }
        while True:
            client = connect()
            print('''
            ********优酷系统********
                  1: 管理员
                  2: 普通用户
                  
                   任意键退出        
            ''')
            choice = input('>>>请选择功能').strip()
            if choice in func_dict:
                func_dict.get(choice).run(client)
            else:
                print('告辞')
                break
    
    if __name__ == '__main__':
        run()
    src
    # _*_ coding: gbk _*_
    # @Author: Wonder
    from lib import common
    import os
    import time
    from conf.settings import DOWNLOAD_PATH
    
    # 注册
    current_user = {}
    
    
    def register(client):
        while True:
            username = input('请输入用户名').strip()
            password = input('请输入密码').strip()
            re_password = input('请再次输入密码').strip()
            if not password == re_password:
                print('密码不一致')
                continue
            dic = {
                'func_type': 'register',
                'username': username,
                'password': password,
                'user_type': 0
            }
            back_dic = common.send_and_back(dic, client)
            if back_dic.get('flag'):
                print(back_dic.get('msg'))
                break
            else:
                print(back_dic.get('msg'))
    
    
    def login(client):
        while True:
            username = input('>>>请输入用户名').strip()
            password = input('>>>请输入密码').strip()
            dic = {
                'func_type': 'login',
                'username': username,
                'password': password,
                'user_type': 0
            }
            back_dic = common.send_and_back(dic, client)
            if back_dic.get('flag'):
                current_user['cookies'] = back_dic.get('session')  # 登陆成功之后,server会将session返回。
                current_user['u_id'] = back_dic.get('u_id')
                current_user['is_vip'] = back_dic.get('is_vip')
                print(back_dic.get('msg'))
                break
            else:
                print(back_dic.get('msg'))
    
    
    # 充会员
    def pay_member(client):
        # 此处是永久会员,修改is_vip
        pay = input('请确认开通vip,按y确认').strip()
        if not pay == 'y':
            print('再见,未开通')
        else:
            dic = {
                'func_type': 'pay_member',
                'is_vip': 1,
                'cookies': current_user.get('cookies')
            }
            back_dic = common.send_and_back(dic, client)
            print(back_dic.get('msg'))
    
    
    # 查看电影目录
    def check_movie(client):
        # 查看所有未删除的电影
        dic = {
            'func_type': 'check_nodel_movie',
            'cookies': current_user.get('cookies'),
            'select_type': 'all'
        }
        back_dic = common.send_and_back(dic, client)
        if back_dic.get('flag'):
            print(back_dic.get('mv_list'))
        else:
            print(back_dic.get('msg'))
    
    
    # 下载免费电影
    def download_free_mv(client):
        # 先查免费电影的列表以供选择
        while True:
            dic1 = {
                'func_type': 'check_nodel_movie',
                'cookies': current_user.get('cookies'),
                'select_type': 'free'
            }
    
            back_dic = common.send_and_back(dic1, client)
            if not back_dic.get('flag'):
                print(back_dic.get('msg'))
                break
            # 封装一个方法,用于来选择。
            free_mv_list = back_dic.get('mv_list')
            flag, msg = common.show_and_choice(free_mv_list)
            if not flag:  # 输入了无效指令
                continue
            else:
                # 接下来发送下载的请求
                mv_name = msg
                dic2 = {
                    'func_type': 'download_mv',
                    'cookies': current_user.get('cookies'),
                    'mv_name': mv_name
                }
    
                back_dic = common.send_and_back(dic2, client)  # 给出文件的大小
                mv_size = back_dic.get('mv_size')
                mv_file = os.path.join(DOWNLOAD_PATH, mv_name)
                temp_size = 0
                with open(mv_file, 'wb') as f:
                    while temp_size < mv_size:
                        data = client.recv(1024)
                        f.write(data)
                        temp_size += len(data)
                print('下载完毕......')
                break
    
    
    # 下载付费电影(要么充值会员,要么付费观影)
    def download_paid_mv(client):
        while True:
            # 付费电影,对普通用户有限制  先获取当前用户
            if not current_user.get('is_vip'):
                print('当前用户不可以下载付费电影')
                pay_choice = input('press A去充会员,press B付费下载,任意键退出')
                if pay_choice == 'A':
                    pay_member(client)
                    login(client)
                    break
                elif pay_choice == 'B':
                    money = input('>>>充值的钱').strip()
                    print('广告时间...5秒')
                    time.sleep(5)
                else:
                    break
    
                # 此处可以扩展付费模块,钱包功能。
    
            dic = {
                'func_type': 'check_nodel_movie',
                'select_type': 'pay',
                'cookies': current_user.get('cookies')
            }
            back_dic = common.send_and_back(dic, client)
            if not back_dic.get('flag'):
                print(back_dic.get('msg'))
                break
            else:
                pay_mv_list = back_dic.get('mv_list')
    
                flag, msg = common.show_and_choice(pay_mv_list)
                if not flag:
                    print(msg)
                    break
                else:
                    movie_name = msg
                    dic2 = {
                        'func_type': 'download_mv',
                        'cookies': current_user.get('cookies'),
                        'mv_name': movie_name
                    }
                    back_dic = common.send_and_back(dic2, client)
                    mv_size = back_dic.get('mv_size')
                    temp_size = 0
                    file_path = os.path.join(DOWNLOAD_PATH, movie_name)
                    with open(file_path, 'wb') as f:
                        while temp_size < mv_size:
                            data = client.recv(1024)
                            f.write(data)
                            temp_size += len(data)
                    print('下完了')  # 这句话是否要从服务端传过来
                    break
    
    
    # 查看下载记录
    def check_record(client):
        dic = {
            'func_type': 'check_record',
            'cookies': current_user.get('cookies'),
        }
        back_dic = common.send_and_back(dic, client)
        if not back_dic.get('flag'):
            print(back_dic.get('msg'))
        else:
            print(back_dic.get('mv_list'))
    
    
    # 查看公告
    def check_notice(client):
        dic = {
            'func_type': 'check_notice',
            'cookies': current_user.get('cookies')
        }
        back_dic = common.send_and_back(dic, client)
        if not back_dic.get('flag'):
            print(back_dic.get('msg'))
        else:
            print(back_dic.get('notice_list'))
    
    
    def run(client):
        func_dic = {
            '1': register,
            '2': login,
            '3': pay_member,
            '4': check_movie,
            '5': download_free_mv,
            '6': download_paid_mv,
            '7': check_record,
            '8': check_notice,
        }
    
        while True:
            print('''
              ********普通用户界面********
                        1 注册
                        2 登录
                        3 冲会员
                        4 查看视频
                        5 下载免费视频
                        6 下载收费视频
                        7 查看下载记录
                        8 查看公告
                        q.退出   
                ''')
            choice = input('>>>请选择功能对应的编号').strip()
            if choice == 'q':
                print('再见')
                break
            if choice in func_dic:
                func_dic.get(choice)(client)
            else:
                print('无效指令')
    user_view
    # _*_ coding: gbk _*_
    # @Author: Wonder
    
    import json
    import struct
    import os
    from hashlib import md5
    from tcp_client.client import connect
    
    
    # 发数据
    def send_and_back(dic, client, path=None):  # 一次请求一次响应
        send_dic = json.dumps(dic).encode('utf-8')
        send_head = struct.pack('i', len(send_dic))
        client.send(send_head)
        client.send(send_dic)
        if path:
            with open(path, 'rb') as f:
                for line in f:
                    client.send(line)
    
        head2 = client.recv(4)
        back_size = struct.unpack('i', head2)[0]
        back_dic = json.loads(client.recv(back_size).decode('utf-8'))
        return back_dic
    
    
    # 查看列表数据并进行选择
    def show_and_choice(li):
        for index, content in enumerate(li):
            print(index, content)
        choice = input('请输入选择的电影序号').strip()
        if not choice.isdigit():
            return False, '无效指令'
        choice = int(choice)
        if choice not in range(len(li)):
            return False, '无效指令'
        return True, li[choice]
    
    
    def get_movie_md5(path):
        movie_size = os.path.getsize(path)
        list_md5 = [0, movie_size // 2, movie_size - 10]
        with open(path, 'rb') as f:
            for index in list_md5:
                md5_obj = md5()
                f.seek(index)
                part = f.read(10)
                md5_obj.update(part)
            return md5_obj.hexdigest()
    common
    # _*_ coding: gbk _*_
    # @Author: Wonder
    
    import socket
    
    from conf.settings import IP, PORT
    def connect():
        client = socket.socket()
        client.connect((IP, PORT))
        return client
    client
    # _*_ coding: gbk _*_
    # @Author: Wonder
    
    import sys
    from conf import settings
    from core import src
    sys.path.append(settings.BASE_PATH)
    
    
    if __name__ == '__main__':
        src.run()
    start














  • 相关阅读:
    机器学习系列丛书
    Growing Pains for Deep Learning
    What qualities characterize a great PhD student
    PHP中$_SERVER的具体參数与说明
    JavaScript总结(二) 系统分析
    .net中将DataTable导出到word、Excel、txt、htm的方法
    World Wind Java开发之十五——载入三维模型
    插入排序:二路插入
    使用HashMap对象传递url參数有用工具类
    mini2440裸机试炼之——DMA直接存取 实现Uart(串口)通信
  • 原文地址:https://www.cnblogs.com/csic716/p/12093027.html
Copyright © 2020-2023  润新知