仿优酷客户端

项目目录结构

client目录

    tcpClient.py---》客户端连接

conf目录

    setting.py:存放配置信息

core目录

    admin.py:管理员视图相关功能函数

    src.py    :主视图

    user.py :用户视图相关功能函数

download_movie目录

    存放下载完的电影

upload_movie目录

    存放要上传的电影

lib目录

    common.py:存放公共方法

start.py:启动文件

各文件功能代码

client.py

import socket
from conf import setting


def client_conn():
    # 先建立连接
    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    client.connect(setting.server_address)
    return client
View Code

 

setting.py

import os

BASE_DIR = os.path.dirname(os.path.dirname(__file__))
BASE_MOVIE_UP = os.path.join(BASE_DIR, 'upload_movie')
BASE_MOVIE_DOWN = os.path.join(BASE_DIR, 'download_movie')

server_address = ('127.0.0.1', 8087)
配置信息

 

admin.py

from client import tcpClient
from lib import common
from conf import setting
import os

admin_data = {
    'session': None,
}

send_dic = {'type': None, 'user_type': 'admin', 'session': None}


def admin_register(client):
    print('管理员注册')
    while True:
        name = input('请输入手机号>>:').strip()
        if name == 'q': break
        password = input('请输入密码>>').strip()
        conf_password = input('请确认密码>>:').strip()
        if password == conf_password:
            send_dic = {'type': 'register', 'user_type': 'admin', 'name': name, 'password': common.make_md5(password)}
            back_dic = common.send_data(client, send_dic, None)
            if back_dic['flag']:
                print(back_dic['msg'])
                break
            else:
                print(back_dic['msg'])

        else:
            print('两次密码不一致')


def admin_login(client):
    print('管理员登录')
    while True:
        name = input('用户名>>').strip()
        if name == 'q': break
        password = input('密码>>').strip()
        send_dic = {'type': 'login', 'user_type': 'admin', 'name': name, 'password': common.make_md5(password)}

        back_dic = common.send_data(client, send_dic, None)
        if back_dic['flag']:
            admin_data['session'] = back_dic['session']
            print(back_dic['msg'])
            break
        else:
            print(back_dic['msg'])


def upload_movie(client):
    if not admin_data['session']:
        print('请先登录')
        return
    print('上传视频')
    while True:
        up_list = common.get_allfile_by_path(setting.BASE_MOVIE_UP)
        if not up_list:
            print('暂无能上传的影片')
            break
        for i, m in enumerate(up_list):
            print('%s : %s' % (i, m))
        choose = input('请选择要上传的影片').strip()
        if choose == 'q': break
        if choose.isdigit():
            choose = int(choose)
            # 先把md5值传上去校验一下文件是否存在,在决定要不要上传
            if choose >=len(up_list):
                print('请输入范围内的数字')
                continue
            movie_path = os.path.join(setting.BASE_MOVIE_UP, up_list[choose])
            file_md5 = common.get_bigfile_md5(movie_path)
            send_dic={'type':'check_movie','session':admin_data['session'],'file_md5':file_md5}
            back_dic=common.send_data(client,send_dic,None)
            if back_dic['flag']:
                is_free = input('是否免费(y/n)>>:').strip()
                if is_free == 'y':
                    is_free = 1
                else:
                    is_free = 0
                fsize = os.path.getsize(movie_path)
                send_dic = {'type': 'upload', 'user_type': 'admin',
                            'session': admin_data['session'],
                            'file_name': up_list[choose], 'file_size': fsize, 'file_md5':common.get_bigfile_md5(movie_path),'is_free': is_free}
                back_dic = common.send_data(client, send_dic, movie_path)
                if back_dic['flag']:
                    print(back_dic['msg'])
                    break
                else:
                    print(back_dic['msg'])
            else:
                print(back_dic['msg'])
        else:
            print('请输入数字')


def delete_movie(client):
    '''
    1 先拿到视频列表,打印
    2 根据视频前数字,选择要删除的视频
    3 删除成功/失败,打印
    '''
    if not admin_data['session']:
        print('请先登录')
        return
    print('删除视频')
    while True:
        send_dic['type'] = 'get_movie_list'
        send_dic['session'] = admin_data['session']
        send_dic['movie_type'] = 'all'
        back_dic = common.send_data(client, send_dic, None)
        if back_dic['flag']:
            for i, mo in enumerate(back_dic['movie_list']):
                print('%s : %s--%s' % (i, mo[0], mo[1]))
            choose = input('请输入要删除的电影(数字):').strip()
            if choose == 'q': break
            if choose.isdigit():
                choose = int(choose)
                if choose >= len(back_dic['movie_list']):
                    print('请输入范围内的数字')
                    continue
                send_dic['type'] = 'delete_movie'
                # 回忆后台返回的数据是什么样的
                send_dic['movie_id'] = back_dic['movie_list'][choose][2]
                back_dic = common.send_data(client, send_dic, None)
                if back_dic['flag']:
                    print(back_dic['msg'])
                    break
                else:
                    print(back_dic['msg'])

            else:
                print('请输入数字')

        else:
            print(back_dic['msg'])
            break


def release_notice(client):
    if not admin_data['session']:
        print('请先登录')
        return
    print('发布公告')
    while True:
        notice_name = input('请输入公告标题:').strip()
        notice_content = input('请输入公告内容:').strip()
        if notice_name == 'q': break
        send_dic['type'] = 'release_notice'
        send_dic['session'] = admin_data['session']
        send_dic['notice_name'] = notice_name
        send_dic['notice_content'] = notice_content
        back_dic = common.send_data(client, send_dic, None)
        if back_dic['flag']:
            print(back_dic['msg'])
            break
        else:
            print(back_dic['msg'])


fun_dic = {
    '1': admin_register,
    '2': admin_login,
    '3': upload_movie,
    '4': delete_movie,
    '5': release_notice,
}


def admin_view():
    client = tcpClient.client_conn()
    while True:
        print('''
        1 注册
        2 登录
        3 上传视频
        4 删除视频
        5 发布公告
        ''')

        choose = input('please choose>>:').strip()
        if 'q' == choose: break
        if choose not in fun_dic: continue
        fun_dic[choose](client)
    client.close()
管理员视图

 

src.py

from core import admin, user

fun_dic = {
    '1': admin.admin_view,
    '2': user.user_view
}


def run():
    while True:
        print('''
        1 管理员视图
        2 用户视图
        ''')
        choose = input('please choose>>:').strip()
        if 'q' == choose: break
        if choose not in fun_dic: continue
        fun_dic[choose]()
主视图

 

user.py

from client import tcpClient
from lib import common
from conf import setting
import os
import time

user_data = {
    'session': None,
    'is_vip': None
}

send_dic = {'type': None, 'user_type': 'user', 'session': None}


def user_register(client):
    print('用户注册')
    while True:
        name = input('请输入手机号>>:').strip()
        password = input('请输入密码>>').strip()
        conf_password = input('请确认密码>>:').strip()
        if password == conf_password:
            send_dic = {'type': 'register', 'user_type': 'user', 'name': name, 'password': common.make_md5(password)}
            back_dic = common.send_data(client, send_dic, None)
            if back_dic['flag']:
                print(back_dic['msg'])
                break
            else:
                print(back_dic['msg'])

        else:
            print('两次密码不一致')


def user_login(client):
    print('用户登录')
    while True:
        name = input('用户名>>').strip()
        if name == 'q': break
        password = input('密码>>').strip()
        send_dic = {'type': 'login', 'user_type': 'user', 'name': name, 'password': common.make_md5(password)}

        back_dic = common.send_data(client, send_dic, None)
        if back_dic['flag']:
            user_data['session'] = back_dic['session']
            user_data['is_vip'] = back_dic['is_vip']
            print(back_dic['msg'])
            print(back_dic['last_notice'])
            break
        else:
            print(back_dic['msg'])


def buy_member(client):
    print('购买会员')
    if not user_data['session']:
        print('请先登录')
        return
    if user_data['is_vip'] == 1:
        print('您已经是会员了')
        return
    while True:
        buy = input('是否购买会员(y/n)q 退出').strip()
        if 'y' == buy:
            send_dic['type'] = 'buy_member'
            send_dic['session'] = user_data['session']
            back_dic = common.send_data(client, send_dic, None)
            if back_dic['flag']:
                user_data['is_vip'] = 1
                print(back_dic['msg'])
                break
            else:
                print(back_dic['msg'])

        elif 'q' == buy:
            break
        else:
            print('您没有购买')


def get_movie_list(client):
    if not user_data['session']:
        print('请先登录')
        return
    print('查看视频列表')
    send_dic['type'] = 'get_movie_list'
    send_dic['movie_type'] = 'all'
    send_dic['session'] = user_data['session']
    back_dic = common.send_data(client, send_dic, None)
    if back_dic['flag']:
        for i, mo in enumerate(back_dic['movie_list']):
            print('%s : %s-->%s' % (i, mo[0], mo[1]))
    else:
        print(back_dic['msg'])


def down_free_movie(client):
    if not user_data['session']:
        print('请先登录')
        return
    print('下载免费视频')
    '''
    先查询免费视频,打印出来,
    用户选择后,通过电影id去后台下载
    '''
    send_dic['type'] = 'get_movie_list'
    send_dic['movie_type'] = 'free'
    send_dic['session'] = user_data['session']
    back_dic = common.send_data(client, send_dic, None)
    if back_dic['flag']:
        for i, mo in enumerate(back_dic['movie_list']):
            print('%s : %s-->%s' % (i, mo[0], mo[1]))
        choose = input('请输入要下载的电影(数字):').strip()
        if choose.isdigit():
            choose = int(choose)
            # 回忆后台返回的数据是什么样的
            send_dic['type'] = 'download_movie'
            send_dic['session'] = user_data['session']
            send_dic['movie_id'] = back_dic['movie_list'][choose][2]
            send_dic['movie_type'] = 'free'
            back_dic = common.send_data(client, send_dic, None)
            if back_dic['flag']:
                if back_dic['wait_time'] > 0:
                    print('请等待 %s 秒' % back_dic['wait_time'])
                    time.sleep(back_dic['wait_time'])
                recv_size = 0
                print('----->', back_dic['filename'])
                path = os.path.join(setting.BASE_MOVIE_DOWN, back_dic['filename'])
                with open(path, 'wb') as f:
                    while recv_size < back_dic['filesize']:
                        recv_data = client.recv(1024)
                        f.write(recv_data)
                        recv_size += len(recv_data)
                        print('recvsize:%s filesize:%s' % (recv_size, back_dic['filesize']))
                print('%s :下载成功' % back_dic['filename'])
            else:
                print(back_dic['msg'])
    else:
        print(back_dic['msg'])


def down_charge_movie(client):
    if not user_data['session']:
        print('请先登录')
        return
    print('下载收费视频')
    if user_data['is_vip']:
        charge = input('您是会员,收费5元(y 确认)').strip()
    else:
        charge = input('您不是会员,收费10元(y 确认)').strip()
    if not charge == 'y':  # 不是y,相当于没付钱,直接返回
        return
    send_dic['type'] = 'get_movie_list'
    send_dic['movie_type'] = 'charge'
    send_dic['session'] = user_data['session']
    back_dic = common.send_data(client, send_dic, None)
    if back_dic['flag']:
        for i, mo in enumerate(back_dic['movie_list']):
            print('%s : %s-->%s' % (i, mo[0], mo[1]))
        choose = input('请输入要下载的电影(数字):').strip()
        if choose.isdigit():
            choose = int(choose)
            # 回忆后台返回的数据是什么样的
            send_dic['type'] = 'download_movie'
            send_dic['session'] = user_data['session']
            send_dic['movie_id'] = back_dic['movie_list'][choose][2]
            send_dic['movie_type'] = 'charge'
            back_dic = common.send_data(client, send_dic, None)
            if back_dic['flag']:
                recv_size = 0
                print('----->', back_dic['filename'])
                path = os.path.join(setting.BASE_MOVIE_DOWN, back_dic['filename'])
                with open(path, 'wb') as f:
                    while recv_size < back_dic['filesize']:
                        recv_data = client.recv(1024)
                        f.write(recv_data)
                        recv_size += len(recv_data)
                        print('recvsize:%s filesize:%s' % (recv_size, back_dic['filesize']))
                print('%s :下载成功' % back_dic['filename'])
            else:
                print(back_dic['msg'])
    else:
        print(back_dic['msg'])


def check_download_record(client):
    if not user_data['session']:
        print('请先登录')
        return
    print('查看观影记录')
    send_dic['type'] = 'check_download_record'
    send_dic['session'] = user_data['session']
    back_dic = common.send_data(client, send_dic, None)
    if back_dic['flag']:
        for re in back_dic['download_list']:
            print(re)
    else:
        print(back_dic['msg'])


def check_notice(client):
    if not user_data['session']:
        print('请先登录')
        return
    print('查看公告')
    send_dic['type'] = 'check_notice'
    send_dic['session'] = user_data['session']
    back_dic = common.send_data(client, send_dic, None)
    if back_dic['flag']:
        for value in back_dic['notice_list']:
            print(value)
    else:
        print(back_dic['msg'])


fun_dic = {
    '1': user_register,
    '2': user_login,
    '3': buy_member,
    '4': get_movie_list,
    '5': down_free_movie,
    '6': down_charge_movie,
    '7': check_download_record,
    '8': check_notice
}


def user_view():
    client = tcpClient.client_conn()
    while True:
        print('''
        1 注册
        2 登录
        3 冲会员
        4 查看视频
        5 下载免费视频
        6 下载收费视频
        7 查看观影记录
        8 查看公告
        ''')

        choose = input('please choose>>:').strip()
        if 'q' == choose: break
        if choose not in fun_dic: continue
        fun_dic[choose](client)
    client.close()
用户视图

 

common.py

import struct
import json
import os
import hashlib


def send_data(client, send_dic, file):
    # 发送部分
    head_json_bytes = json.dumps(send_dic).encode('utf-8')  # 先把报头转为bytes格式
    client.send(struct.pack('i', len(head_json_bytes)))  # 先发报头的长度
    client.send(head_json_bytes)  # 再发送报头
    if file:  # 如果存在文件,再把文件打开一行一行发送
        with open(file, 'rb') as f:
            for line in f:
                client.send(line)
    # 接收部分
    back_len_bytes = client.recv(4)  # 先收报头4个bytes,得到报头长度的字节格式
    back_head_len = struct.unpack('i', back_len_bytes)[0]  # 提取报头的长度
    head_bytes = client.recv(back_head_len)  # 按照报头长度back_head_len,收取报头的bytes格式
    header = json.loads(head_bytes.decode('utf-8'))  # 把bytes格式的报头,转换为json格式

    return header


def get_allfile_by_path(path):
    file_list = os.listdir(path)
    return file_list


def make_md5(password):
    md = hashlib.md5()
    md.update(password.encode('utf-8'))
    return md.hexdigest()


def get_bigfile_md5(file_path):
    if os.path.exists(file_path):
        md = hashlib.md5()
        filesize = os.path.getsize(file_path)
        file_list = [0, filesize // 3, (filesize // 3) * 2, filesize - 10]
        with open(file_path, 'rb') as f:
            for line in file_list:
                f.seek(line)
                md.update(f.read(10))
        return md.hexdigest()
公共方法

 

start.py

import os, sys

path = os.path.dirname(__file__)
sys.path.append(path)
from core import src

if __name__ == '__main__':
    src.run()
启动文件

 

 

 

    

 

posted @ 2018-05-14 20:50  刘清政  阅读(592)  评论(0编辑  收藏  举报