分类: IT记事本

  • docker一键部署Aria2 Pro+Aria2 Ng

    如果你遇到Red Hat如下问题,可以尝试使用docker运行Aria2

    无法读取客户身份 本系统尚未在权利服务器中注册。可使用 “rhc” 或 “subscription-manager” 进行注册。

    # subscription-manager register 注册到:subscription.rhsm.redhat.com:443/subscription 用户名: xxxx 密码: xxx 无法注册到任何机构。

    使用 Docker Compose 部署

    Alist 有官方的 Docker 镜像部署文档。但我更倾向于使用 Docker Compose 来管理部署,这样可以将它和Aria2 Pro或其他应用一起部署。

    前置工作

    编写 docker-compose.yml

    • 创建一个部署工程文件夹,并编写一个docker-compose.yml文件,并参environmentvolumes节点中照注释(#)进行配置。
    • ${PWD}指代当前目录,默认配置会将程序产生的数据保存在这个文件中,如果你想将数据保存在其他位置,可以修改volumes配置(:号前为主机上的目录,后为容器内的目录)。

    内容如下:

    version: "3.8"
    
    services:
    
      # Aria2 Pro 的官方部署文档: https://github.com/P3TERX/Aria2-Pro-Docker/blob/master/docker-compose.yml
      Aria2-Pro:
        container_name: aria2-pro
        image: p3terx/aria2-pro
        environment:
          - PUID=65534
          - PGID=65534
          - UMASK_SET=022
          - RPC_SECRET=123456 # 配置Aria2 的 RPC secret 密钥,它将被用于 Alist 和 AriaNg 连接 Aria2,默认123456
          - RPC_PORT=6800
          - LISTEN_PORT=6888
          - DISK_CACHE=64M
          - IPV6_MODE=false
          - UPDATE_TRACKERS=true
          - CUSTOM_TRACKER_URL=
          - TZ=Asia/Shanghai
        volumes:
          - ${PWD}/aria2/config:/config
          - ${PWD}/aria2/downloads:/downloads # 在:号前配置你要在主机上保存下载文件的路径
        ports:
          - "6800:6800"
          - "6888:6888"
          - "6888:6888/udp"
        restart: unless-stopped
        logging:
          driver: json-file
          options:
            max-size: 1m
    
      # Aria2 的 Web UI
      AriaNg:
        container_name: ariang
        image: p3terx/ariang
        command: --port 6880 --ipv6
        ports:
          - "6880:6880"
        restart: unless-stopped
        logging:
          driver: json-file
          options:
            max-size: 1m
    

    部署并启动

    • 在部署工程文件夹中,执行docker-compose up -d命令,就能完成部署了。
    • 程序成功部署完毕 🥳
  • dify对接textin实现 图片/pdf/excl的提取内容并转换为markwodn/excl输出

    将http节点返回的内容如

    {
      "status_code": 200,
      "body": "{\"x_request_id\":\"5d54bffb67988fff2f59e055a3b54ea1\",\"duration\":137,\"message\":\"Success\",\"result\":{\"markdown\":\"[\\/www\\/wwwroot\\/tz.ncncy.com】\\n\\n\",\"success_count\":1,\"pages\":[{\"angle\":0,\"page_id\":1,\"content\":[{\"pos\":[3,8,223,8,223,29,3,29],\"id\":0,\"score\":0.98100000619888,\"type\":\"line\",\"text\":\"[\\/www\\/wwwroot\\/tz.ncncy.com】\"}],\"status\":\"Success\",\"height\":35,\"structured\":[{\"pos\":[3,11,223,11,223,25,3,25],\"type\":\"textblock\",\"id\":0,\"content\":[0],\"text\":\"[\\/www\\/wwwroot\\/tz.ncncy.com】\",\"outline_level\":-1,\"sub_type\":\"text\"}],\"durations\":117.35350799561,\"image_id\":\"\",\"width\":225}],\"valid_page_number\":1,\"total_page_number\":1,\"total_count\":1,\"detail\":[{\"paragraph_id\":0,\"page_id\":1,\"tags\":[],\"outline_level\":-1,\"text\":\"[\\/www\\/wwwroot\\/tz.ncncy.com】\",\"type\":\"paragraph\",\"position\":[3,11,223,11,223,25,3,25],\"content\":0,\"sub_type\":\"text\"}]},\"metrics\":[{\"angle\":0,\"page_id\":1,\"status\":\"Success\",\"duration\":135.72903442383,\"page_image_width\":225,\"page_image_height\":35}],\"code\":200,\"version\":\"3.15.13\"}",
      "headers": {
        "date": "Mon, 28 Apr 2025 03:11:58 GMT",
        "content-type": "application/json;charset=utf-8",
        "content-length": "1002",
        "connection": "keep-alive",
        "access-control-max-age": "86400",
        "access-control-allow-origin": "*",
        "access-control-allow-headers": "Content-Type,token,No-Cache,Pragma,Cache-Control,X-Requested-With,x-ti-app-id,x-ti-secret-code",
        "access-control-expose-headers": "X-Request-Id",
        "server": "Intsig Web Server",
        "strict-transport-security": "max-age=3600; includeSubDomains; preload",
        "x-request-id": "5d54bffb67988fff2f59e055a3b54ea1"
      },
      "files": []
    }

    得到的是一个”body”中含\”markdown\”的格式,我们使用代码节点提取markdown内容

    import json
    
    def main(arg1: str) -> dict:
        # 将arg1(JSON字符串)解析为字典
        data = json.loads(arg1)
        
        # 提取result部分的markdown字段
        markdown_content = data.get("result", {}).get("markdown", "")
        
        # 返回提取的markdown内容
        return {
            "result": markdown_content,
        }

    再使用markdown转文件节点得到你需要的内容格式

  • dify中如何将LLM节点输出的内容(自然语言+MD表格+自然语言)中的MD表格提取出来并渲染成表格

    import re
    
    def main(text: str) -> dict:
        pattern = r'\|.*\|\n\|.*\|\n(\|.*\|\n)*'
        matches = re.findall(pattern, text)
        if matches:
            table = matches[0].strip()
            rows = [row.strip() for row in table.split('\n')]
            headers = [h.strip() for h in rows[0].split('|')[1:-1]]
            data = []
            for row in rows[2:]:
                cells = [c.strip() for c in row.split('|')[1:-1]]
                data.append(dict(zip(headers, cells)))
            return {'result': data}
        return {'result': []}
  • 使用代码转换节点将dify的http请求节点返回的body体将Unicode编码转换为中文字符

    (如 ‘\u672a\u53d1\u73b0\u6f0f\u6c34\u6765\u6e90’)的输入参数转换成实际的中文字符:(’未发现漏水来源’)

    import json
    
    def main(arg1: str) -> dict:
        # 将Unicode编码转换为中文字符
        decoded_arg1 = bytes(arg1, 'utf-8').decode('unicode_escape')
    
        return {
            "result": decoded_arg1,
        }
  • 将电脑端微信dat文件转jpg图片,并保留原有图片时间

    import os
    import time
    import win32file
    import win32con
    import pywintypes
    
    def detect_key(dat_content):
        """
        通过分析文件内容自动检测密钥
        """
        # 常见的图片文件头
        common_headers = {
            b'\xFF\xD8': 'jpg',  # JPEG 文件头
            b'\x89\x50': 'png',  # PNG 文件头
            b'\x47\x49': 'gif',  # GIF 文件头
            b'\x42\x4D': 'bmp',  # BMP 文件头
        }
    
        for key in range(256):  # 尝试所有可能的密钥 (0-255)
            decrypted_data = bytes([byte ^ key for byte in dat_content[:2]])  # 只解密前两个字节
            for header, format_name in common_headers.items():
                if decrypted_data.startswith(header):
                    return key, format_name
        return None, None
    
    def set_file_creation_time(file_path, creation_time):
        """
        使用 pywin32 设置文件的创建时间
        """
        # 将时间戳转换为 pywintypes 时间对象
        win_time = pywintypes.Time(creation_time)
    
        # 打开文件句柄
        handle = win32file.CreateFile(
            file_path,
            win32con.GENERIC_WRITE,
            0,
            None,
            win32con.OPEN_EXISTING,
            0,
            None
        )
        # 设置文件的创建时间
        win32file.SetFileTime(handle, win_time, None, None)
        win32file.CloseHandle(handle)
    
    def decode_wechat_image(dat_file, output_folder):
        if not os.path.exists(output_folder):
            os.makedirs(output_folder)
    
        # 获取原文件的创建时间
        creation_time = os.path.getctime(dat_file)
    
        with open(dat_file, 'rb') as f:
            dat_content = f.read()
    
        # 获取文件名的前缀
        file_name = os.path.basename(dat_file).split('.')[0]
    
        # 自动检测密钥
        key, image_format = detect_key(dat_content)
        if key is None:
            print(f"无法检测到密钥或识别图片格式: {dat_file}")
            return
    
        # 解密并保存图片
        decrypted_data = bytes([byte ^ key for byte in dat_content])
        output_file = os.path.join(output_folder, f"{file_name}.{image_format}")
        with open(output_file, 'wb') as f:
            f.write(decrypted_data)
    
        # 设置新文件的创建时间为原文件的创建时间
        set_file_creation_time(output_file, creation_time)
    
        print(f"图片已保存到: {output_file} (创建时间已保留)")
    
    def batch_decode_wechat_images(input_folder, output_folder):
        for root, dirs, files in os.walk(input_folder):
            for file in files:
                if file.endswith('.dat'):
                    dat_file = os.path.join(root, file)
                    decode_wechat_image(dat_file, output_folder)
    
    if __name__ == "__main__":
        input_folder = r'C:\Users\yangy\Documents\WeChat Files\wxid_4ipvtcu7uzyk12\FileStorage\MsgAttach\454fe72042640d5aaed6d8b2aa470459\Thumb\2025-03'
        output_folder = r'E:\微信捕捉\weixin捕捉\jiemi\图片2'
    
        batch_decode_wechat_images(input_folder, output_folder)
    更改input和output地址为自己电脑的地址
  • \+ipv6地址就能访问共享文件夹了吗?结果是我想的太简单了? 使用ipv6实现smb共享文件夹

    需求描述

    兄弟们,这两天不是和兄弟们分享一下,关于ipv6的一些基本知识吗?前两篇都是分享关于ipv6的。

    什么ipv6地址还不是很熟,看完这篇文章,你就知道什么是ipv6了?

    ipv6中的EUI-64是什么意思?之前我看了也不懂,但是这次我明白了!

    但是对于ipv6基本知识,学起来的确是有点枯燥,那今天就带着兄弟们来实战一下,对于ipv6地址和本地链接ipv6地址,大家也都知道是什么意思了。那今天,我们就通过ipv6来访问一下共享,看一下,在局域网里面,如何通过ipv6地址访问共享文件夹。

    但是我测试之后,我发现的确没有那么简单,然后做了个总结给兄弟们,避免兄弟们以后踩坑,刚开始的时候,我也以为很简单,和ipv4访问一样,两个\然后+一个ipv6地址就可以正常访问了?结果真的不是那么回事?

    解决过程
    首先,要想使用ipv6地址访问共享,那先要学会ipv6地址和本地链接ipv6地址都是怎么来的,ipv6地址如何在路由器中配置的,如果不会的兄弟,可以参考前两篇文章。
    下面这台主机就是共享文件夹主机,可以看到,ipv6地址和本地链接ipv6地址,两个地址都有。
    可以看到,这台电脑中在D盘共享了一个名称为:”100、share”这个共享文件夹。
    下面这台电脑是客户端,要访问上面那台ipv6主机中的共享文件夹的。兄弟们搬好小板凳,我们的测试即将开始。首先将,共享文件夹主机的ipv6的缩写,还原一下。

    ipv6:240e:03a2:1598:8120:0000:0000:0000:0041

    本地链接ipv6:fe80:0000:0000:0000:1c86:2d0d:d8d9:21eb

    那ipv6地址还原好之后,先使用客户端去ping 共享电脑的ipv6地址,发现全球通用ipv6和本地链接ipv6地址都是可以ping通的。这一步还挺顺利的,如果ping不通,就是共享文件夹的那台主机的防火墙关掉。
    这个是客户端的ipv6地址和本地链接ipv6地址。
    那我在客户端电脑上,直接\+ipv6地址,然后确定。和ipv4一样的输入格式。
    但是确定之后,报错,错误代码:0x80070043,找不到网络名。
    难道是全球通用ipv6地址有问题,那就再测试一下,本地链接ipv6地址。\+本地链接ipv6地址。
    然后,点击确定,发现一样的报错,难道共享文件夹,不能通过ipv6访问,不应该呀?
    这时我先测试一下ipv4地址,可以看到ipv4地址访问是没有问题的。
    那我就使用telnet测试一下,这ipv6到底是否可以访问共享文件夹中的文件,telnet+ipv6地址,然后再+共享文件端口445。
    在客户端上,使用这个命令,发现,客户端电脑是可以正常访问到共享文件夹主机的445共享端口的,没有问题的。
    然后再到共享电脑主机上,使用netstat -an ,可以看到,已经通过ipv6地址和客户端的ipv6地址建立了连接。
    那我再在客户端电脑上,测试一下,本地链接ipv6地址是否也可以访问到共享主机的445端口。
    我发现客户端电脑,也是可以通过本地链接ipv6地址访问到共享主机的445端口的。
    到回到共享主机电脑,再使用netstat -an,可以看到,客户端的本地链接ipv6地址和共享主机的ipv6地址也已经成功建立链接了。看最后的established,这个英文就是确定,表示已建立连接。
    难道是共享主机上,有什么限制,导致客户端电脑访问共享主机有问题的,那我就测试一下,在共享主机电脑访问,通过ipv6地址访问自己是否可以成功。
    当回到共享主机的电脑,直接通过自己的ipv6地址访问自己,我发现都报错,也是报0x80070035错误。
    使用本地链接地址访问,也是报同样的错误,那这到底是什么问题呢?看下图,有一个问题要注意,就是访问本地链接ipv6地址时,后面的%7是否需要加上,这个问题,继续往下看,后面有答案。
    难道是因为我把ipv6地址还原导致的这个问题吗?
    可以看一下,当我在客户端ping共享主机的ipv6地址时,不需要换算成全的ipv6地址也是可以正常ping通的。ping ipv6地址也是不用补全,也是可以直接ping的,缺省的0不需要我们换算回来,直接默认就缺省就可以。
    难道通过ipv6地址访问共享文件夹,不能像ipv4一样,直接通过ip地址直接访问。
    测试一:加中括号
    那这时我又查了一下资料,有的人说,将ipv6地址使用中括号括起来就可以了,于是我按了这个方法测试了一下。

    使用 \[IPv6地址]共享名 格式,IPv6地址需用方括号包裹,确保地址为全球通 IPv6(非本地链路地址),且不带接口标识符。

    \[2001:db8::1]share

    若使用本地链路地址(如 fe80::1),需附加接口标识符(如  %5),这里要注意,使用本地链接ipv6地址,访问共享文件夹,需要加上接口标识,我们继续往下测试。

    \[fe80::1%5]share
    于是,使用中括号括起来,再测试一下,我还是先在共享文件夹主机上,先测试。
    使用中中括号括起来,把接口标识符的%7也加进去。
    无论加不加接口标识的%7,访问时都还是报错。看来和有没有中括号没有关系。
    那再查,再测试。
    测试二,转义字符将“:”转换成“-”,突然看到了,转义特殊字符的 UNC 路径

    如果地址中包含特殊符号( :),用短横线(-)代替。

    案例:如下所示:\[fe80::abcd-1234%5]share,因为给的案例是双冒号不需要替换。

    于是,我又在共享主机电脑上测试。

    发现还是报0x80070035错误 。
    使用全球通用ipv6访问自己,也是一样的报错。
    但是我最后把双冒号也都替换了,也还是不行。
    测试三:将所有”:”都需要更改为”-“,然后还需要在ipv6地址末尾加上.ipv6-literal.net后缀。
    没有转换前的ipv6地址和本地链接ipv6地址。
    我们来把它转换一下,当有两个::时,使用两个横杆代替–。下面是转换后的ipv6地址。
    ipv6地址:240e-3a2-1598-8120–41.ipv6-literal.net

    本地链接ipv6地址:fe80–1c86-2d0d-d8d9-21eb.ipv6-literal.net

    还是先在共享主机测试本地访问。先测试ipv6地址。

    输入完用户名和密码,即可访问。
    当我使用本地链接ipv6地址访问时,可以看到,也可以正常跳出来输入用户名和密码框,但是无论输入什么用户名和密码都无报用户名和密码不正确,但是我输入的用户名和密码是正确的。
    后来我又仔细的看了一下,说当使用本地链接ipv6访问时,需要加上接口标识
    本地链路地址(如 fe80:: 开头)必须附加接口索引(如 %5),否则无法解析。
    把接口标识也加上去。
    接口标识,就是这个网卡在系统中的一个编号。
    当在本地链接ipv6上加上接口标识后,再次输入用户名和密码就可以正常访问共享了,但是这些都是在共享主机上测试的。
    下面我们再换到个客户端电脑上,通过ipv6地址,来访问这台共享主机的共享文件夹
    首先在客户端电脑上,先使用ipv6地址访问:
    \240e-3a2-1598-8120–41.ipv6-literal.net

    访问后输入用户名和密码,可以看到客户端电脑现在终于,可以通过ipv6访问到共享文件主机了。

    当我再使用本地链接ipv6测试时,发现又出问题了。
    \fe80–1c86-2d0d-d8d9-21eb%7.ipv6-literal.net
    又报找不到网络名。
    于是我在客户端访问的时候,把%7去掉。
    去掉之后,结果客户商就可使用共享主机的,本地链接ipv6地址访问到共享文件夹了,输入完用户名和密码就可以正常访问到共享文件夹了。兄弟们,你们说奇怪不奇怪?
    总结:

    1、什么是UNC 路径?

    Windows 的 UNC(通用命名规则)路径格式为 \主机名共享名,其设计初衷是为 IPv4 和主机名服务。

    IPv6 地址中包含冒号 :,而冒号在 UNC 路径中被保留为特殊字符,可能导致解析冲突(例如,系统误将冒号后的内容视为端口号或子路径)。可以看到C盘后面就是:冒号,代表盘符路径。
    2、为什么要把“:”换成“-”?

    UNC 路径的兼容性问题

    Windows 的 UNC 路径(如 \servershare)最初设计用于主机名或 IPv4 地址(如 \192.168.1.1share)。

    IPv6 地址包含冒号 : 和可能的压缩格式(如 ::),而冒号在 UNC 路径中是保留字符,直接使用会导致解析歧义,导致系统无法分辨。

    3、IPV6后面的,.ipv6-literal.net是什么意思? 这个是域名伪装机制。

    .ipv6-literal.net 是一个伪域名后缀,本身没有实际的 DNS 记录。

    Windows 系统内部会识别这个后缀,并自动将其前缀部分(如 2001-db8--1)转换回原始的 IPv6 地址(如 2001:db8::1)。

    例如:
    \2001-db8--1.ipv6-literal.netshare → 解析为 2001:db8::1

    纠正:SMB端口号 445

     

  • 不要安装那么多插件了,一个LSP搞定CAD字体缺少问题!

    蓝字关注,跟周站长学CAD!

    站长推荐:

    各类设计软件学习视频教程,涵盖机械建筑室内平面等,如:AutoCAD、UG NX、Creo、Solidworks、Inventor、Rhino、Keyshot、3dmax、SketchUp、Revit、天正、酷家乐、PS、CDR等,想学习的点此:点我学习 

    站长编写的CAD图书,从用户视角结合十几年CAD经验编写而成,推荐给CAD初学者、系统学习者,也可作为老手查询工具书。此链接购买可额外获得重磅福利点此查看。最近在做图书笔记分享,需要点击查看,可订阅。

    前面站长分享了很多字体自动替换的方法,比如源泉设计、谜你工具、赫思CAD等等,以上都是综合性插件,对AutoCAD、中望CAD、浩辰CAD支持情况都不一样,有粉丝问,周站长有没有单独批量替换字体的插件?能够适应上面软件的呢,今天分享这个lsp适合所有CAD软件所有版本。

    首先下载CAD字体批量替换插件,链接:https://pan.baidu.com/s/1NV2TlgjaVpju9zYQnGy-8w

    提取码:10wc

    解压密码:www.cadzxw.com

    解压下载的插件;

    打开图纸;

    提示缺失字体,直接忽略;

    正常情况下可能看不到文字;

    输入AP快捷键;

    找到插件,加载;

    即可自动将空字体或缺失字体自动替换;

    也可以输入快捷键zzz;

    进行自定义替换,默认情况下按1空字替换;

    比如我们选择4国标字体;

    那所有的文字样式中的字体都会被换成gbenor和gbcbig;

    注:也可以ap内容里永久加载插件,这样以后只要缺字体会自动空字替换。

  • openwrt 开启IPV6防火墙实现转发访问内网服务器

    设置防火墙

    打开OpenWRT-网络-防火墙-通信规则,拉到下面,新增:

    • 常规设置
      • 名称随便写
      • 协议选TCPUDPICMP(或者根据实际情况写,不需要的可以不选)
      • 源区域选WAN口
      • 源地址指定的是访问者的地址,如果需要就指定,不需要则留空
      • 源端口指定的是访问者访问目标地址的端口,如果需要就指定,不需要则留空
      • 目标区域:
        如果是以路由器本机作为暴露对象,则选择“设备(输入)”
        如果是以下面挂接设备作为暴露对象,则选择设备所在LAN口(推荐)
      • 目标地址看下面解释,设备多建议留空
      • 目标端口根据实际情况写,就是要暴露出去的端口,设备多端口多建议留空,则为放开全部V6端口
      • 操作选接受
    • 高级设置
      • 限制地址类型:IPv6
    • 保存-保存并应用
      借鉴别人的文章没有哦,生气了吗? | OpenWRT IPv6 防火墙设置 | 泠泫凝的异次元空间
  • 申请永久免费的域名!可托管至Cloudflare,无限免费续期!US.KG

    650bbc977520241206152319

    1、首选你需要准备一个海外的虚拟身份信息 【点击获取

    进入以后,可以自由获取一个虚拟的海外身份信息,比如地址、电话号码等,一会要用到

    2、在 US.KG 官网查看可免费注册的域名【链接直达

    3、准备好一个Github账号,如果没有的话可以自行免费注册一个【点击前往 】

    4、最后托管在 Cloudflare 域名管理平台就可以免费使用了,域名虽然是1年有效期,但是在到期前180天去免费续期下,就可以一直永久免费使用!

    c4699c5e3220241206151900

    具体的注册教程,看下面这个视频:

    https://www.bilibili.com/video/BV1AjiBYVEoF/?spm_id_from=333.337.search-card.all.click