python 系统管理员_python-优酷系统管理员视图粗糙版(无详细注释)

Tank-YouKu(仅管理员功能粗糙版)

优酷系统管理员视图功能

注册

登录

上传视频

删除视频

发布公告

前期准备

先创建好数据库以及各数据表

安装 pymysql 模块、安装 DBUtils 模块

配置好服务端的 db_pool 中的数据库信息

创库创表语句

手动创建数据库 youku_demo, 需配置数据库编码 utf8 (安装时配置好了命令行中就不用管)

创建数据库:create database youku_demo;

选择该数据库:use youku_demo,然后执行下面的一堆sql代码,或者手动导入

创表代码及测试数据

测试用户:tank 密码: 123

/*

Navicat MySQL Data Transfer

Source Server : localhost-E

Source Server Type : MySQL

Source Server Version : 50645

Source Host : localhost:3306

Source Schema : youku_demo

Target Server Type : MySQL

Target Server Version : 50645

File Encoding : 65001

Date: 28/08/2019 21:22:47

*/

SET NAMES utf8mb4;

SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------

-- Table structure for download_record

-- ----------------------------

DROP TABLE IF EXISTS `download_record`;

CREATE TABLE `download_record` (

`id` int(11) NOT NULL AUTO_INCREMENT,

`user_id` int(11) NULL DEFAULT NULL,

`movie_id` int(11) NULL DEFAULT NULL,

`download_time` datetime(0) NULL DEFAULT NULL,

PRIMARY KEY (`id`) USING BTREE

) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;

-- ----------------------------

-- Table structure for movie

-- ----------------------------

DROP TABLE IF EXISTS `movie`;

CREATE TABLE `movie` (

`id` int(11) NOT NULL AUTO_INCREMENT,

`name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,

`path` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,

`is_free` int(11) NULL DEFAULT NULL,

`file_md5` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,

`user_id` int(11) NULL DEFAULT NULL,

`is_delete` int(11) NULL DEFAULT NULL,

`upload_time` datetime(0) NULL DEFAULT NULL,

PRIMARY KEY (`id`) USING BTREE

) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;

-- ----------------------------

-- Table structure for notice

-- ----------------------------

DROP TABLE IF EXISTS `notice`;

CREATE TABLE `notice` (

`id` int(11) NOT NULL AUTO_INCREMENT,

`title` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,

`content` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,

`user_id` int(11) NULL DEFAULT NULL,

`create_time` datetime(0) NULL DEFAULT NULL,

PRIMARY KEY (`id`) USING BTREE

) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;

-- ----------------------------

-- Records of notice

-- ----------------------------

INSERT INTO `notice` VALUES (1, 'test1', '测试发布公告是否正常', 1, '2019-08-28 21:18:38');

-- ----------------------------

-- Table structure for user

-- ----------------------------

DROP TABLE IF EXISTS `user`;

CREATE TABLE `user` (

`id` int(11) NOT NULL AUTO_INCREMENT,

`name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,

`pwd` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,

`is_vip` int(11) NULL DEFAULT NULL,

`is_locked` int(11) NULL DEFAULT NULL,

`user_type` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,

`register_time` datetime(0) NULL DEFAULT NULL,

PRIMARY KEY (`id`) USING BTREE

) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;

-- ----------------------------

-- Records of user

-- ----------------------------

INSERT INTO `user` VALUES (1, 'tank', 'e23087636dfcd7addf39e32f89e25d44', 0, 0, 'admin', '2019-08-28 21:18:10');

SET FOREIGN_KEY_CHECKS = 1;

数据库结构

安装pymysql模块

安装DBUtils模块

在命令行输入pip3 install DBUtils 开始安装

配置 db_pool

根据自己电脑的mysql 情况配置

项目架构与数据流向

目录结构

server目录结构

client目录结构

服务端代码

start.py

import os

import sys

from tcp_server.socket_server import SocketServer

sys.path.append(os.path.dirname(__file__))

if __name__ == '__main__':

server = SocketServer()

server.run()

tcp_server/socket_server.py

import socket

import struct

import json

from interface import common_interface

from interface import admin_interface

from concurrent.futures import ThreadPoolExecutor

from threading import Lock

from lib import lock_file

lock = Lock()

lock_file.mutex = lock

func_dic = {

'register': common_interface.register_interface,

'login': common_interface.login_interface,

'check_movie': admin_interface.check_movie_interface,

'upload_movie': admin_interface.upload_movie_interface,

'get_movie_list': common_interface.get_movie_list_interface,

'delete_movie': admin_interface.delete_movie_interface,

'put_notice': admin_interface.put_notice_interface

}

class SocketServer:

def __init__(self):

self.server = socket.socket()

self.server.bind(('127.0.0.1', 9527))

self.server.listen(5)

self.pool = ThreadPoolExecutor(50)

def run(self):

print('启动服务端...')

while True:

conn, addr = self.server.accept()

self.pool.submit(self.working, conn, addr)

# 任务分发

def dispatcher(self, client_back_dic, conn):

# # 判断功能的类型

# if client_back_dic.get('type') == 'register':

# common_interface.register_interface(client_back_dic, conn)

#

# elif client_back_dic.get('type') == 'login':

# common_interface.login_interface(client_back_dic, conn)

_type = client_back_dic.get('type')

if _type in func_dic: # register

func_dic.get(_type)(client_back_dic, conn)

# 用于执行客户端连接任务

def working(self, conn, addr):

while True:

try:

# 每一个客户端访问服务端都会经过此处

# 此处用于接收客户端传入的数据

headers = conn.recv(4)

data_len = struct.unpack('i', headers)[0]

data_bytes = conn.recv(data_len)

client_back_dic = json.loads(data_bytes.decode('utf-8'))

client_back_dic['addr'] = str(addr)

self.dispatcher(client_back_dic, conn)

except Exception as e:

print(e)

conn.close()

break

interface/common_interface.py

from db import models

from lib import common, lock_file

from db import user_data

def register_interface(client_back_dic, conn):

# 写业务逻辑

# 1.判断用户名是否存在

username = client_back_dic.get('username')

# 通过用户名当作条件查询

user_obj_list = models.User.select(name=username)

# 若存在,给客户端返回数据, 告诉用户,用户已存在!

if user_obj_list:

send_dic = {'flag': False, 'msg': '用户已存在!'}

# 若不存在,保存数据到MySQL数据库中, 返回注册成功给客户端

else:

password = client_back_dic.get('password')

user_obj = models.User(

name=username,

# pwd, is_vip, is_locked, user_type, register_time

pwd=common.get_md5_pwd(password),

is_vip=0, # 0表示不是VIP, 1表示VIP

is_locked=0, # 0表示不锁定, 1表示锁定

user_type=client_back_dic.get('user_type'),

register_time=common.get_time())

user_obj.save()

send_dic = {'flag': True, 'msg': '注册成功'}

common.send_data(send_dic, conn)

def login_interface(client_back_dic, conn):

username = client_back_dic.get('username')

user_list = models.User.select(name=username)

if not user_list:

send_dic = {'flag': False, 'msg': '用户不存在'}

else:

user_obj = user_list[0]

password = client_back_dic.get('password')

# 1.判断客户端传入的密码与数据库中的密码是否相等

if user_obj.pwd == common.get_md5_pwd(password):

# 产生一个随机字符串,作为session值

session = common.get_random_code()

addr = client_back_dic.get('addr')

# 保存session值到服务端,session + user_id一同保存到服务端本地

# 使用锁写入数据

lock_file.mutex.acquire()

user_data.user_online[addr] = [session, user_obj.id]

lock_file.mutex.release()

send_dic = {'flag': True, 'msg': '登录成功!', 'session': session}

else:

send_dic = {'flag': False, 'msg': '密码错误!'}

common.send_data(send_dic, conn)

# 获取电影接口

@common.login_auth

def get_movie_list_interface(client_back_dic, conn):

# 获取所有电影对象

movie_obj_list = models.Movie.select()

back_movie_list = []

if movie_obj_list:

# 过滤已删除的电影

for movie_obj in movie_obj_list:

# 没有删除则返回

if not movie_obj.is_delete:

back_movie_list.append(

# [电影名称、是否免费、电影ID]

[movie_obj.name, '免费' if movie_obj.is_free else "收费", movie_obj.id]

)

if back_movie_list:

send_dic = {'flag': True, 'back_movie_list': back_movie_list}

else:

send_dic = {'flag': False, 'msg': '没有可删除的电影!'}

else:

send_dic = {'flag': False, 'msg': '没有电影!'}

common.send_data(send_dic, conn)

db/models.py

from orm.orm import Models, StringField, IntegerField

# 用户表

class User(Models):

# 表名

table_name = 'user'

# 字段

id = IntegerField(name='id', primary_key=True)

name = StringField(name='name')

# pwd, is_vip, is_locked, user_type, register_time

pwd = StringField(name='pwd')

is_vip = IntegerField(name='is_vip')

is_locked = IntegerField(name='is_locked')

user_type = StringField(name='user_type')

register_time = StringField(name='register_time')

# 电影表

class Movie(Models):

# 表名

table_name = 'movie'

# 字段

id = IntegerField(name='id', primary_key=True)

name = StringField(name='name')

# path, is_free, file_md5, user_id, is_delete, upload_time

path = StringField(name='path')

is_free = IntegerField(name='is_free') # 1 0

file_md5 = StringField(name='file_md5')

user_id = IntegerField(name='user_id')

is_delete = IntegerField(name='is_delete')

upload_time = StringField(name='upload_time')

# 公告表

class Notice(Models):

table_name = 'notice'

# 字段

id = IntegerField(name='id', primary_key=True)

title = StringField(name='title')

content = StringField(name='content')

user_id = IntegerField(name='user_id')

create_time = StringField(name='create_time')

# 下载记录表

class DownloadRecord(Models):

table_name = 'download_record'

# 字段

id = IntegerField(name='id', primary_key=True)

user_id = IntegerField(name='user_id')

movie_id = IntegerField(name='movie_id')

download_time = StringField(name='download_time')

orm/orm.py

'''

定义字段类

'''

from orm.mysql_control import Mysql

class Field:

def __init__(self, name, column_type, primary_key, default):

self.name = name

self.column_type = column_type

self.primary_key = primary_key

self.default = default

# varchar

class StringField(Field):

def __init__(self, name, column_type='varchar(255)', primary_key=False, default=None):

super().__init__(name, column_type, primary_key, default)

# int

class IntegerField(Field):

def __init__(self, name, column_type='int', primary_key=False, default=0):

super().__init__(name, column_type, primary_key, default)

# 元类控制表模型类的创建

class OrmMetaClass(type):

# 类名, 类的基类, 类的名称空间

def __new__(cls, class_name, class_bases, class_attr):

# print(class_name, class_bases, class_attr)

# 1.过滤Models类

if class_name == 'Models':

return type.__new__(cls, class_name, class_bases, class_attr)

# 2.控制模型表中: 表名, 主键, 表的字段

# 如果模型表类中没有定义table_name,把类名当做表名

# 获取表名

table_name = class_attr.get('table_name', class_name) # user_info, User

# 3.判断是否只有一个主键

primary_key = None

# 用来存放所有的表字段, 存不是目的,目的是为了取值方便

mappings = {}

'''

__main__: xxxx

'id': <__main__.integerfield object at>,

'name': <__main__.stringfield object at>}

'''

for key, value in class_attr.items():

# 判断value是否是字段类的对象

if isinstance(value, Field):

# 把所有字段都添加到mappings中

mappings[key] = value

if value.primary_key:

if primary_key:

raise TypeError('主键只能有一个')

# 获取主键

primary_key = value.name

# 删除class_attr中与mappings重复的属性, 节省资源

for key in mappings.keys():

class_attr.pop(key)

# 判断是否有主键

if not primary_key:

raise TypeError('必须要有一个主键')

class_attr['table_name'] = table_name

class_attr['primary_key'] = primary_key

class_attr['mappings'] = mappings

'''

'table_name': table_name

'primary_key': primary_key

'mappings': {'id': <__main__.integerfield object at>,

'name': <__main__.stringfield object at>}

}

'''

return type.__new__(cls, class_name, class_bases, class_attr)

# 继承字典类,

class Models(dict, metaclass=OrmMetaClass):

def __init__(self, **kwargs):

# print(kwargs) # 接收关键字参数

super().__init__(**kwargs)

# 在对象.属性没有的时候触发

def __getattr__(self, item):

# print(item)

return self.get(item, '没有这个key')

# 在对象.属性 = 属性值 时触发

def __setattr__(self, key, value):

# 字典赋值操作

self[key] = value

# 查

@classmethod

def select(cls, **kwargs):

# 获取数据库链接对象

ms = Mysql()

# 若没有kwargs代表没有条件查询

if not kwargs:

# select * from table;

sql = 'select * from %s' % cls.table_name

res = ms.my_select(sql)

# 若有kwargs代表有条件

else:

# print(kwargs) # {id:1}

key = list(kwargs.keys())[0] # id

value = kwargs.get(key) # 1

# select * from table where id=1;

sql = 'select * from %s where %s=?' % (cls.table_name, key)

sql = sql.replace('?', '%s')

res = ms.my_select(sql, value)

if res:

# [{},{}, {}] ----> [obj1, obj2, obj3]

# 把mysql返回来的 列表套 字典 ---> 列表套 对象

# l1 = []

# # 遍历mysql返回所有的字典

# for d in res:

# # 把每一个字典传给cls实例化成一个个的r1对象

# r1 = cls(**d)

# # 追加到l1列表中

# l1.append(r1)

return [cls(**result) for result in res]

# 插入

def save(self):

ms = Mysql()

# insert into table(x,x,x) values(x,x,x);

# 字段名

fields = []

# 字段的值

values = []

# 存放对应字段的?号

args = []

for k, v in self.mappings.items():

# 把主键过滤掉

if not v.primary_key:

fields.append(v.name)

values.append(getattr(self, v.name, v.default))

args.append('?')

# insert into table(x,x,x) values(?, ?, ?);

sql = 'insert into %s(%s) values(%s)' % (

self.table_name, ','.join(fields), ','.join(args)

)

sql = sql.replace('?', '%s')

ms.my_execute(sql, values)

# 更新

def sql_update(self):

ms = Mysql()

fields = []

primary_key = None

values = []

for k, v in self.mappings.items():

# 获取主键的值

if v.primary_key:

primary_key = getattr(self, v.name, v.default)

else:

# 获取 字段名=?, 字段名=?,字段名=?

fields.append(v.name + '=?')

# 获取所有字段的值

values.append(getattr(self, v.name, v.default))

# update table set %s=?,... where id=1; 把主键当做where条件

sql = 'update %s set %s where %s=%s' % (

self.table_name, ','.join(fields), self.primary_key, primary_key

)

# print(sql) # update User set name=? where id=3

sql = sql.replace('?', '%s')

ms.my_execute(sql, values)

orm/mysql_control.py

import pymysql

from orm.db_pool import POOL

class Mysql:

def __init__(self):

# 建立链接

self.conn = POOL.connection()

# 获取游标

self.cursor = self.conn.cursor(pymysql.cursors.DictCursor)

# 关闭游标\链接方法

def close_db(self):

self.cursor.close()

self.conn.close()

# 查看

def my_select(self, sql, args=None):

self.cursor.execute(sql, args)

res = self.cursor.fetchall()

# [{}, {}, {}]

# print(res)

return res

# 提交

def my_execute(self, sql, args):

try:

# 把insert , update...一系列sql提交到mysql中

self.cursor.execute(sql, args)

except Exception as e:

print(e)

orm/db_pool.py

from DBUtils.PooledDB import PooledDB

import pymysql

# pip3 install DBUtils

POOL = PooledDB(

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='000000',

database='youku_demo',

charset='utf8',

autocommit='True'

)

lib/common.py

import time

import hashlib

import json

import struct

import uuid

from functools import wraps

from db import user_data

def get_time():

now_time = time.strftime('%Y-%m-%d %X')

return now_time

def get_md5_pwd(pwd):

md = hashlib.md5()

md.update(pwd.encode('utf-8'))

md.update('虹桥炮王,Jason是也!'.encode('utf-8'))

return md.hexdigest()

def send_data(send_dic, conn):

data_bytes = json.dumps(send_dic).encode('utf-8')

headers = struct.pack('i', len(data_bytes))

conn.send(headers)

conn.send(data_bytes)

def get_random_code():

# uuid可以产生一个世界上唯一的字符串

md5 = hashlib.md5()

md5.update(str(uuid.uuid4()).encode('utf-8'))

return md5.hexdigest()

# 登录认证装饰器

def login_auth(func):

@wraps(func)

# client_back_dic, conn = args

def inner(*args, **kwargs):

# if args[0].get('session') == 服务端存放的session值:

# # [session, user_id] = values

addr = args[0].get('addr')

# addr: [session, user_id]

user_session = user_data.user_online.get(addr)

if args[0].get('session') == user_session[0]:

args[0]['user_id'] = user_session[1]

#

# for values in user_data.user_online.values():

# if args[0].get('session') == values[0]:

# # 添加到client_back_dic

# args[0]['user_id'] = values[1] # user_id

# 判断user_id是否存在

if args[0].get('user_id'):

func(*args, **kwargs)

else:

send_dic = {'flag': False, 'msg': '未登录,请去登录!'}

# send_data(send_dic, conn)

send_data(send_dic, args[1])

return inner

# if __name__ == '__main__':

#

# # print(get_time())

# print(get_random_code())

# 05248e1b1a10ac08872f8dd5d9dbd814

# 161df6d362dc52b0037d938a0717963e

# aabd3987f88b2db46566cf6d9ec864e2

lib/lock_file.py

mutex = None

db/user_data.py

user_online = {

# addr: [session, user_id]

}

interface/admin_interface.py

from lib import common

from db import models

import os

from conf import settings

@common.login_auth

def upload_movie_interface(client_back_dic, conn):

print('炮王来交货啦!')

# 确保电影名称是唯一的 随机字符串 + 电影名称

movie_name = common.get_random_code() + client_back_dic.get('movie_name') # .mp4

movie_size = client_back_dic.get('file_size')

movie_path = os.path.join(settings.DOWNLOAD_PATH, movie_name)

# 1.接受上传的文件

data_recv = 0

with open(movie_path, 'wb') as f:

while data_recv < movie_size:

data = conn.recv(1024)

f.write(data)

data_recv += len(data)

# 2.把电影数据保存到mysql中

movie_obj = models.Movie(

name=movie_name, file_md5=client_back_dic.get('file_md5'),

is_free=client_back_dic.get('is_free'), is_delete=0,

path=movie_path, user_id=client_back_dic.get('user_id'),

upload_time=common.get_time()

)

movie_obj.save()

send_dic = {

'flag': True, 'msg': f'{client_back_dic.get("movie_name")}电影上传成功!'

}

common.send_data(send_dic, conn)

@common.login_auth

def check_movie_interface(client_back_dic, conn):

file_md5 = client_back_dic.get('file_md5')

movie_list = models.Movie.select(file_md5=file_md5)

if movie_list:

print(1111)

send_dic = {

'flag': False,

'msg': '电影已存在!'

}

else:

print(222)

send_dic = {

'flag': True,

'msg': '电影可以上传'

}

common.send_data(send_dic, conn)

def delete_movie_interface(client_back_dic, conn):

# 直接删除

movie_obj = models.Movie.select(id=client_back_dic.get('movie_id'))[0]

movie_obj.is_delete = 1

# 调用更新方法

movie_obj.sql_update()

send_dic = {

'flag': True,

'msg': '电影删除成功!'

}

common.send_data(send_dic, conn)

@common.login_auth

def put_notice_interface(client_back_dic, conn):

title = client_back_dic.get('title')

content = client_back_dic.get('content')

user_id = client_back_dic.get('user_id')

notice_obj = models.Notice(title=title, content=content, user_id=user_id,

create_time=common.get_time())

notice_obj.save()

send_dic = {

'msg': '公告发布成功!'

}

common.send_data(send_dic, conn)

conf/settings.py

import os

BASE_PATH = os.path.dirname(os.path.dirname(__file__))

DOWNLOAD_PATH = os.path.join(BASE_PATH, 'download_files')

客户端代码

start.py

import os

import sys

from core import src

sys.path.append(os.path.dirname(__file__))

if __name__ == '__main__':

src.run()

core/src.py

from core import admin, user

func_dic = {

'1': admin.admin_view,

'2': user.user_view,

}

def run():

while True:

print('''

1.管理员功能

2.用户功能

q.退出

''')

choice = input('请选择功能编号: ').strip()

if choice == 'q':

break

if choice not in func_dic:

continue

func_dic.get(choice)()

core/admin.py

from tcp_client import socket_client

from lib import common

import os

from conf import settings

user_info = {

'cookies': None

}

def register(client):

while True:

username = input('请输入用户名:').strip()

password = input('请输入密码:').strip()

re_password = input('请确认密码:').strip()

if password == re_password:

send_dic = {'username': username,

'password': password,

'type': 'register',

'user_type': 'admin'}

# {'flag': False, 'msg': '用户已存在!'}

# {'flag': True, 'msg': '注册成功'}

back_dic = common.send_msg_back_dic(send_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()

send_dic = {

'type': 'login',

'username': username,

'password': password,

'user_type': 'admin'

}

back_dic = common.send_msg_back_dic(send_dic, client)

if back_dic.get('flag'):

session = back_dic.get('session')

user_info['cookies'] = session

print(back_dic.get('msg'))

break

else:

print(back_dic.get('msg'))

# 上传电影

def upload_movie(client):

while True:

# 1.打印电影列表

movie_list = common.get_movie_list()

for index, movie in enumerate(movie_list):

print(index, movie)

choice = input('请输入上传的电影编号:').strip()

if not choice.isdigit():

print('请输入数字!')

continue

choice = int(choice)

if choice not in range(len(movie_list)):

print("请选择正确编号!")

continue

movie_name = movie_list[choice]

movie_path = os.path.join(settings.UPLOAD_FILES, movie_name)

# 2.去服务端校验电影是否存在

file_md5 = common.get_movie_md5(movie_path)

send_dic = {

'type': 'check_movie',

'session': user_info.get('cookies'),

'file_md5': file_md5

}

back_dic = common.send_msg_back_dic(send_dic, client)

if back_dic.get('flag'):

print(back_dic.get('msg'))

send_dic = {

'type': 'upload_movie',

'file_md5': file_md5,

'file_size': os.path.getsize(movie_path),

'movie_name': movie_name,

'session': user_info.get('cookies')

}

is_free = input('上传电影是否免费: y/n').strip()

if is_free == 'y':

send_dic['is_free'] = 1

else:

send_dic['is_free'] = 0

back_dic = common.send_msg_back_dic(send_dic, client, file=movie_path)

if back_dic.get('flag'):

print(back_dic.get('msg'))

break

else:

print(back_dic.get('msg'))

#

#

# send_dic = {'type': 'upload_movie','session': user_info.get('cookies')}

# back_dic = common.send_msg_back_dic(send_dic, client)

# print(back_dic)

# 删除电影

def delete_movie(client):

while True:

# 1.从服务端获取电影列表

send_dic = {

'type': 'get_movie_list',

'session': user_info.get('cookies')

}

# 发送获取电影请求

back_dic = common.send_msg_back_dic(

send_dic, client)

if back_dic.get('flag'):

back_movie_list = back_dic.get('back_movie_list')

# 打印选择的电影

for index, movie_list in enumerate(back_movie_list):

print(index, movie_list)

# 2.选择需要删除的电影

choice = input('请输入需要删除的电影编号:').strip()

if not choice.isdigit():

continue

choice = int(choice)

if choice not in range(len(back_movie_list)):

continue

movie_id = back_movie_list[choice][2]

send_dic = {

'type': 'delete_movie',

'movie_id': movie_id,

'session': user_info.get('cookies')

}

# 发送删除电影请求

back_dic = common.send_msg_back_dic(send_dic, client)

if back_dic.get('flag'):

print(back_dic.get('msg'))

break

else:

print(back_dic.get('msg'))

break

# 发布公告

def put_notice(client):

title = input('请输入公告标题:').strip()

content = input('请输入公告内容:').strip()

send_dic = {

'type': 'put_notice',

'session': user_info.get('cookies'),

'title': title,

'content': content

}

back_dic = common.send_msg_back_dic(send_dic, client)

print(back_dic.get('msg'))

func_dic = {

'1': register,

'2': login,

'3': upload_movie,

'4': delete_movie,

'5': put_notice,

}

def admin_view():

sk_client = socket_client.SocketClient()

client = sk_client.get_client()

while True:

print('''

1.注册

2.登录

3.上传视频

4.删除视频

5.发布公告

q.退出

''')

choice = input('请选择功能编号:').strip()

if choice == 'q':

break

if choice not in func_dic:

continue

func_dic.get(choice)(client)

tcp_client/socket_client.py

import socket

class SocketClient:

def __init__(self):

self.client = socket.socket()

self.client.connect(('127.0.0.1', 9527))

def get_client(self):

return self.client

lib/common.py

import json

import struct

from conf import settings

import os

import hashlib

def send_msg_back_dic(send_dic, client, file=None):

data_bytes = json.dumps(send_dic).encode('utf-8')

headers = struct.pack('i', len(data_bytes))

client.send(headers)

client.send(data_bytes)

# 上传电影

if file:

with open(file, 'rb') as f:

for line in f:

# print(line)

client.send(line)

headers = client.recv(4)

data_len = struct.unpack('i', headers)[0]

data_bytes = client.recv(data_len)

back_dic = json.loads(data_bytes.decode('utf-8'))

return back_dic

def get_movie_list():

if os.path.exists(settings.UPLOAD_FILES):

movie_list = os.listdir(settings.UPLOAD_FILES)

if movie_list:

return movie_list

# 获取电影的md5值

def get_movie_md5(movie_path):

md5 = hashlib.md5()

# 截取电影的4个位置的md5值

movie_size = os.path.getsize(movie_path)

# 从电影的4个位置个截取10个bytes数据

current_index = [0, movie_size // 3, (movie_size // 3) * 2, movie_size - 10]

with open(movie_path, 'rb') as f:

for index in current_index:

f.seek(index)

data = f.read(10)

md5.update(data)

return md5.hexdigest()

conf/settings.py

import os

BASE_PATH = os.path.dirname(os.path.dirname(__file__))

UPLOAD_FILES = os.path.join(BASE_PATH, 'upload_files')

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值