Zipfile

创建 zip 文件

demo

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
import zipfile
from pathlib import Path

with zipfile.ZipFile('/mnt/e/Downloads/hello.zip', 'w') as zfile:
    # zfile.writestr('/path/to/zip/insidefile.txt', "content_str_or_bytes")
    zfile.writestr('folder/age.txt', "12") # 写入 str 类型
    zfile.writestr('raw', "好天气".encode()) # 写入 bytes 类型
    zfile.writestr('demo/qq.exe', Path('/mnt/e/Downloads/qq.exe').read_bytes())

    # 直接写入文件,不需要通过 open 读入内存再写入zip
    zipfile.write("/file/on/disk.txt", "path/in/zipfile/name.txt")

遍历 zip 文件

使用 ZipFile.infolist()

使用 ZipFile.namelist()

1
2
3
4
In [22]: with zipfile.ZipFile('/mnt/e/Downloads/hello.zip', 'r') as zread:
    ...:     print(zread.filelist)
    ...:
[<ZipInfo filename='folder/age.txt' filemode='?rw-------' file_size=2>, <ZipInfo filename='raw' filemode='?rw-------' file_size=9>, <ZipInfo filename='demo/qq.exe' filemode='?rw-------' file_size=183394032>]

使用 ZipFile.filelist 属性

1
2
3
4
In [24]: with zipfile.ZipFile('/mnt/e/Downloads/hello.zip', 'r') as zread:
    ...:     print(zread.namelist())
    ...:
['folder/age.txt', 'raw', 'demo/qq.exe']

使用 zipfile.Path 类 (类似 pathlib.Path)

1
2
3
4
5
In [25]: list(zipfile.Path('/mnt/e/Downloads/hello.zip', at='/').iterdir())
Out[25]:
[Path('/mnt/e/Downloads/hello.zip', 'raw'),
 Path('/mnt/e/Downloads/hello.zip', 'folder/'),
 Path('/mnt/e/Downloads/hello.zip', 'demo/')]

递归遍历:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
from pathlib import Path

import zipfile

def zipiter_recursive(filename: Path|str):
    if isinstance(filename, (Path, str)):
        zip_file = Path(filename)
        assert zip_file.suffix.lower() == ".zip"
        iter_path = zipfile.Path(zip_file)

    elif isinstance(filename, zipfile.Path):
        iter_path = filename
    else:
        raise TypeError(f'not a valid zip file {filename = }')

    for i in iter_path.iterdir():
        if i.is_dir():
            yield from zipiter_recursive(i)
        else:
            yield i

使用例子:

Wireguard

相关软件

tailscale

替代的开源 server headscale

FAQ

wireguard + archlinux 安装方法

注意:

Frp

三方 frp 服务供应商

http nat 穿透反向代理和 ssh nat 穿透代理例子

实现功能:

  1. 允许通过子域名(subDomainHost)访问内网 http 服务
  2. 通过 16000 端口代理内网 ssh 服务

frps.toml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
bindPort = 17000
vhostHTTPPort = 18080
vhostHTTPSPort = 10443
subDomainHost = "frp.mydomain.com" # 注意:需要创建一个 *.frp.mydomain.com 指向 frp server 所在机器的DNS记录

serverPort = 7000

# #鉴权使用的 token 值,需要和内网客户端端设置一样的值才能鉴权通过
[auth]
method = "token"
token = "mytoken1133"

frpc.toml

 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
serverAddr = "host-server.com"
serverPort = 17000
# 可选,是否使用 kcp 协议(底层使用UDP)
transport.protocol = "kcp"

[auth]
method = "token"
token = "mytoken1133"

# http 服务,域名映射
[[proxies]]
name = "web"
type = "http"
# 本地服务地址,localIP 设置可选(默认127.0.0.1)
localIP = "127.0.0.1"
localPort = 80
#customDomains = ["file.otherCustomDomain.site"]
subdomain = "file"              # 相当于:file.mydomain.com:18080

# 登录验证,可选配置
httpUser = "the-user"
httpPassword = "the-password"


# ssh, tcp 端口映射
[[proxies]]
name = "wsl-ssh"
type = "tcp"
localPort = 22
RemotePort = 16000              # 相当于:ssh user@host-server.com -p 1600

stcp 类型 ,安全的 tcp 穿透代理

作用: