晨曦's Blog

This is a window to the soul

前记

Python 中使用 json.dumps 时出现 xxx is not JSON serializable

问题一

1
TypeError: Object of type Decimal is not JSON serializable

问题二

1
TypeError: Object of type datetime is not JSON serializable

解决

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import datetime
import decimal

class JSONEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, decimal.Decimal):
return float(obj)
if isinstance(obj, datetime.datetime):
return obj.strftime('%Y-%m-%d %H:%M:%S')
if isinstance(obj, date):
return obj.strftime("%Y-%m-%d")
return json.JSONEncoder.default(self, obj)

json.dumps(data, cls=JSONEncoder)

JSONEncoder 中的类型可以扩展,加上自己需要的类型即可

需求

Vue 中需要对 Table 数据进行多选,且翻页时需要对前一页选中进行保留

代码

HTML

1
2
3
4
5
6
7
8
9
<el-table
:data="data" border highlight-current-row
@selection-change="handleSelectionChange"
:row-key="getRowKeys"
ref="selectionTable">
<el-table-column type="selection" :reserve-selection="true">
</el-table-column>
...
</el-table>

JS

1
2
3
4
5
6
7
8
9
// 当选择时调用
handleSelectionChange(val) {
// 业务处理
},
getRowKeys(row) {
return row.id; // 重点是id不能重复
},
// 清除所选,视情况在所需要的地方调用即可
this.$refs.selectionTable.clearSelection();

重点是:row-key 不能重复,也就是 getRowKeys 中的 ID 不能重复

前记

业务需求,在 Vue 表格中需要是实现一件展开与一键折叠

代码

HTML

1
2
3
4
5
6
7
8
9
<el-form>
<el-form-item>
<el-button type="primary" @click="handleExpand">{{expandText}}</el-button>
</el-form-item>
</el-form>

<el-table ref="multipleTable" :data="data" border highlight-current-row>
...
</el-table>

JS

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
export default {
data() {
return {
isExpand:false,
expandText:"一键展开",
};
},
methods: {
handleExpand() {
this.isExpand = !this.isExpand
this.$nextTick(() => {
this.forArr(this.data, this.isExpand)
})
if (this.isExpand === true) {
this.expandText = '一键折叠'
}
if (this.isExpand === false) {
this.expandText = '一键展开'
}
},
// 遍历
forArr(arr, isExpand) {
arr.forEach(i => {
// 用于可展开表格与树形表格,切换某一行的展开状态,如果使用了第二个参数,则是设置这一行展开与否(expanded 为 true 则展开)
this.$refs.multipleTable.toggleRowExpansion(i, isExpand)
if (i.children) {
this.forArr(i.children, isExpand)
}
})
},
}
};

效果



Vue 中通过 Key 值的改变进行新的渲染,如:key="变量名" 通过修改变量的值可以重新渲染组件

grep 过滤注释行和空白行

cat /etc/kibana/kibana.yml | grep "^\s*[^# \t].*$"

grep 查看非系统进程

ps -ef | grep -v ]$

Bash 脚本错误处理

1
2
3
4
5
6
# 写法一
set -euxo pipefail

# 写法二
set -eux
set -o pipefail

参考

前记

bitwarden_rs 一直是安装在群晖上的 Docker 中的,对外访问也是通过群晖应用门户程序->反向代理反向代理加路由器端口转发

但是有一个问题,就是群晖 UI 界面的反代没有办法编辑配置,也就没有办法利用 bitwarden_rsWebSocket 自动推送更新

解决

想到的解决方案有两个,第一是通过 Docker 再装一个 Nginx 来做反代,第二是通过群晖自身的 Nginx 来做反代;最后选择了通过自身 Nginx 来做反代

Nginx 配置

/usr/syno/etc/certificate/system/default/ 为群晖安全性->证书上传的默认证书的存储位置

8888、3012 端口为 bitwarden_rs80、3012 映射到群晖对应的端口

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
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name xxx.com;

ssl_certificate /usr/syno/etc/certificate/system/default/fullchain.pem;
ssl_certificate_key /usr/syno/etc/certificate/system/default/privkey.pem;

#ssl_session_cache shared:SSL:50m;
ssl_session_timeout 4h;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_buffer_size 4k;

if ($scheme = http) {
return 301 https://$host$request_uri;
}

location / {
proxy_pass http://127.0.0.1:8888;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect http:// https://;
}

# bw WebSockets
location /notifications/hub {
proxy_pass http://127.0.0.1:3012;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}

# bw WebSockets
location /notifications/hub/negotiate {
proxy_pass http://127.0.0.1:8888;
}

error_page 403 404 500 502 503 504 @error_page;

location @error_page {
root /usr/syno/share/nginx;
rewrite (.*) /error.html break;
allow all;
}
}

链接

将配置文件链接到 /etc/nginx/sites-enabled/
ln -s /volume1/docker/nginx/xxx.com.conf /etc/nginx/sites-enabled/

重启

最后只需要重启 Nginx 即可
sudo synoservicecfg --restart nginx


题外话:

利用第三方 FFMPEG 解码器让群晖的 Video Station 完美支持 DTS、EAC3、TrueHD

参考 01
参考 02

这里指的破解之法为无限期使用 30 天试用期

方法一

卸载重装

方法二

对于 Mac 系统删除以下两个文件即可

1
2
~/Library/Preferences/SmartGit/20.2/preferences.yml
~/Library/Preferences/SmartGit/20.2/license

前记

每次 Mac 大的版本更新后 Git 都用不了

1
2
~ git
xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun

解决

前往官网下载新的 Command_Line_Tools_for_Xcode 安装即可

下载地址

代码

1
2
from Crypto.Cipher import PKCS1_v1_5
from Crypto.PublicKey import RSA

错误

1
2
3
4
5
6
Traceback (most recent call last):
File "/Users/jakehu/Documents/Web/python-usability-cli/app.py", line 13, in <module>
from libs import cmdb, esutil, mysqlutil, redisutil, sendmsg
File "/Users/jakehu/Documents/Web/python-usability-cli/libs/sendmsg.py", line 14, in <module>
from Crypto.Cipher import PKCS1_v1_5
ModuleNotFoundError: No module named 'Crypto'

解决

1
2
3
pip3 uninstall crypto
pip3 uninstall pycrypto
pip3 install pycrypto

x-www-form-urlencoded

requestscontent-typ"content-type": "application/x-www-form-urlencoded; charset=UTF-8", 时请求参数当如下

1
2
3
4
5
r = requests.post(
url,
headers=headers,
data=data
)

json

requestscontent-typ"Content-Type": "application/json;charset=UTF-8", 时请求参数当如下

1
2
3
4
5
r = requests.post(
url,
headers=headers,
data=json.dumps(data)
)

x-www-form-urlencoded 时应该为一个字典,json 时应该为一个 json 字符串

前记

19 年的时候准备用群晖来做软路由,由于双网卡配置失败遂放弃

在群晖上利用 Virtual Machine Manager 玩转软路由之 LEDE

因为把 AC86UAC66UB1 都刷回了官方固件 386,所以就需要一个旁路由。既然单网卡的群晖做不了软路由,那就用来做旁路有吧

LEDE

镜像

K 站下载硬盘镜像后上传至 VMM

镜像下载地址:koolcenter.com

找到名为 openwrt-koolshare-mod-v2.36-r14941-67f6fa0a30-x86-64-generic-squashfs-combined.vmdk 的虚拟机磁盘,下载后上传至 VMM

网络

网络这里我们直接使用 Default VM Network 即可

开机

导入虚拟机

通过之前下载的虚拟机磁盘导入虚拟机


配置网络

其他配置

开机

修改 IP

通过 VMM -> 虚拟机 -> 连接进入虚拟机

通过命令 vi /etc/config/network 来修改网络 IP 地址

最后通过命令 /etc/init.d/network restart 来重启网络,或则 reboot 重启虚拟机

配置

关于 LEDE 的配置可以看看下面这篇文章

LEDE 配置

最后需要在路由器上修改路由器的网关和 DNS

到这里 LEDE 旁路由的配置就完成了