directorio
Resumen Ejecutivo Hoy
canales para lograr la función de chat grupo django-basado
enchufe gojs
Usted da el código de paquete, usado para copia directa
módulo paramiko
Usted da el código de paquete, usado para copia directa
módulo gitpython
Usted da el código de paquete, usado para copia directa
contenido detallado de hoy
canales para lograr la función de chat grupo django-basado
Pre-configurado en tres etapas, a saber, soporte para HTTP y el apoyo WebSocket
class ProtocolTypeRouter:
"""
Takes a mapping of protocol type names to other Application instances,
and dispatches to the right one based on protocol name (or raises an error)
"""
def __init__(self, application_mapping):
self.application_mapping = application_mapping
if "http" not in self.application_mapping:
self.application_mapping["http"] = AsgiHandler
# routing.py
from channels.routing import ProtocolTypeRouter,URLRouter
from django.conf.urls import url
from django.urls import path
from app01 import consumers
application = ProtocolTypeRouter({
'websocket':URLRouter([
path('chat/', consumers.ChatConsumer),
])
})
# consumers.py
from channels.generic.websocket import WebsocketConsumer
from channels.exceptions import StopConsumer
consumers_obj_list = []
class ChatConsumer(WebsocketConsumer):
def websocket_connect(self, message):
"""请求websocket连接的时候自动触发"""
print('校验并请求连接')
consumers_obj_list.append(self)
self.accept() # 与客户端建立链接
def websocket_receive(self, message):
"""前端浏览器发送消息自动触发"""
# print(message) # 消息字典 {'type': 'websocket.receive', 'text': '哈哈'}
text_data = message['text']
for obj in consumers_obj_list:
# 给客户端发消息
obj.send(text_data=text_data)
def websocket_disconnect(self, message):
"""断开websocket连接自动触发"""
# print('断开链接')
# 将当前断开的对象从列表中移除
consumers_obj_list.remove(self)
raise StopConsumer
sala de chat
"""
http协议
index >>> index函数
访问:浏览器地址栏输入地址直接访问
websocket协议
chat >>> ChatConsumer类(3个方法)
访问:利用js内置对象new WebSocket('ws://127.0.0.1:8080/chat/')
"""
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/twitter-bootstrap/4.4.1/js/bootstrap.min.js"></script>
<link href="https://cdn.bootcss.com/twitter-bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<h1>聊天室</h1>
<div>
<input type="text" name="" id="i1">
<button onclick="sendMsg()">发送</button>
</div>
<h1>聊天记录</h1>
<div id="record"></div>
<script>
// 生成内置对象
var ws = new WebSocket('ws://127.0.0.1:8000/chat/');
// 1.握手环节成功之后自动触发 onopen
ws.onopen =function (){
console.log('链接成功!')
};
// 2.发送数据 send
function sendMsg(){
ws.send($("#i1").val())
}
// 3.服务端发送数据自动触发, onmessage
ws.onmessage = function(args){
{#alert(args.data)#}
var Eple = $('<p>');
Eple.text(args.data);
$('#record').append(Eple);
};
// 4.浏览器断开链接 close
ws.onclose = function () {
ws.close()
};
</script>
</body>
</html>
versión de servidor de listas Lowb
Mantener una lista global de los clientes una vez que se añade el enlace a la lista, cuando el mensaje de respuesta después de la lista de circulación de los objetos que envían mensajes a cada objeto de enlace de cliente con el fin de conseguir una masa
De hecho, la función de masa, el funcionario ha proporcionado un método para el canal-capas (escribe la repetición de código)
resumen
# 后端三个方法
websocket_connect
websocket_receive
websocket_disconnect
# 前端四个方法
onopen
send
onmessage
onclose
enchufe gojs
Es sólo un enchufe front-end
js, y luego ir a la página web oficial para descargar la necesidad correspondiente: https://gojs.net/latest/index.html
Después de descargar los archivos js no están acostumbrados, tenemos que entender que sólo tres
"""
go.js 正常必须要导入的文件
go-debug.js 会展示报错消息 类似于debug模式 线上肯定不会使用
Figures.js 扩展图表(go.js自带的图表比较少,如果出现图标显示不出来的情况)
"""
# 总结:使用的时候导入go.js和Figures.js就不会有任何问题了
uso básico
rutina fija: primero con div delineado área de la página, después de todos gojs trazan renderizado todo el interior de la div
<div id="myDiagramDiv" style="width:500px; height:350px; background-color: #DAE4E4;"></div>
<script src="go.js"></script>
<script>
var $ = go.GraphObject.make;
// 第一步:创建图表
var myDiagram = $(go.Diagram, "myDiagramDiv"); // 创建图表,用于在页面上画图
// 第二步:创建一个节点,内容为jason
var node = $(go.Node, $(go.TextBlock, {text: "jason"}));
// 第三步:将节点添加到图表中
myDiagram.add(node)
</script>
Conceptos importantes
- Crear un TextBlock de texto
- Gráficos de formas
- Nodo Nodo (texto y gráficos combinados)
- Flecha de enlace
Bloque de texto
<div id="myDiagramDiv" style="width:500px; height:350px; background-color: #DAE4E4;"></div>
<script src="go.js"></script>
<script>
var $ = go.GraphObject.make;
// 第一步:创建图表
var myDiagram = $(go.Diagram, "myDiagramDiv"); // 创建图表,用于在页面上画图
var node1 = $(go.Node, $(go.TextBlock, {text: "zhangzhangzhang"}));
myDiagram.add(node1);
var node2 = $(go.Node, $(go.TextBlock, {text: "zhangzhang", stroke: 'red'}));
myDiagram.add(node2);
var node3 = $(go.Node, $(go.TextBlock, {text: "zhang", background: 'lightblue'}));
myDiagram.add(node3);
</script>
Forma
<div id="myDiagramDiv" style="width:500px; height:350px; background-color: #DAE4E4;"></div>
<script src="go.js"></script>
<script src="Figures.js"></script>
<script>
var $ = go.GraphObject.make;
// 第一步:创建图表
var myDiagram = $(go.Diagram, "myDiagramDiv"); // 创建图表,用于在页面上画图
var node1 = $(go.Node,
$(go.Shape, {figure: "Ellipse", width: 40, height: 40})
);
myDiagram.add(node1);
var node2 = $(go.Node,
$(go.Shape, {figure: "RoundedRectangle", width: 40, height: 40, fill: 'green',stroke:'red'})
);
myDiagram.add(node2);
var node3 = $(go.Node,
$(go.Shape, {figure: "Rectangle", width: 40, height: 40, fill: null})
);
myDiagram.add(node3);
var node5 = $(go.Node,
$(go.Shape, {figure: "Club", width: 40, height: 40, fill: 'red'})
);
myDiagram.add(node5);
</script>
nodo
<div id="myDiagramDiv" style="width:500px; height:350px; background-color: #DAE4E4;"></div>
<script src="go.js"></script>
<script src="Figures.js"></script>
<script>
var $ = go.GraphObject.make;
// 第一步:创建图表
var myDiagram = $(go.Diagram, "myDiagramDiv"); // 创建图表,用于在页面上画图
var node1 = $(go.Node,
"Vertical", // 垂直方向
{
background: 'yellow',
padding: 8
},
$(go.Shape, {figure: "Ellipse", width: 40, height: 40,fill:null}),
$(go.TextBlock, {text: "jason"})
);
myDiagram.add(node1);
var node2 = $(go.Node,
"Horizontal", // 水平方向
{
background: 'white',
padding: 5
},
$(go.Shape, {figure: "RoundedRectangle", width: 40, height: 40}),
$(go.TextBlock, {text: "jason"})
);
myDiagram.add(node2);
var node3 = $(go.Node,
"Auto", // 居中
$(go.Shape, {figure: "Ellipse", width: 80, height: 80, background: 'green', fill: 'red'}),
$(go.TextBlock, {text: "jason"})
);
myDiagram.add(node3);
</script>
enlace
<div id="myDiagramDiv" style="width:500px; min-height:450px; background-color: #DAE4E4;"></div>
<script src="go.js"></script>
<script>
var $ = go.GraphObject.make;
var myDiagram = $(go.Diagram, "myDiagramDiv",
{layout: $(go.TreeLayout, {angle: 0})}
); // 创建图表,用于在页面上画图
var startNode = $(go.Node, "Auto",
$(go.Shape, {figure: "Ellipse", width: 40, height: 40, fill: '#79C900', stroke: '#79C900'}),
$(go.TextBlock, {text: '开始', stroke: 'white'})
);
myDiagram.add(startNode);
var downloadNode = $(go.Node, "Auto",
$(go.Shape, {figure: "RoundedRectangle", height: 40, fill: 'red', stroke: '#79C900'}),
$(go.TextBlock, {text: '下载代码', stroke: 'white'})
);
myDiagram.add(downloadNode);
var startToDownloadLink = $(go.Link,
{fromNode:downloadNode, toNode:startNode,},
$(go.Shape, {strokeWidth: 1}),
$(go.Shape, {toArrow: "OpenTriangle", fill: null, strokeWidth: 1})
);
myDiagram.add(startToDownloadLink);
</script>
Pregunta: Queremos generar dinámicamente tablas y dinámicamente modificar el icono de estado y mensajes, los datos deben provenir de la parte de atrás
Por lo tanto, una resolución para ser escrito extremos frontal interacción de datos y
Los datos de unión
<div id="diagramDiv" style="width:100%; min-height:450px; background-color: #DAE4E4;"></div>
<script src="go.js"></script>
<script>
var $ = go.GraphObject.make;
var diagram = $(go.Diagram, "diagramDiv",{
layout: $(go.TreeLayout, {
angle: 0,
nodeSpacing: 20,
layerSpacing: 70
})
});
// 生成一个节点模版
diagram.nodeTemplate = $(go.Node, "Auto",
$(go.Shape, {
figure: "RoundedRectangle",
fill: 'yellow',
stroke: 'yellow'
}, new go.Binding("figure", "figure"), new go.Binding("fill", "color"), new go.Binding("stroke", "color")),
$(go.TextBlock, {margin: 8}, new go.Binding("text", "text"))
);
// 生成一个箭头模版
diagram.linkTemplate = $(go.Link,
{routing: go.Link.Orthogonal},
$(go.Shape, {stroke: 'yellow'}, new go.Binding('stroke', 'link_color')),
$(go.Shape, {toArrow: "OpenTriangle", stroke: 'yellow'}, new go.Binding('stroke', 'link_color'))
);
// 数据集合 以后替换ajax请求 注意使用key和parent来规定箭头的指向
var nodeDataArray = [
{key: "start", text: '开始', figure: 'Ellipse', color: "lightgreen"},
{key: "download", parent: 'start', text: '下载代码', color: "lightgreen", link_text: '执行中...'},
{key: "compile", parent: 'download', text: '本地编译', color: "lightgreen"},
{key: "zip", parent: 'compile', text: '打包', color: "red", link_color: 'red'},
{key: "c1", text: '服务器1', parent: "zip"},
{key: "c11", text: '服务重启', parent: "c1"},
{key: "c2", text: '服务器2', parent: "zip"},
{key: "c21", text: '服务重启', parent: "c2"},
{key: "c3", text: '服务器3', parent: "zip"},
{key: "c31", text: '服务重启', parent: "c3"},
];
diagram.model = new go.TreeModel(nodeDataArray);
// 动态控制节点颜色变化 后端给一个key值 即可查找图表并修改
var node = diagram.model.findNodeDataForKey("zip");
diagram.model.setDataProperty(node, "color", "lightgreen");
</script>
resumen
"""
通过数据绑定的方式就可以实现前后端交互的形式
"""
Cómo quitar gojs propia marca de agua
JS tiene que modificar el código fuente
Encontrar el archivo js cadena fija 7eba17a4ca3b1a8346
/*a.kr=b.V[Ra("7eba17a4ca3b1a8346")][Ra("78a118b7")](b.V,Jk,4,4);*/
Tenga en cuenta la línea de cadena de código se encuentra
Y añadir una línea de código nuevo
a.kr=function(){return false};
módulo paramiko
A través de ssh servidor de conexión remota y ejecutar el comando en la respuesta, Xshell similares
gestión de lotes ansible para servidores remotos, con el hecho subyacente es el módulo paramiko
instalar
pip3 install paramiko
uso
Módulo paramiko que es para apoyar el nombre de usuario y la contraseña del modo de funcionamiento del servidor
También es compatible con la clave pública y privada del modo de funcionamiento del servidor
Y la producción real de clave pública y privada se utiliza más, ya que la contraseña es la información sensible
Ejecutar el comando
"""执行命令 用户名和密码的方式"""
# 创建对象
ssh = paramiko.SSHClient()
# 允许链接不在know_hosts文件中的主机
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 链接服务器
ssh.connect(hostname='172.16.219.173',port=22,username='root',password='jason123')
# 执行命令
stdin, stdout, stderr = ssh.exec_command('ls /')
"""
stdin用来输入额外的命令
yum install ansible 额外的命令-y
stdout命令的返回结果 正确
stderr命令的返回结果 错误
"""
res = stdout.read() # 网络传输过来的二进制数据
print(res.decode('utf-8'))
# 关闭链接
ssh.close()
# 公钥和私钥(先讲公钥保存到服务器上)
import paramiko
# 读取本地私钥
private_key = paramiko.RSAKey.from_private_key_file('a.txt')
# 创建SSH对象
ssh = paramiko.SSHClient()
# 允许连接不在know_hosts文件中的主机
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 连接服务器
ssh.connect(hostname='172.16.219.173', port=22, username='root', pkey=private_key)
# 执行命令
stdin, stdout, stderr = ssh.exec_command('ls /')
# 获取命令结果
result = stdout.read()
print(result.decode('utf-8'))
# 关闭连接
ssh.close()
archivos de carga y descarga
"""上传下载文件 用户名和密码的方式"""
import paramiko
# 用户名和密码
transport = paramiko.Transport(('172.16.219.173', 22))
transport.connect(username='root', password='jason123')
sftp = paramiko.SFTPClient.from_transport(transport)
# 上传文件
# sftp.put("a.txt", '/data/b.txt') # 注意上传文件到远程某个文件下 文件必须存在
# 下载文件
sftp.get('/data/b.txt', 'c.txt') # 将远程文件下载到本地并重新命令
transport.close()
"""上传下载文件 公钥私钥的方式"""
# 公钥和私钥
import paramiko
private_key = paramiko.RSAKey.from_private_key_file('c.txt')
transport = paramiko.Transport(('172.16.219.173', 22))
transport.connect(username='root', pkey=private_key)
sftp = paramiko.SFTPClient.from_transport(transport)
# 将location.py 上传至服务器 /tmp/test.py
# sftp.put('manage.py', '/data/temp.py')
# 将remove_path 下载到本地 local_path
# sftp.get('remove_path', 'local_path')
transport.close()
clase paquete
"""
我现在即想执行命令又想上传下载文件并且多次执行
yum install ansible
yum install redis
yum install redis
upload
单链接下完成多部操作
"""
# 下面写的类 你只要只要是想通过paramiko链接服务器都可以使用
import paramiko
class SSHProxy(object):
def __init__(self, hostname, port, username, password):
self.hostname = hostname
self.port = port
self.username = username
self.password = password
self.transport = None
def open(self): # 给对象赋值一个上传下载文件对象连接
self.transport = paramiko.Transport((self.hostname, self.port))
self.transport.connect(username=self.username, password=self.password)
def command(self, cmd): # 正常执行命令的连接 至此对象内容就既有执行命令的连接又有上传下载链接
ssh = paramiko.SSHClient()
ssh._transport = self.transport
stdin, stdout, stderr = ssh.exec_command(cmd)
result = stdout.read()
return result
def upload(self, local_path, remote_path):
sftp = paramiko.SFTPClient.from_transport(self.transport)
sftp.put(local_path, remote_path)
sftp.close()
def close(self):
self.transport.close()
def __enter__(self): # 对象执行with上下文会自动触发
#
# print('触发了enter')
self.open()
return self # 这里发挥上面with语法内的as后面拿到的就是什么
# return 123
def __exit__(self, exc_type, exc_val, exc_tb): # with执行结束自动触发
# print('触发了exit')
self.close()
"""
上面这个类在使用的时候 需要先执行open方法
obj = SSHProxy()
obj.open() 文件对象 链接服务器
obj.command()
obj.command()
obj.upload()
obj.upload()
obj.close() 关闭链接
文件操作
f = open()
f.write()
f.read()
f.close()
with上下文管理
with open() as f:
...
"""
# 对象默认是不支持with语法的
# obj = SSHProxy('172.16.219.173',22,'root','jason123')
# with obj as f:
# # print('进入with代码块')
# print(f)
if __name__ == '__main__':
with SSHProxy('172.16.219.173',22,'root','jason123') as ssh:
ssh.command()
ssh.command()
ssh.command()
ssh.upload()
preguntas cara orientada a objetos
"""
面试题
请在Context类中添加代码完成该类的实现
class Context:
pass
with Context() as ctx:
ctx.do_something()
"""
class Context:
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
pass
def do_something(self):
pass
with Context() as ctx:
ctx.do_something()
pitón operación GIT
gipython módulo de instalación
pip3 install gitpython
uso básico
from git.repo import Repo
import os
# 从远程仓库下载代码到本地 pull/clone
download_path = os.path.join('jason','NB')
# 从远程仓库将代码下载到上面创建的目录中
Repo.clone_from('https://github.com/DominicJi/TeachTest.git',to_path=download_path,branch='master')
más acciones
# ############## 2. pull最新代码 ##############
import os
from git.repo import Repo
local_path = os.path.join('jason', 'NB')
repo = Repo(local_path)
repo.git.pull()
# ############## 3. 获取所有分支 ##############
import os
from git.repo import Repo
local_path = os.path.join('jason', 'NB')
repo = Repo(local_path)
branches = repo.remote().refs
for item in branches:
print(item.remote_head)
# ############## 4. 获取所有版本 ##############
import os
from git.repo import Repo
local_path = os.path.join('jason', 'NB')
repo = Repo(local_path)
for tag in repo.tags:
print(tag.name)
# ############## 5. 获取所有commit ##############
import os
from git.repo import Repo
local_path = os.path.join('jason', 'NB')
repo = Repo(local_path)
# 将所有提交记录结果格式成json格式字符串 方便后续反序列化操作
commit_log = repo.git.log('--pretty={"commit":"%h","author":"%an","summary":"%s","date":"%cd"}', max_count=50,
date='format:%Y-%m-%d %H:%M')
log_list = commit_log.split("\n")
real_log_list = [eval(item) for item in log_list]
print(real_log_list)
# ############## 6. 切换分支 ##############
import os
from git.repo import Repo
local_path = os.path.join('jason', 'NB')
repo = Repo(local_path)
before = repo.git.branch()
print(before)
repo.git.checkout('master')
after = repo.git.branch()
print(after)
repo.git.reset('--hard', '854ead2e82dc73b634cbd5afcf1414f5b30e94a8')
# ############## 7. 打包代码 ##############
with open(os.path.join('jason', 'NB.tar'), 'wb') as fp:
repo.archive(fp)
Las versiones posteriores del paquete
import os
from git.repo import Repo
from git.repo.fun import is_git_dir
class GitRepository(object):
"""
git仓库管理
"""
def __init__(self, local_path, repo_url, branch='master'):
self.local_path = local_path
self.repo_url = repo_url
self.repo = None
self.initial(repo_url, branch)
def initial(self, repo_url, branch):
"""
初始化git仓库
:param repo_url:
:param branch:
:return:
"""
if not os.path.exists(self.local_path):
os.makedirs(self.local_path)
git_local_path = os.path.join(self.local_path, '.git')
if not is_git_dir(git_local_path):
self.repo = Repo.clone_from(repo_url, to_path=self.local_path, branch=branch)
else:
self.repo = Repo(self.local_path)
def pull(self):
"""
从线上拉最新代码
:return:
"""
self.repo.git.pull()
def branches(self):
"""
获取所有分支
:return:
"""
branches = self.repo.remote().refs
return [item.remote_head for item in branches if item.remote_head not in ['HEAD', ]]
def commits(self):
"""
获取所有提交记录
:return:
"""
commit_log = self.repo.git.log('--pretty={"commit":"%h","author":"%an","summary":"%s","date":"%cd"}',
max_count=50,
date='format:%Y-%m-%d %H:%M')
log_list = commit_log.split("\n")
return [eval(item) for item in log_list]
def tags(self):
"""
获取所有tag
:return:
"""
return [tag.name for tag in self.repo.tags]
def change_to_branch(self, branch):
"""
切换分值
:param branch:
:return:
"""
self.repo.git.checkout(branch)
def change_to_commit(self, branch, commit):
"""
切换commit
:param branch:
:param commit:
:return:
"""
self.change_to_branch(branch=branch)
self.repo.git.reset('--hard', commit)
def change_to_tag(self, tag):
"""
切换tag
:param tag:
:return:
"""
self.repo.git.checkout(tag)
if __name__ == '__main__':
local_path = os.path.join('codes', 'luffycity')
repo = GitRepository(local_path,remote_path)
branch_list = repo.branches()
print(branch_list)
repo.change_to_branch('dev')
repo.pull()
resumen
"""
后期你在接触一些模块的时候 也应该想到将该模块所有的方法整合到一起
方便以后的调用
"""