全自动替换图床链接

手动处理图片链接太痛苦了,每次都要下载、上传、替换链接,步骤多还容易出错。写个脚本让它全自动,一劳永逸。 问题 博客图片管理一直是个麻烦事: 从微信公众号转载文章,图片都是外链 外链不稳定,说不定哪天就挂了 想迁移图床,手动改链接太繁琐 一不小心就忘了某个步骤,图片上传了链接没更新 原理 其实就三步: 下载:扫描 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

地图定位怎么实现

自动驾驶之高精度地图(一)定位篇-阿宝1990 以下转载自微信公众号文章,阿宝 1990 自动驾驶之高精度地图(一)定位篇 作者: 阿宝1990 阿宝1990 作者 / 阿宝 编辑 / 阿宝 出品 / 阿宝1990 在讲解高精度地图之前,我们先把定位这个事情弄清楚,想明白,后面的事情就会清晰很多,自古哲学里面讨论的人生终极问题,无非就三个,我是谁,我从哪里来,我要去哪里,这里的位置定位就包含了人生哲学中的两个问题,可见其重要性。 如果你有一个路痴女朋友,如果她在外面迷路了,如果是在10年前没有那么发达的导航手机,可能给你电话沟通是这样的。 ——你在哪儿呢? ——啊?我在马路上啊。 ——有什么特征? ——头顶有个月亮。 ——你旁边有什么啊? ——有个路灯。 ——有没有路牌啊?路牌上写的什么? ——我看看啊。还真的有,上边写着“禁止停车 违者罚款”。 ——姑奶奶,我真是服了你了…… ——哼,你是不是不爱我了,你肯定是不爱我了,你是不是喜欢上了新来的那个前台? 说了现代人,再来说说我们古代的人对于导航的需求:朝辞白帝彩云间,千里江陵一日还。两岸猿声啼不住,轻舟已过万重山,看看李白当时由于没有导航,导致过了多少座山都数不清了。 我们身处何方?怎样到达目的地?多久可以到达?——这是自人类出现以来一直萦绕于心的问题。早在石器时代,“北京人”外出打猎时会在沿途留下痕迹,待捕获猎物之后,配合固定的坐标物来找到回家的路。天体导航时代,罗盘、指南针、六分仪等发明不断拓展着人类在地球上的足迹,人们开始远行,世界走向融合。 普通定位 学过初中数学都知道,我们如果要在一个二维平面上定位的话,首先建立一个笛卡尔坐标系,通过坐标原点,就可以判定A点的具体位置(x,y)的坐标,如果要从A点到B点的绝对距离,也就是通过坐标系上的绝对位置的运算即可。 这里的二维平面的定位比较准确,而且相对容易一些,是只有X/Y方向上的坐标,只要大家都遵循对应的原点坐标,或者哪怕原点坐标不同,轻易转换也可以得到,所以一般情况下在室内的一些平面定位会比较好做一些,比如扫地机器人的定位。 GPS三维定位 我们先来看看地球上的某个位置的定位,其实对于对球上的某个点而言,正常情况下只需要知道经度和纬度,但是对于导航而言,一定还需要定位的高度,否则像重庆这样的魔幻8D城市,太多高架桥的位置,上桥和下桥的导航位置显示的经纬度都一样,只能通过高度来定位自己处于哪条道路上,否则导航分分钟让人在重庆高架桥上半日游,所以大家都说看一个地图准确不,来重庆立交桥溜溜就行。 有的这个概念后我们再来看GPS定位原理就会轻松很多。 首先明白一个事情,无论是GPS还是北斗,都是通过卫星来定位的,GPS 的全称是导航星测时和测距全球定位系统,简称全球定位系统(Global Position System,GPS),可以实现地球表面附近范围的全天候三维位置等信息的获取,其具有实时性好、准确度高的优点,是当前世界发展最完善、应用最广泛的全球卫星导航系统。 我们经常在文章中看到的GNSS,是全球卫星导航系统(GNSS)是卫星导航的统称,是除了GPS以外,还包含目前俄罗斯的GLONASS、中国的北斗,欧洲的伽利略这四大导航系统。 GPS的工作的标准定义如下: GPS由24颗工作星和4颗备用星组成。卫星工作在互成55度的6条高度为2.02万KM的非同步轨道上。如此一来,在全球的任何地方、任何时间都可观测到4颗以上的GPS卫星。GPS卫星向地球发射导航电文(系统时间、星历、历书、卫星时钟修正参数、导航卫星健康状况、电离层延时参数等内容),GPS终端收到卫星发送的数据,经解算即可确定当前位置,并以NMEA0183格式,WGS-84坐标系输出数据。 读起来很拗口吧,那我以一个专业理科生的理解方式来给你剖析剖析。 ①为什么不使用同步轨道卫星呢? ...

January 26, 2026 · 1 min · 182 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