全自动替换图床链接

手动处理图片链接太痛苦了,每次都要下载、上传、替换链接,步骤多还容易出错。写个脚本让它全自动,一劳永逸。 问题 博客图片管理一直是个麻烦事: 从微信公众号转载文章,图片都是外链 外链不稳定,说不定哪天就挂了 想迁移图床,手动改链接太繁琐 一不小心就忘了某个步骤,图片上传了链接没更新 原理 其实就三步: 下载:扫描 Markdown 文件,找到所有外部图片,下载到本地 上传:把本地图片通过 PicGo 上传到图床 替换:更新 Markdown 中的图片链接 核心是用正则提取图片引用 ![](url),然后做 URL 映射替换。 加上缓存机制(基于文件 hash),避免重复上传。再加个备份功能,出问题能回滚。 实现 写了三个脚本: 1. auto_migrate.py - 一键式 最常用,自动完成所有步骤: 1 2 python3 scripts/auto_migrate.py --dry-run # 预览 python3 scripts/auto_migrate.py # 正式执行 运行前会提醒检查 PicGo 配置,避免上传到错误图床。 2. fix_current_links.py - 修复 如果图片已上传但链接没更新,用这个: 1 python3 scripts/fix_current_links.py --yes 从缓存文件 .image_cache.json 读取映射关系,批量更新链接。 3. blog_image_manager.py - 手动模式 需要精细控制时用,可以单独执行下载或上传。 使用 最简单就两步: 1 2 3 4 5 # 1. 预览(首次推荐) python3 scripts/auto_migrate.py --dry-run # 2. 正式执行 python3 scripts/auto_migrate.py 出问题可以回滚: ...

January 28, 2026 · 1 min · 129 words · Ray

PostGIS 浅尝

PostGIS 教程 1. 什么是 PostGIS PostGIS 是 PostgreSQL 数据库的一个扩展,它允许在数据库中存储和操作 GIS(地理信息系统)空间数据。它为 PostgreSQL 添加了空间数据类型、索引和大量空间函数,可以进行地理分析、距离计算、空间查询等操作。 PostGIS 2. 准备工作:安装与启用扩展 在 PostgreSQL 数据库中启用 PostGIS,需要使用 SQL 命令创建扩展。示例: 1 CREATE EXTENSION postgis; 启用后,数据库将支持空间数据类型如 geometry 和 geography。 3. 空间数据类型 坐标系统说明 SRID 4326:WGS84 坐标系,通常用于 GPS 经纬度数据。 GEOGRAPHY 类型:采用球面/椭球面计算真实地球表面距离(单位是米). GEOMETRY 类型:采用平面坐标计算,通常用于投影坐标系,不适合直接计算地球表面距离。 3.1 geometry 类型 geometry 是用于表示平面(笛卡尔)空间几何对象的数据类型,支持点、线、多边形等多种几何类型。空间行为依赖于坐标参考系统(SRID)。 常见的几何类型包括: POINT:单个点 LINESTRING:线段序列 POLYGON:多边形 MULTIPOINT、MULTILINESTRING、MULTIPOLYGON:复合几何类型 3.2 geography 类型 geography 是用于地理空间数据的类型,面向真实球面或椭球体,适合经纬度数据和真实地球距离的计算。使用此类型的距离和面积计算会基于地球模型返回现实世界的单位(如米)。 4. 空间参考系统(SRID) 空间数据的坐标依赖空间参考系统(SRID)。常见的 SRID 包括: 4326(WGS84):基于全球 GPS 坐标,经度/纬度,常用于地理坐标。 使用 SRID 能确保空间对象在正确的参考系统下解释和计算。 5. 基本操作:创建空间数据 5.1 创建几何点 1 SELECT ST_MakePoint(-121.97, 37.38); 这个函数会返回一个 geometry 类型的点对象。 ...

January 26, 2026 · 2 min · 267 words · Ray

浅尝AI帮我分析股票

之前看到多次那种AI虚拟盘炒股大战了,今天又刷到个股市分析的项目,忍不住了,搞一个下来玩玩 以下记录折腾过程而已 GitHub - ZhuLinsen/daily_stock_analysis: LLM驱动的 A/H股智能分析器,多数据源行情 + 实时新闻 + Gemini 决策仪表盘 + 多渠道推送,零成本,纯白嫖,定时运行 我就不搞actions了,反正有服务器 第一步先拉仓库下来 配环境 随后我最近在学uv,让uv接管依赖管理。直接 uv add -r requirements.txt 然按照作者的环境配置指南,配上gemini的连接方式,由于没看到在哪里自定义gemini的调用方式,进代码一看,发现作者使用的是google.generativeai包,该包已被弃用,虽然还能用,但是我改成了使用 google.genai analyzer.py 中 _init_model 方法更新成如下 [python] 显示已折叠代码(58 行) 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 def _init_model(self) -> None: """ 初始化 Gemini 模型 配置: - 使用 gemini-3-flash-preview 或 gemini-2.5-flash 模型 - 不启用 Google Search(使用外部 Tavily/SerpAPI 搜索) - 支持自定义 endpoint(通过 GEMINI_API_ENDPOINT 环境变量) Note: 使用新的 google.genai 包(旧的 google.generativeai 已弃用) """ try: from google import genai from google.genai import types # 从配置获取参数 config = get_config() model_name = config.gemini_model fallback_model = config.gemini_model_fallback # 构建客户端配置 client_kwargs = { 'api_key': self._api_key, } # 配置自定义 endpoint(如果设置) if config.gemini_api_endpoint: logger.info(f"使用自定义 Gemini Endpoint: {config.gemini_api_endpoint}") client_kwargs['http_options'] = { 'baseUrl': config.gemini_api_endpoint, # 注意:参数名是 baseUrl,不是 api_endpoint } # 如果配置了 API 版本,也添加进去 if config.gemini_api_version: client_kwargs['http_options']['apiVersion'] = config.gemini_api_version # 注意:参数名是 apiVersion # 创建 Gemini 客户端 self._genai_client = genai.Client(**client_kwargs) # 尝试初始化主模型 try: # 新版 API 不再使用 GenerativeModel,而是直接通过 client.models.generate_content # 这里我们只需要记录模型名称 self._current_model_name = model_name self._using_fallback = False self._model = self._genai_client # 保存客户端引用 logger.info(f"Gemini 模型初始化成功 (模型: {model_name})") except Exception as model_error: # 尝试备选模型 logger.warning(f"主模型 {model_name} 初始化失败: {model_error},将尝试备选模型 {fallback_model}") self._current_model_name = fallback_model self._using_fallback = True self._model = self._genai_client logger.info(f"Gemini 备选模型配置完成 (模型: {fallback_model})") except Exception as e: logger.error(f"Gemini 模型初始化失败: {e}") self._model = None self._genai_client = None config加上 ...

January 24, 2026 · 2 min · 282 words · Ray

初识 BLE 协议以及微信小程序

手头有个项目,涉及到 app 端蓝牙连接。硬件开发伙伴给到了 BLE 协议,完全一头雾水 最近忙的没空推进 Go 的学习,想着博客至少不能落下更新,不管怎么样也要逼自己写一篇水文。 什么是 BLE 首先得知道什么是蓝牙(Bluetooth) 小时候肯定有人好奇为什么要叫 Bluetooth,无奈好奇心还不够,只停留在发起 why,今天才是真的解惑。 不出意外是和人名有关,他是Harald Bluetooth(哈拉尔德·蓝牙王) 他是丹麦国王,功绩差不多是统一了分裂的丹麦与挪威。90 年代蓝牙技术的研发小组以其名号期许新技术能集成各大资通品牌的标准。蓝牙的 logo 也是如此 卢恩字母 (Hagall,ᚼ)和 (Bjarkan,ᛒ)的组合,也就是Harald Blåtand的首字母HB的合写。 蓝牙技术规范由蓝牙技术联盟 (Bluetooth Special Interest Group, SIG) 制定,版本现如今已经更新到 第六代了 其中第四代开始,支持了本文的主角,也就是蓝牙低功耗 (Bluetooth Low Energy, BLE) 目前蓝牙最为普遍使用的有两种规格: 蓝牙基础率/增强数据率 (Bluetooth Basic Rate/Enhanced Data Rate, BR/EDR): 也称为经典蓝牙。常用在对数据传输带宽有一定要求的场景上,比如需要传输音频数据的蓝牙音箱、蓝牙耳机等; 蓝牙低功耗 (Bluetooth Low Energy, BLE): 从蓝牙 4.0 起支持的协议,特点就是功耗极低、传输速度更快,常用在对续航要求较高且只需小数据量传输的各种智能电子产品中,比如智能穿戴设备、智能家电、传感器等,应用场景广泛。 BLE 大概是什么 大概分成三个核心维度来了解 BLE:架构(Stack)、连接机制(GAP-Generic Access Profile) 和 数据交互(GATT-Generic Attribute Profile)。 BLE 的分层架构 (Protocol Stack) BLE 协议栈主要分为两大部分:控制器 (Controller) 和 主机 (Host)。 ...

January 19, 2026 · 2 min · 376 words · Ray

OpenCode 初体验

我是如何爽用OpenCode的 - 开发调优 - LINUX DO OpenCode 确实听说有一段时间,但是由于手头 codex+claudecode 以及cursor 三个工具配合使用对我而言vibe coding的体验已经算是不错的了。gemini3 出世以来 虽说强,但是没用过gemini cli,antigravity使用体感不佳(也许是用的太早了?)至少觉得简中交互不佳。 那受佬友这篇文章的启发,怎么说我也要尝尝咸淡。 什么是OpenCode GitHub - anomalyco/opencode: The open source coding agent. The open source coding agent. 感谢开源贡献者。 怎么用 我的开发工具是 家中的windows+wsl 和公司的mac 写本文时在家里,那么就在vscode+wsl 里面实践一下 官方的安装方式 1 2 3 4 5 6 7 8 9 10 11 12 # YOLO curl -fsSL https://opencode.ai/install | bash # Package managers npm i -g opencode-ai@latest # or bun/pnpm/yarn scoop bucket add extras; scoop install extras/opencode # Windows choco install opencode # Windows brew install anomalyco/tap/opencode # macOS and Linux (recommended, always up to date) brew install opencode # macOS and Linux (official brew formula, updated less frequently) paru -S opencode-bin # Arch Linux mise use -g opencode # Any OS nix run nixpkgs#opencode # or github:anomalyco/opencode for latest dev branch Vscode插件市场可以直接找到Opencode 的插件,安装一下,(ok 我以为这个就是完全体,原来只是个类似之前的 cc for vscode一样的东西) 那还是执行 curl -fsSL https://opencode.ai/install | bash,在点击运行。 ...

January 9, 2026 · 1 min · 180 words · Updated: January 10, 2026 · Ray