即使一个人,也要活得像军队一样!

主要文件: launch.jsonsettings.json

launch.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [

{
"name": "odoo",
"type": "python",
"request": "launch",
"program": "${workspaceRoot}/start", // 启动入口
"pythonPath":"${config:python.pythonPath}", // python环境路径, 对应settings文件
"cwd": "${workspaceRoot}",
"env": {},
"envFile": "${workspaceRoot}/.env",
"args": [
"-c",
"${workspaceRoot}/config/cscloud-dev.conf" // 参数
],
"debugOptions": [
"WaitOnAbnormalExit",
"WaitOnNormalExit",
"RedirectOutput"
],
"console": "integratedTerminal"
}
],
"compounds": []
}
阅读全文 »

概述

在开发过程中,一般情况下会基于Fork项目进行,完成后提交到origin项目。但是,在每次开发项目之前,需要保证Fork项目与Origin项目保持一致,如何操作请参考下文。

FORK项目后与原项目进行同步

Fork项目,通过UI完成

clone项目到本地

1
git clone https://gitlab.xxx.com/shuzhang/payment.git
阅读全文 »

问题描述

Chrome浏览器所有页面崩溃,包括设置页面,“喔唷,崩溃啦!”
显示错误码:STATUS_INVALID_IMAGE_HASH
Chrome所有插件报错,右下角一串弹框

问题所在

Google在79版本(2019年12月20号左右)的更新中又重新启用了Renderer Code Integrity Protection(渲染器代码完整性保护),会阻止签名不是谷歌和微软的模块加载。该功能已经在之前一个版本中导致同样的问题,并由Google自己禁用了。

阅读全文 »

引子

假如有两个程序A和B,程序A在执行到一半的过程中,需要读取大量的数据输入(I/O操作),而此时CPU只能静静地等待任务A读取完数据才能继续执行,这样就白白浪费了CPU资源。是不是在程序A读取数据的过程中,让程序B去执行,当程序A读取完数据之后,让程序B暂停,然后让程序A继续执行?当然没问题,但这里有一个关键词:切换。既然是切换,那么这就涉及到了状态的保存,状态的恢复,加上程序A与程序B所需要的系统资源(内存,硬盘,键盘等等)是不一样的。自然而然的就需要有一个东西去记录程序A和程序B分别需要什么资源,怎样去识别程序A和程序B等等,所以就有了一个叫进程的抽象

阅读全文 »

手写websocket

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import socket, base64, hashlib

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(('127.0.0.1', 9527))
sock.listen(5)
# 获取客户端socket对象
conn, address = sock.accept()
# 获取客户端的【握手】信息
data = conn.recv(1024)
print(data)
"""
b'GET /ws HTTP/1.1\r\n
Host: 127.0.0.1:9527\r\n
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:62.0) Gecko/20100101 Firefox/62.0\r\n
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2\r\n
Accept-Encoding: gzip, deflate\r\n
Sec-WebSocket-Version: 13\r\n
Origin: http://localhost:63342\r\n
Sec-WebSocket-Extensions: permessage-deflate\r\n
Sec-WebSocket-Key: jocLOLLq1BQWp0aZgEWL5A==\r\n
Cookie: session=6f2bab18-2dc4-426a-8f06-de22909b967b\r\n
Connection: keep-alive, Upgrade\r\n
Pragma: no-cache\r\n
Cache-Control: no-cache\r\n
Upgrade: websocket\r\n\r\n'
"""

# magic string为:258EAFA5-E914-47DA-95CA-C5AB0DC85B11
magic_string = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'


def get_headers(data):
header_dict = {}
header_str = data.decode("utf8")
for i in header_str.split("\r\n"):
if str(i).startswith("Sec-WebSocket-Key"):
header_dict["Sec-WebSocket-Key"] = i.split(":")[1].strip()

return header_dict


def get_header(data):
"""
将请求头格式化成字典
:param data:
:return:
"""
header_dict = {}
data = str(data, encoding='utf-8')

header, body = data.split('\r\n\r\n', 1)
header_list = header.split('\r\n')
for i in range(0, len(header_list)):
if i == 0:
if len(header_list[i].split(' ')) == 3:
header_dict['method'], header_dict['url'], header_dict['protocol'] = header_list[i].split(' ')
else:
k, v = header_list[i].split(':', 1)
header_dict[k] = v.strip()
return header_dict


headers = get_headers(data) # 提取请求头信息
# 对请求头中的sec-websocket-key进行加密
response_tpl = "HTTP/1.1 101 Switching Protocols\r\n" \
"Upgrade:websocket\r\n" \
"Connection: Upgrade\r\n" \
"Sec-WebSocket-Accept: %s\r\n" \
"WebSocket-Location: ws://127.0.0.1:9527\r\n\r\n"

value = headers['Sec-WebSocket-Key'] + magic_string
print(value)
ac = base64.b64encode(hashlib.sha1(value.encode('utf-8')).digest())
response_str = response_tpl % (ac.decode('utf-8'))
# 响应【握手】信息
conn.send(response_str.encode("utf8"))

while True:
msg = conn.recv(8096)
print(msg)
阅读全文 »

一、描述符是什么
  描述符本质就是一个新式类,在这个新式类中,至少实现了__get__(),__set__(),__delete__()中的一个,这也被称为描述符协议
  __get__():调用一个属性时,触发
  __set__():为一个属性赋值时,触发
  __delete__():采用del删除属性时,触发

阅读全文 »

一、可以利用property对静态属性的进行修改操作,包括设置和删除属性
  1、调用静态属性===>在静态属性函数前先用@property;
  2、设置静态属性===>在静态属性函数前加上@静态属性函数名.setter,同时静态属性函数要加上value参数;
  3、删除静态属性===>在静态属性函数前加上@静态属性函数名.deleter。

阅读全文 »

有时候,有些业务场景需要返回一些特定的数据。在调用后端接口时,比较频繁。不断的和数据库进行交互。
此时,我们就可以使用@ormcache装饰器装饰该接口。将相同条件的数据,存储在缓存中,下次相同的查询条件就可以直接从缓存中拿。

举栗子:

现在,我有一张表params。用来存放系统的各个模块的参数以及参数值。

阅读全文 »

只需要在context中指定即可, 话不多说,请看代码:

1
2

<field name="packaging_ids" nolabel="1" context="{'tree_view_ref':'product.product_packaging_tree_view2','form_view_ref':'product.product_packaging_form_view2'}"/>
阅读全文 »