-
我给写博客的自己「顺手」写了个封面小工具,真·1 分钟出图
01|写博客 5 分钟,做封面 15 分钟?我忍够了 以前常用 coverview,后来 Vercel 抽风,国内打不开了;醒图、美图秀秀等APP来回导有点割裂,手机→电脑→公众号后台。于是,我干脆自己写了一个「在线文章封面生成器」——纯粹为了让自己少点抓狂。 02|它到底能干啥? 一句话:把“做图”缩成“填表” 左边填字、选图、挑颜色,右边实时出图,所见即所得 主标题+副标题,字体、字号、颜色、九格位置全独立,想怎么歪就怎么歪 画布比例一键切:16:9、4:3、1:1、3:4,公众号头图、知乎封面、小红薯方图全覆盖 背景想偷懒?直接搜 Unsplash 关键词,10 万张高清图免版权;想个性?本地上传,纯色渐变随心情 图标 10w+ 矢量在线选,大小、颜色、位置随便拖,SVG 放大不虚 导出 PNG/JPG/WEBP 三格式,圆角 0-50 px 可调, retina 也能hold住 03|我最在意的隐私:图片不上传,处理全在本地 所有上传、渲染都在浏览器完成,0 服务器交互,公司电脑也能放心用,图只在你的硬盘里留下痕迹。 04|界面丑吗?目前确实“程序员审美” 双栏布局,左边功能,右边预览,主打一个能用。UI后期会随心情翻新,先把功能先实现。桌面端优先,移动端无法使用——毕竟写博客,我从来没想过在手机上实现。 05|开源吗? 代码简单到羞于公开,纯原生,一个 html 丢到 gh-pages 就能跑。 06|地址 & 小彩蛋浏览器直接戳 → https://cover.apicdo.top/ 后续的一些计划(看心情实现) 目前已知的问题:Unsplash 毕竟国内体验较差,打开比较慢,有些时候点了背景没有反应。(但国内没看到有平替的免费接口……) 🎨 设计增强 3D效果: 支持3D文字和图形效果 粒子系统: 添加粒子背景效果 滤镜系统: 提供多种图像滤镜 形状工具: 支持基础几何图形绘制 2026年6月7日更新: 时代变了,使用了Node重构了整个项目。... -
阻止搜索引擎和恶意蜘蛛爬虫访问
现在大部分网站都使用 CDN 进行加速,建议直接在 CDN 设置 User-Agent 黑名单 阿里云全站加速 DCDN 设置方法如图所示,填入 User-Agent: *dotbot*|*CensysInspect*|*MegaIndex*|*MegaIndex.ru*|*BLEXBot*|*Qwantify*|*qwantify*|*semrush*|*Semrush*|*serpstatbot*|*hubspot*|*python*|*Bytespider*|*Go-http-client*|*Java*|*PhantomJS*|*SemrushBot*|*Scrapy*|*Webdup*|*AcoonBot*|*AhrefsBot*|*Ezooms*|*EdisterBot*|*EC2LinkFinder*|*jikespider*|*Purebot*|*MJ12bot*|*WangIDSpider*|*WBSearchBot*|*Wotbox*|*xbfMozilla*|*Yottaa*|*YandexBot*|*Jorgee*|*SWEBot*|*spbot*|*TurnitinBot-Agent*|*mail.RU*|*Perl*|*Python*|*Wget*|*Xenu*|*ZmEu* Cloudflare 设置方法如图,若使用表达式生成器手动一个个添加将耗费太多时间,直接编辑表达式填入如下表达式即可 (http.user_agent contains "Go-http-client") or (http.user_agent contains "CensysInspect") or (http.user_agent contains "MegaIndex.ru") or (http.user_agent contains "BLEXBot") or (http.user_agent contains "Qwantify") or (http.user_agent contains "qwantify") or (http.user_agent contains "semrush") or (http.user_agent contains "Semrush") or (http.user_agent contains "serpstatbot") or (http.user_agent contains "hubspot") or (http.user_agent contains "python") or (http.user_agent contains "Bytespider") or (http.user_agent contains "Go-http-client") or (http.user_agent contains "Java") or (http.user_agent contains "PhantomJS") or (http.user_agent contains "SemrushBot") or (http.user_agent contains "Scrapy") or (http.user_agent contains "Webdup") or (http.user_agent contains "AcoonBot") or (http.user_agent contains "AhrefsBot") or (http.user_agent contains "Ezooms") or (http.user_agent contains "EdisterBot") or (http.user_agent contains "EC2LinkFinder") or (http.user_agent contains "jikespider") or (http.user_agent contains "Purebot") or (http.user_agent contains "MJ12bot") or (http.user_agent contains "WangIDSpider") or (http.user_agent contains "WBSearchBot") or (http.user_agent contains "Wotbox") or (http.user_agent contains "xbfMozilla") or (http.user_agent contains "Yottaa") or (http.user_agent contains "YandexBot") or (http.user_agent contains "Jorgee") or (http.user_agent contains "SWEBot") or (http.user_agent contains "spbot") or (http.user_agent contains "TurnitinBot-Agent") or (http.user_agent contains "mail.RU") or (http.user_agent contains "perl") or (http.user_agent contains "Python") or (http.user_agent contains "Wget") or (http.user_agent contains "Xenu") or (http.user_agent contains "ZmEu") 在 Nginx 配置代码如下: if ($http_user_agent ~ "MegaIndex|MegaIndex.ru|BLEXBot|Qwantify|qwantify|semrush|Semrush|serpstatbot|hubspot|python|Bytespider|Go-http-client|Java|PhantomJS|SemrushBot|Scrapy|Webdup|AcoonBot|AhrefsBot|Ezooms|EdisterBot|EC2LinkFinder|jikespider|Purebot|MJ12bot|WangIDSpider|WBSearchBot|Wotbox|xbfMozilla|Yottaa|YandexBot|Jorgee|SWEBot|spbot|TurnitinBot-Agent|mail.RU|perl|Python|Wget|Xenu|ZmEu|^$" ) { return 444; }... -
用EdgeOne加速CloudflareR2存储桶
加速前 加速后 开始操作 打开 EdgeOne,选择添加域名 把源站配置的IP/域名改为对象存储源站,后面的S3 兼容不用改,接着打开 Cloudflare 的 r2 存储桶 找到 设置,复制这一串 S3 API 复制下来应该是 https://aaaa.r2.cloudflarestoreage.com/bbbb这种格式的 你需要改成 bbbb.aaaa.r2.cloudflarestoreage.com 填到源站地址中 打开私有访问授权,鉴权选择v4,地域填auto 打开 r2 api(见下图) 创建一个 api,权限选择对象只读,生成之后显示这样 访问密钥ID 填到 Access Key ID,机密访问密钥填到 Secret Access Key 中,最后填完了长这样。 然后就可以了。... -
宝塔面板,左侧菜单乱码
解决方案:进入文件夹 /www/server/panel/config,删除 local_menu.json(或者将local_menu.json重命名)。进入浏览器,刷新面板所在的网页,发现左侧菜单乱码的问题解决了,另外,你会发现local_menu.json的修改时间更新了。... -
wordpress的每日60秒一堆不靠谱的
刚刚去下载了一个发现各种报错,而且拿回来的图片1MB多,对带宽小的服务器来说是致命打击。 接口就不提供了,自己找一找吧,这个网上很多免费的。 发现有个bug,直接往 $wpdb->posts 写记录,绕过了 WordPress 的发布流程,因此 没有触发 wp_insert_post() 等钩子 会导致明明发布了却显示404 重新改了一下: <?php /** * 获取每天60秒读懂世界的内容并发布到WordPress * 修复了数组访问和文件处理的错误 */ // 获取API数据 $content = curl_get('API接口'); // 调试:输出原始返回内容 if ($content === false) { die('cURL请求失败,无法获取API数据'); } // 调试:检查返回内容 if (empty($content)) { die('API返回内容为空'); } $data = json_decode($content, true); // 调试:检查JSON解析 if (json_last_error() !== JSON_ERROR_NONE) { die('JSON解析失败: ' . json_last_error_msg() . ',原始内容: ' . substr($content, 0, 500)); } // 检查数据是否有效 if (!$data || !is_array($data)) { die('API返回数据格式无效,原始内容: ' . substr($content, 0, 500)); } // 检查是否有必要的字段 if (!isset($data['code'])) { die('API返回数据格式错误:缺少code字段'); } // 调试:输出code值和类型 // echo 'API返回的code值: ' . $data['code'] . ',类型: ' . gettype($data['code']) . '<br>'; // 检查API返回状态 if ($data['code'] !== 200 && $data['code'] !== '200') { // API返回错误或数据未更新 echo 'API返回错误或数据未更新,状态码:' . $data['code']; if (isset($data['msg'])) { echo ',错误信息:' . $data['msg']; } } else { // 验证必要字段是否存在 if (!isset($data['image']) || !isset($data['title']) || !isset($data['data'])) { die('API返回数据格式错误:缺少必要字段'); } $head_img = $data['image']; // 检查图片URL是否有效 if (empty($head_img) || !filter_var($head_img, FILTER_VALIDATE_URL)) { die('图片URL无效'); } $ext = pathinfo($head_img, PATHINFO_EXTENSION); // 如果无法获取扩展名,使用默认扩展名 if (empty($ext)) { $ext = 'jpg'; } $rand_name = date("Ymd") . '.' . $ext; if (is_dir('60s') == false) { mkdir('60s', 0777, true); } // 获取图片内容并检查是否成功 $image_content = file_get_contents($head_img); if ($image_content === false) { die('无法下载图片'); } // 压缩图片以减少文件大小和带宽消耗 $compressed_image = compress_image($image_content, $ext); if ($compressed_image…... -
吾今有世家存档修改器 Python版本
内容已失效,年代久远,后续没再继续玩了。 #!/usr/bin/env python3 # -*- coding: utf-8 -*- """ 吾今有世家游戏存档修改器 用于修改GameData.es3文件中的游戏数据 作者: SnowZ 版本: 2.3.1 日期: 2025 """ import json import tkinter as tk from tkinter import ttk, filedialog, messagebox, scrolledtext import os import shutil from datetime import datetime class SaveEditor: """ 游戏存档修改器主类 提供图形界面来修改ES3格式的存档文件 """ def __init__(self): """ 初始化修改器界面和数据 """ self.root = tk.Tk() self.root.title("吾今有世家 - 游戏存档修改器 v2.3.1") self.root.geometry("1200x800") self.root.resizable(True, True) # 存档数据 self.game_data = None self.save_file_path = "" # 创建界面 self.create_widgets() # 尝试自动加载当前目录的GameData.es3 default_save = os.path.join(os.getcwd(), "GameData.es3") if os.path.exists(default_save): self.load_save_file(default_save) def create_widgets(self): """ 创建主界面组件 """ # 创建菜单栏 self.create_menu() # 创建主框架 main_frame = ttk.Frame(self.root) main_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=5) # 创建选项卡控件 self.notebook = ttk.Notebook(main_frame) self.notebook.pack(fill=tk.BOTH, expand=True) # 创建各个功能选项卡 self.create_character_tab() # 人物信息 self.create_family_tab() # 家族信息 self.create_noble_tab() # 世家信息 self.create_fief_tab() # 封地信息 self.create_military_tab() # 军事信息 self.create_economy_tab() # 经济信息 self.create_raw_data_tab() # 原始数据 # 状态栏 self.status_var = tk.StringVar() self.status_var.set("就绪 - 请加载存档文件") status_bar = ttk.Label(main_frame, textvariable=self.status_var, relief=tk.SUNKEN) status_bar.pack(side=tk.BOTTOM, fill=tk.X, pady=(5, 0)) def create_menu(self): """ 创建菜单栏 """ menubar = tk.Menu(self.root) self.root.config(menu=menubar) # 文件菜单 file_menu = tk.Menu(menubar, tearoff=0) menubar.add_cascade(label="文件(F)", menu=file_menu) file_menu.add_command(label="打开存档(O)", command=self.open_save_file, accelerator="Ctrl+O") file_menu.add_command(label="保存存档(S)", command=self.save_file, accelerator="Ctrl+S") file_menu.add_command(label="另存为(A)", command=self.save_as_file, accelerator="Ctrl+Shift+S") file_menu.add_separator() file_menu.add_command(label="备份存档(B)", command=self.backup_save_file) file_menu.add_separator() file_menu.add_command(label="退出(X)", command=self.root.quit) # 工具菜单 tools_menu = tk.Menu(menubar, tearoff=0) menubar.add_cascade(label="工具(T)", menu=tools_menu) tools_menu.add_command(label="验证数据完整性", command=self.validate_data) tools_menu.add_command(label="重置所有修改", command=self.reset_all_changes) # 帮助菜单 help_menu = tk.Menu(menubar, tearoff=0) menubar.add_cascade(label="帮助(H)", menu=help_menu) help_menu.add_command(label="使用说明", command=self.show_help) help_menu.add_command(label="关于", command=self.show_about)…... -
jsdelivr npm CDN 国内加速节点
jsdelivr 节点:常用于加速 GitHub/npm 项目,可通过更改节点改善项目在国内的可用性。 gcore.jsdelivr.netGcore 节点可用性高testingcf.jsdelivr.netCloudflare 节点可用性高quantil.jsdelivr.netQuantil 节点可用性尚可fastly.jsdelivr.netFastly 节点可用性尚可originfastly.jsdelivr.netFastly 节点可用性低test1.jsdelivr.netCloudflare 节点可用性低cdn.jsdelivr.net通用节点可用性低 第三方提供的 jsdelivr 节点 jsd.cdn.zzko.cn国内 CDNjsd.onmicrosoft.cn国内 CDNjsdelivr.b-cdn.net台湾 CDNcdn.jsdelivr.usAnycast 这两个节点国内速度很快,不清楚稳定性。 npm 节点:unpkg.com 国内几乎不可用,可用下方国内 cdn 节点。 npm.elemecdn.com饿了么同步快,缺的多npm.onmicrosoft.cn公益需准确的版本号unpkg.zhimg.com知乎同步慢npm.akass.cn公益需准确的版本号cdn.chuqis.com/npm/公益需准确的版本号code.bdstatic.com/npm百度仅同步热门包... -
umami mysql版本更新到2.18 check-db报错解决
升级到 2.18.0 后,Umami 由于 09_update_hostname_region 迁移失败而无法启动。 在 DB 容器内的 SQL shell 中使用以下 SQL 命令: UPDATE _prisma_migrations SET finished_at = NOW(), logs = NULL, applied_steps_count = 1 WHERE migration_name = '09_update_hostname_region'; Prisma 迁移过程中可能因数据库权限、表结构冲突或版本兼容性问题导致状态卡住。... -
如何在宝塔面板中更新 SearXNG(Python 项目)
我个人其实不喜欢使用docker的方式部署项目,万不得已需要非常多的依赖环境的时候,会优先选择使用docker,网上搜来搜去全是部署的教程,一概没有提到如何更新的。这里安装的步骤就不说了,我只记录更新的步骤,之前是记得的,最近去忙别的项目太久了,以至于忘了,所以在这里记录一下。 本文将详细介绍如何在宝塔面板中非 Docker 部署的环境下,更新 SearXNG 项目。适用于使用 uWSGI、Nginx 或 Apache 部署的 Python 项目。 前提条件 已通过宝塔面板部署 SearXNG 项目。 熟悉宝塔面板基本操作(如启动/停止服务)。 具备基础 Linux 命令行操作能力。 更新步骤 1. 停止 SearXNG 服务 在宝塔面板中: 进入「网站」→ 选择你的 SearXNG 项目 → 点击「停止」。 2. 备份重要文件 cd /www/wwwroot/your_searxng_path # 替换为实际路径 # 备份配置文件 cp settings.yml settings.yml.bak # 备份虚拟环境(可选) cp -r venv venv.bak 3. 拉取最新代码 # 添加安全目录(若首次出现权限警告) git config --global --add safe.directory /www/searxng # 获取最新代码 git pull origin master 到这步基本上结束了,你在Python项目的终端里退出,重启一下Python项目就可以看到更新了已经。如果报错的,可以看看下面的步骤。 20250802这个版本需要从gunicorn启动项目,以后应该不支持uwsgi 4. 更新 Python 依赖 # 升级 pip 并安装依赖 pip install -U pip pip install -U -r requirements.txt # 退出虚拟环境 deactivate 5. 更新前端资源 cd searx/static/themes/simple # 安装 Node.js 依赖 npm install # 编译前端资源 npm run build 6. 检查并修改配置文件 如果 settings.yml 有变更,手动合并 settings.yml.bak 和新版本的配置。 确保数据库、端口等配置正确。 7. 重启服务 在宝塔面板中: 进入「网站」→ 选择你的 SearXNG 项目 → 点击「启动」。 或通过修改 uwsgi 配置触发重启: touch uwsgi.ini # 修改时间戳以重启服务 验证更新 访问你的 SearXNG 站点(如 http://yourdomain.com)。 检查页面底部是否显示新版本号(如 SearXNG vX.Y.Z)。 测试搜索功能是否正常。 注意事项 定期备份:更新前务必备份 settings.yml 和虚拟环境。 官方文档:参考 SearXNG 官方更新日志 了解新版本变更。 权限问题:确保宝塔用户对项目目录有读写权限。 通过以上步骤,您可以安全地在宝塔面板中更新 SearXNG 项目。如遇问题,可通过备份快速回滚。... -
MaxKB 迁移教程(基于宝塔面板 Docker 环境)
一、迁移前准备工作 确保新旧服务器都已安装宝塔面板和 Docker :在新旧服务器上分别登录宝塔面板,检查 Docker 是否正常运行。可通过宝塔面板的 Docker 管理模块查看服务状态。 记录原始 MaxKB 配置信息 :包括容器名称、端口号(默认为 8080)、数据卷挂载路径(默认为 /root/.maxkb 和 /root/.python-packages)等,便于在新服务器上恢复原有配置。 二、在旧服务器上备份数据 进入旧服务器的宝塔面板,停止 MaxKB 容器 :在宝塔面板的 Docker 容器列表中找到 MaxKB 容器,点击 “停止” 按钮。 使用命令打包数据目录 : 打开旧服务器的终端,执行以下命令将 /root/.maxkb 和 /root/.python-packages 目录打包压缩: tar -czvf maxkb_backup.tar.gz /root/.maxkb /root/.python-packages 将打包好的 maxkb_backup.tar.gz 文件从旧服务器下载到本地,可通过宝塔面板的文件管理功能或使用 scp 命令进行传输。 三、在新服务器上准备环境 上传备份文件到新服务器 :将本地的 maxkb_backup.tar.gz 文件上传到新服务器的 /root 目录下,可使用宝塔面板的文件上传功能或 scp 命令,例如: scp /path/on/local/maxkb_backup.tar.gz root@新服务器IP:/root 解压备份文件 :在新服务器的终端中,执行以下命令解压备份文件: tar -xzvf maxkb_backup.tar.gz -C /root 这会将备份的数据解压到 /root/.maxkb 和 /root/.python-packages 目录下。 四、在新服务器上拉取 MaxKB 镜像并运行 拉取 MaxKB 官方镜像 :在新服务器的终端中,执行以下命令拉取最新的 MaxKB 镜像: docker pull registry.fit2cloud.com/maxkb/maxkb 运行 MaxKB 容器 :根据需要设置端口号(可修改为原本的端口或其他端口),执行以下命令启动 MaxKB 容器: docker run -d --name=maxkb --restart=always -p <新端口号>:8080 -v ~/.maxkb:/var/lib/postgresql/data -v ~/.python-packages:/opt/maxkb/app/sandbox/python-packages registry.fit2cloud.com/maxkb/maxkb 例如,若要使用原本的 8080 端口,命令为: docker run -d --name=maxkb --restart=always -p 8080:8080 -v ~/.maxkb:/var/lib/postgresql/data -v ~/.python-packages:/opt/maxkb/app/sandbox/python-packages registry.fit2cloud.com/maxkb/maxkb 五、验证迁移是否成功 在宝塔面板查看 MaxKB 容器状态 :登录新服务器的宝塔面板,进入 Docker 容器列表,检查 MaxKB 容器是否处于 “运行中” 状态。 通过浏览器访问 MaxKB 服务 :在浏览器中输入新服务器的 IP 地址和设置的端口号,例如 http://新服务器IP:8080,测试是否能正常访问 MaxKB 系统,登录后检查数据是否完整迁移。 六、注意事项 在迁移过程中,确保新旧服务器的网络连接正常,避免数据传输中断。 若需要修改 MaxKB 的配置文件(如端口号等),可在解压备份文件后,进入 /root/.maxkb 目录下查找相关配置文件进行修改,但需谨慎操作,修改完成后再启动容器。 迁移完成后,建议在旧服务器上清理已停止的 MaxKB 容器及相关镜像,以释放资源。可使用以下命令: docker stop maxkb docker rm maxkb docker rmi registry.fit2cloud.com/maxkb/maxkb 以上就是基于宝塔面板 Docker 环境的 MaxKB 迁移教程,按照步骤操作即可完成数据的迁移和新环境的搭建。...





