惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

P
Privacy International News Feed
I
Intezer
T
Tenable Blog
S
Schneier on Security
Project Zero
Project Zero
G
GRAHAM CLULEY
酷 壳 – CoolShell
酷 壳 – CoolShell
小众软件
小众软件
Know Your Adversary
Know Your Adversary
博客园 - 司徒正美
The Cloudflare Blog
Recent Commits to openclaw:main
Recent Commits to openclaw:main
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
N
News and Events Feed by Topic
博客园 - 叶小钗
宝玉的分享
宝玉的分享
L
LINUX DO - 热门话题
aimingoo的专栏
aimingoo的专栏
S
Secure Thoughts
Forbes - Security
Forbes - Security
T
The Exploit Database - CXSecurity.com
D
Darknet – Hacking Tools, Hacker News & Cyber Security
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 【当耐特】
罗磊的独立博客
IT之家
IT之家
H
Hacker News: Front Page
I
InfoQ
云风的 BLOG
云风的 BLOG
S
Security Affairs
M
MIT News - Artificial intelligence
GbyAI
GbyAI
Jina AI
Jina AI
Help Net Security
Help Net Security
Engineering at Meta
Engineering at Meta
大猫的无限游戏
大猫的无限游戏
Webroot Blog
Webroot Blog
L
Lohrmann on Cybersecurity
A
About on SuperTechFans
Attack and Defense Labs
Attack and Defense Labs
The Register - Security
The Register - Security
V
V2EX
G
Google Developers Blog
D
DataBreaches.Net
Apple Machine Learning Research
Apple Machine Learning Research
C
Cybersecurity and Infrastructure Security Agency CISA
J
Java Code Geeks
W
WeLiveSecurity
Cloudbric
Cloudbric
T
Tor Project blog

夜行人

回家路上 第一期的直播演示项目 震动检测器 正能量 在线参观CodeLab Neverland 发布 CodeLab Adapter 3.3.1 DynamicTable 之 纸糊方向盘 CodeLab DynamicTable: 一个可实施的技术方案 CodeLab Insight 发布 Alpha 版 情人节 Home Assistant 周报 && IoT 周报 (02) Joplin: 关注隐私的 Evernote 开源替代软件 浏览器的未来与 Web 传感器 Home Assistant 周报 && IoT 周报 (01) 百宝箱(01) 论自由 介绍 WebThings Home Assistant 周报 && iot 周报 (00) 百宝箱(00) 毛姆读书心得 传世之作 周末徒步 CodeLab Adapter ❤️ Jupyter/Python 航班 躲雨 夏令营途中 [译]思想--作为一种技术 The future of coding 美国之行 三门问题的程序模拟 从Python转向Pharo https://blog.just4fun.site/post/iot/iot-open-source-projects/ Python异步编程笔记 https://blog.just4fun.site/post/iot/iot-open-source-hardware-community/ 万物积木化开发者社区 CodeLab ❤️ Blender Scratch3技术分析之云变量 API(第7篇) [译]对管道(Pipes)的偏爱 [译]提出正确的问题比得到正确答案更重要 蓝牙设备与Scratch3.0 创建你的第一个Scratch3.0 Extension Scratch3技术分析之项目内部数据(第6篇) Scratch3技术分析之社区 API(第5篇) Scratch3技术分析之User API(第4篇) Scratch3技术分析之项目主页API(第3篇) Scratch3技术分析之静态资源API(第2篇) Scratch3.0、micro:bit与Windows7 https://blog.just4fun.site/post/iot/zerynth-vs-micropython/ 核聚变、方所与半宅空间 可视化编程为何是个糟糕的主意 codelab.club周末聚会 关于codelab.club '下一件大事'是一个房间 Hungry Robot - Eat everything 编程作为一种思考方式 今日简史 史蒂夫·乔布斯传 罗素自选文集 https://blog.just4fun.site/post/edx/tianjin-scratch-ai/ https://blog.just4fun.site/post/edx/richie-cms-openedx/ 徒步武功山 WebUSB与micro:bit 积木化编程与3D场景 夜宿武功山顶 scratch3-adapter接入优必选Alpha系列机器人 https://blog.just4fun.site/post/edx/video-migration-note/ scratch3-adapter重构笔记 https://blog.just4fun.site/post/edx/edx-community-members/ 两种硬件编程风格的比较 使用micro:bit自制PPT翻页笔 柏拉图对话集 scratch3.0 + micro:bit 七月电影放映计划 非营利组织的管理 Screenly--用树莓派让任何屏幕变为可编程的数字标牌 以最佳实践开始你的Django项目 micro:bit与事件驱动 为Scratch3.0设计的插件系统(上篇) OCR应用一例 近两年读过的一些好书 blockly开发之使用python驱动浏览器中的turtle(2) 牛顿新传 文学理论入门 逻辑的引擎 人生的意义 blockly开发之生成并运行js代码(1) blockly开发之hello world(0) micro:bit使用笔记 神器之Termux https://blog.just4fun.site/post/iot/micropython-notes/ Cozmo what is this Scratch的前世今生 下段旅程 我行在远方 爆裂 途中杂记 https://blog.just4fun.site/post/edx/open-edx-startup/ cozmo系列之入门 - 有性格且可编程的机器人 PaperWeekly开发笔记 创业二三事
博客迁移:从Pelican到Hugo
种瓜 · 2019-10-30 · via 夜行人

文章目录

前言

timqian在Github上收集中文独立博客,提到独立博客虽已式微,但爱其“自由的排版,自由的说话”。

将自己的独立博客提交到列表的时候,timeqian提醒我RSS似乎有误,于是修理了一下博客工具(五年前的版本),不修还好,修理之下问题越来越多,一咬牙,决心切换到Hugo,文章有点多,只好写了自动迁移脚本,结果编译速度从一分钟下降到了3秒不到(591篇文章)!终于甩掉了6年前的老旧风格,换上自己喜欢的干净主题

犹豫的原因

在静态博客生成器中,Hugo口碑很好,速度快是其核心优势, slogan是

The world’s fastest framework for building websites.

迟迟没有迁移的原因有二:

  1. 需要调整meta数据(categories,tag,Slug…)
  2. 兼容旧的链接(外部引用或者搜索结果)
  3. 需要迁移自定义的东西(访客统计脚本等),忘了当初在哪做的配置

这些工作想想就觉得费时。

动手

meta数据

既然决定动手,便先在Google/Github上搜罗了一圈,看看前人都是如何吃螃蟹的,提前了解一下风险,也看看社区里是不是已经有自动化迁移工具了。

首先注意到了pelican-to-hugo.py

这个脚本似乎能帮我解决第一个问题:

需要调整meta数据(categories,tag,Slug…)

使用正则表达式,批量替换meta数据。

虽有些地方需要调整,但有了这个骨架,剩下就是一些细活了,我的正则表达式功底还不错(推荐《精通正则表达式》),调整起来很快。

对文件和路径的处理,我都采用pathlib,代码比前头要整洁。

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

p = Path(path)
files = list(p.glob('**/*.md'))

for file_p in files:
        # print(file_p)
        content = file_p.read_text()
        content = xxx(content) # 业务逻辑
        file_p.write_text(content)

兼容旧的链接

Hugo为文章生成url有它的默认规则。

我希望旧的文章保持和之前同样的url,因为搜索引擎近期搜出的文章还是老旧的连接,不希望用户搜出我的博客文章后,打开却是404。此外也希望保持对被人引用的兼容。

如果你在不同时间内阅读过腾讯开发者文档,就知道url改来改去是多操蛋的一件事了。真令人生气。所以我现在尽量回避腾讯生态的技术设施。

hugo有两个meta信息允许你自定义文档url,其一是slug, 其二是aliasesslug。我们来看个例子.

1
2
3
4
5
6
---
Date: 2019-09-09
title: "开源项目与开源社区"
Slug: about-opensource
aliases: ["/about-opensource","/about-opensource.html"]
---

这篇文章分别可以使用以下链接访问:

1
2
3
4
/post/编程/about-opensource/

/about-opensource
/about-opensource.html

slug和目录结构有关。

aliases的左右类似重定向,这样就能很好做到兼容。aliases是我用正则表达式自动生成的。

迁移自定义的东西

这部分倒简单,原因是hugo有庞大的社区,所以像统计脚本之类的,都只需要做个简单配置就行。

更多

既然已经对博客大动刀子了,索性不如来个彻底,把想做却迟迟没有实施的事情一并做了。

此前博客图片一直放在qiniu上,为此还写了一个自动化截图工具

七牛是很好的云服务,对开发者也友好。但和国内所有的事情一样: 政策风险太高,哪天说不能访问就不能访问,诸如前段时间的leancloud,这些都不是技术问题。

所以我决定让博客尽可能自托管,其中核心的一个工作是将图片自托管。于是写了一些简单的正则表达式,提取出所有图片:

1
2
ack -ho "http:[^\(\)\[\]]*?\.(png|jpg|jpeg|gif|PNG|JPG|JPEG)" > /tmp/blog_img_list.txt
ack -ho "http://.*?.(mp4|MP4)" > /tmp/blog_mp4_list.txt

使用wget下载到hugo文件目录里。

1
2
3
4
5
6
7
import subprocess
with open("/tmp//tmp/blog_img_list.txt") as png_url_list:
    urls = set(png_url_list.readlines()) # 去重
for url in urls: 
    if "just4fun" in url:
        cmd = f"wget {url}"
        subprocess.call(cmd,shell=True)

参考