点餐网站怎么做/今日要闻新闻

点餐网站怎么做,今日要闻新闻,国外财经网站是怎么做的,网络安装公司使用Github Action自动同步obisidian和hexo仓库,避免手动操作。 本文首发于❄慕雪的寒舍 1. 烦恼 先来说说慕雪现在的笔记和博客是怎么管理的吧,我正在使用两套笔记软件 思源笔记:私密性高一些,不是博客的笔记都在这里面。由于思…

使用Github Action自动同步obisidian和hexo仓库,避免手动操作。

本文首发于❄慕雪的寒舍

1. 烦恼

先来说说慕雪现在的笔记和博客是怎么管理的吧,我正在使用两套笔记软件

  • 思源笔记:私密性高一些,不是博客的笔记都在这里面。由于思源笔记不是markdown编辑器,不能直接和hexo对接;
  • obisdian:专门管理hexo的博客;

然后我的hexo博客和obsidian又有分离,hexo配置仓库是一个单独的git仓库(后文简称为hexo仓库),obsidian博客库也是一个单独的git仓库(后文简称为obisidian仓库)。

我采用的操作特别繁琐,步骤如下:

  1. 在obsidian里面写好博客之后,手动使用FreeFileSync软件,将obisidian/blog目录同步到hexo/source/_posts目录中(这两个目录完全一样);
  2. 然后再到hexo本地仓库中执行hexo三板斧命令,给新的博客生成abbrlink,push到hexo的github仓库;
  3. 再用FreeFileSync反向将hexo/source/_posts目录同步回obisidian/blog目录,因为新的博客会多出abbrlink;

是不是听起来都头大了?

2. 曾经的想法

先前我一直在想怎么让这套流程简化,考虑过几个方案都不太满意。我想过直接把obsidian vaults丢到hexo/source/_posts目录里面,但是考虑到我的obsidian中还有博客模板这种不需要上传到博客里面的内容,此项并不方便(虽然hexo其实可以跳过渲染某些md文件)

现在就想出了自动化的方案,也就是用github action来同步obsidian和hexo的仓库,当obisidian/blog目录有变动的时候,触发action,自动将这个目录的内容拷贝到hexo/source/_posts仓库目录中,并push到hexo仓库。

这里就有一个问题,abbrlink是基于hexo插件生成的,如果用这种方式那就没办法给新的博客md文件生成一个固定abbrlink了。不管是怎么让github action执行hexo g命令,最后都会出现远程仓库md文件中有abbrlink,但本地需要pull才能更新的问题,这会对我后续的博客编写和git操作带来不便(毕竟之前都是无脑push上去的)

之前每次想折腾github action的时候就会发现这个问题(由于没记笔记导致折腾的时候忘记了之前为啥没搞定……),然后又不了了之。

今天突然想起来,既然问题是在abbrlink插件上,那我不用hexo来生成abbrlink不就行了?反正abbrlink本质上和随机数没啥关系,我只要给新的博客手动加上一个和其他博客不冲突的abbrlink不就ok了?

注:hexo的abbrlink插件是通过crc16/crc32算法计算得到文件的abbrlink的,并非随机数生成。但对于abbrlink的作用来看,只要博客上每个文章都有一个独立的abbrlink其实就够了,所以abbrlink说它是随机数也没啥问题。

解决方法明了:用别的方法给新博客生成abbrlink,然后再用github action自动化同步obsidian仓库和hexo仓库。

3. 解决步骤

3.1. 生成abbrlink的python脚本

其实obsidian中是有一个abbrlink插件的,首先感谢插件作者能提供一个hexo-abbrlink插件的替代品。但是,这个插件不太符合本人的需求,因为它直接针对于obsidian全局,会把我的其他文件以及博客模板文件都加上abbrlink。

折腾了一会后,感觉不如返璞归真,直接写个python脚本,把所有博客文件的abbrlink遍历出来,然后生成30个不冲突的abbrlink写入到一个文件里面,每次写新博客的时候从这个文件里面取一个abbrlink出来用就完事啦!

说干就干,GPT,启动!

# 生成不冲突的abbrlink
import yaml
import re
import os
import randomMD_FILE_PATH = '../../Notes/CODE'
"""博客md文件路径"""
NEW_ABBRLINK_SIZE = 20
"""生成几个abbrlink"""
NEW_ABBRLINK_MD_FILE = '../../Notes/ABBRLINK归档.md'
"""生成的abbrlink写入这个md文件里面"""def extract_front_matter(file_path):"""提取 Markdown 文件中的 front-matter 内容。假设 front-matter 是以 '---' 包围的 YAML 格式内容。"""with open(file_path, 'r', encoding='utf-8') as file:content = file.read()# 使用正则表达式匹配 front-mattermatch = re.match(r'---\n(.*?)\n---\n', content, re.DOTALL)if match:front_matter = match.group(1)return yaml.safe_load(front_matter)  # 使用 yaml 解析 front-matterelse:return Nonedef remove_front_matter(file_path):"""移除 Markdown 文件中的 front-matter 部分,返回去除 front-matter 后的内容。"""with open(file_path, 'r', encoding='utf-8') as file:content = file.read()# 使用正则表达式去除 front-mattercleaned_content = re.sub(r'---\n(.*?)\n---\n', '', content, flags=re.DOTALL)return cleaned_contentdef update_front_matter(file_path, new_front_matter):"""更新 Markdown 文件中的 front-matter 内容。"""with open(file_path, 'r+', encoding='utf-8') as file:content = file.read()# 使用正则表达式替换 front-matternew_front_matter_str = yaml.dump(new_front_matter, default_flow_style=False)content = re.sub(r'---\n(.*?)\n---\n', f'---\n{new_front_matter_str}\n---\n', content, flags=re.DOTALL)# 写回文件with open(file_path, 'w', encoding='utf-8') as file:file.write(content)def extract_front_matter_from_dir(directory_path):"""遍历指定目录及其子目录下的所有 .md 文件,提取它们的 front-matter 内容,并将所有内容添加到列表中。"""front_matter_list = []# 遍历目录中的所有文件和子目录for root, dirs, files in os.walk(directory_path):for filename in files:file_path = os.path.join(root, filename)# 只处理 .md 文件if filename.endswith('.md'):front_matter = extract_front_matter(file_path)if front_matter:front_matter_list.append(front_matter)return front_matter_listdef generate_unique_10digit_numbers(existing_numbers, n):"""生成 n 个不在 existing_numbers 列表中的 10 位数字。:param existing_numbers: 已存在的整数列表:param n: 需要生成的数字数量:return: 不重复的 10 位数字列表"""unique_numbers = set(existing_numbers)  # 将现有的数字转换为集合,加速查找generated_numbers = []# 如果现有数字数量已经非常大,可能无法生成足够的唯一数字if len(unique_numbers) > 9999999999 - 1000000000:return Nonewhile len(generated_numbers) < n:num = random.randint(1000000000, 9999999999)  # 随机生成一个10位数字if num not in unique_numbers:generated_numbers.append(num)unique_numbers.add(num)  # 将新生成的数字添加到现有数字集合中return generated_numbersdef write_int_list_to_md(file_path, int_list):"""将整数列表的成员按行写入一个Markdown文件。:param file_path: Markdown文件的路径:param int_list: 要写入文件的整数列表"""with open(file_path, 'w', encoding='utf-8') as file:for number in int_list:file.write(f"{number}\n")  # 每个数字写一行# 示例使用
if __name__ == "__main__":# 假设 markdown 文件目录路径为 "../../Notes/CODE"file_path = MD_FILE_PATH# 提取所有 .md 文件的 front-matterfront_matter_list = extract_front_matter_from_dir(file_path)# 打印所有文件的 front-matterif not front_matter_list:print("没有找到 front-matter 或目录为空。")os.abort()abbrlink_list = []for fm in front_matter_list:# print(f"文件的 front-matter 内容:", fm)if 'abbrlink' not in fm:print(f"ERR! abbrlink not in {fm}")continuelink = int(fm['abbrlink'])if link in abbrlink_list:print(f"ERR! {link} in abbrlink list!")continueabbrlink_list.append(link)# 获取新的abbrlinknew_abbrlink = generate_unique_10digit_numbers(abbrlink_list, NEW_ABBRLINK_SIZE)for link in new_abbrlink:print(link)print("Gen abbrlink success")write_int_list_to_md(NEW_ABBRLINK_MD_FILE, new_abbrlink)print("Write abbrlink to", NEW_ABBRLINK_MD_FILE)

脚本运行效果如下,会生成新的abbrlink链接数字,然后写入到指定的md文件中。这样在obsidian里面就能看到这个md文件,取用里面的abbrlink了。用完了之后再手动执行一下脚本更新abbrlink就完事啦。

❯ python3 gen_abbrlink.py
8608489065
7885829874
8484489314
4284761477
1589125738
9151131777
4800824161
7141292217
2714461943
5131440419
2816690027
9574459795
6572894529
2920325088
2724835080
7631222809
1802821635
3120273636
2860205445
3100823185
Gen abbrlink success
Write abbrlink to ../../Notes/ABBRLINK归档.md

3.2. Github Action配置

接下来就是配置Github Action来同步两个仓库了。让GPT写了个大概,发现GPT在瞎说,它给出https的仓库clone链接,并表示用自带的GITHUB_TOKEN就能克隆私有仓库了,但实际上完全没用。最后还是得用老办法ssh密钥对来实现。

首先使用如下命令生成一个ssh密钥,弹出的提示中填写一个文件名字(不然会覆盖默认目录的ssh密钥对)

ssh-keygen -t rsa -C "github action" 

然后,搞清楚同步的方向,我的需要是将obsidian仓库中的内容同步到hexo仓库,所以公钥放在hexo仓库,私钥放在obsidian仓库中。

在hexo仓库(被推送的仓库)中,仓库设置Settings->Deploy keys->Add deploy key添加公钥,命名为HEXO_PUB_KEY注意需要勾选允许write写入仓库,不然默认权限只允许pull和clone仓库。

在obsidian仓库中,仓库设置Settings->Secrets and variables->Secrets添加私钥,命名为HEXO_PRI_KEY

最后的Github Action Workflow文件如下,将该文件写入obsidian仓库的.github/workflows/sync-code-to-posts.yml即可,每个步骤都写了注释。

name: Sync CODE to _postson:push:paths:- 'Notes/CODE/**' # 监听 CODE 文件夹内的文件变化,没有变化不会触发actionjobs:sync:runs-on: ubuntu-lateststeps:      # 检出 obsidian 仓库的代码- name: Checkout muob repositoryuses: actions/checkout@v3# 设置 Git 配置- name: Set up Gitenv:ACTIONS_KEY: ${{ secrets.HEXO_PRI_KEY }}run: |mkdir -p ~/.ssh/echo "$ACTIONS_KEY" > ~/.ssh/id_rsachmod 700 ~/.sshchmod 600 ~/.ssh/id_rsassh-keyscan github.com >> ~/.ssh/known_hostsgit config --global user.name "musnows"git config --global user.email "ezplayingd@126.com"git config --global core.quotepath falsegit config --global i18n.commitEncoding utf-8 git config --global i18n.logOutputEncoding utf-8 # 克隆 HexoBlog 仓库(私有仓库),使用 ssh 来进行认证- name: Checkout HexoBlog repositoryrun: |git clone git@github.com:musnows/Hexo-Blog.git HexoBlog# 同步文件:将 obsidain 仓库中的 CODE 文件夹内容复制到 HexoBlog 仓库的 _posts 文件夹- name: Sync files from CODE to _postsrun: |rsync -av --delete Notes/CODE/ HexoBlog/source/_posts/# 提交更改并推送到 HexoBlog 仓库- name: Commit and push changes to HexoBlog repositoryrun: |cd HexoBloggit add .git commit -m "Sync CODE to _posts at $(TZ='Asia/Shanghai' date '+%Y-%m-%d %H:%M:%S')"git push origin hexo

第二步的Git操作中,我们将仓库配置的secrets.HEXO_PRI_KEY映射成环境变量ACTIONS_KEY,然后写入执行action的ubuntu环境的~/.ssh/id_rsa私钥文件中,这样就能操作另外一个仓库了。

第四步的Sync操作使用了rsync命令

rsync -av --delete 源文件夹 目标文件夹

解释一下这里的几个命令参数,-a用于保持文件的原有属性,-v代表verbose,会输出详细的日志,--delete用于在目标目录中删除源目录中不存在的文件(同步删除操作)。

4. 测试效果

我在目录中创建了一个测试文件,push到了远端仓库中,触发了action

image.png

hexo配置仓库成功被push了,有更新的文件也是在obsidain仓库中被修改的文件,符合预期。

image.png

这样就搞定啦!以后我只需要push博客到obsidian仓库中,就能自动同步到hexo仓库内了。不需要手动做那部分繁琐的操作

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/76160.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

scala简介和基础语法

Scala简介 Scala 是一门多范式&#xff08;multi-paradigm&#xff09;的编程语言&#xff0c;设计初衷是要集成面向对象编程和函数式编程的各种特性。 Scala 运行在 Java 虚拟机上&#xff0c;并兼容现有的 Java 程序。Scala 源代码被编译成 Java 字节码&#xff0c;所以它可…

时序数据库:InfluxDB命令行操作

学习 InfluxDB 的命令行操作至关重要&#xff0c;它不仅是与数据库直接交互的工具&#xff0c;也是理解 InfluxDB 核心概念的关键途径。通过命令行&#xff0c;用户可以高效地执行数据库管理、数据查询和插入等任务&#xff0c;深入掌握 InfluxQL 的语法及功能。这对于调试、快…

⑥ ACG-系统管理

上网管理行为是指对员工在工作时间内使用公司网络的行为进行管理和监督。在企业中&#xff0c;系统管理是实施上网管理行为的重要方式之一。系统管理包括以下几个方面&#xff1a; 1. 访问控制&#xff1a;通过设置网络访问权限&#xff0c;对员工访问特定网站或使用特定应用程…

【Docker】Dockerfile 优化工具 hadolint

本文内容均来自个人笔记并重新梳理&#xff0c;如有错误欢迎指正&#xff01; 如果对您有帮助&#xff0c;烦请点赞、关注、转发、订阅专栏&#xff01; 专栏订阅入口 | 精选文章 | Kubernetes | Docker | Linux | 羊毛资源 | 工具推荐 | 往期精彩文章 【Docker】&#xff08;全…

接口自动化——初识pytest

缩写单词含义.passed通过Ffailed失败&#xff08;用例执行时报错&#xff09;Eerror出错&#xff08;fixture执行报错&#xff09;sskipped跳过Xxpassed预期外的通过&#xff08;不符合预期&#xff09;xxfailed预期内的失败&#xff08;符合预期&#xff09; 1.pytest 配置 1…

leetcode日记(100)填充每个节点的下一个右侧节点指针

和层序遍历差不多的思路&#xff0c;将节点储存在队列里&#xff0c;一边取出节点一边放入取出节点的左右节点&#xff0c;直到队列空。 /* // Definition for a Node. class Node { public:int val;Node* left;Node* right;Node* next;Node() : val(0), left(NULL), right(NU…

注意力蒸馏技术

文章目录 摘要abstract论文摘要简介方法预备知识注意力蒸馏损失注意力引导采样 实验结论总结参考文献 摘要 本周阅读了一篇25年二月份发表于CVPR 的论文《Attention Distillation: A Unified Approach to Visual Characteristics Transfer》,论文开发了Attention Distillation…

PyTorch单机多卡训练(DataParallel)

PyTorch单机多卡训练 nn.DataParallel 是 PyTorch 中用于多GPU并行训练的一个模块&#xff0c;它的主要作用是将一个模型自动拆分到多个GPU上&#xff0c;并行处理输入数据&#xff0c;从而加速训练过程。以下是它的核心功能和工作原理&#xff1a; 1、主要作用 数据并行&am…

RCE复现

1.过滤flag <?php error_reporting(0); if(isset($_GET[c])){$c $_GET[c];if(!preg_match("/flag/i", $c)){eval($c);}}else{highlight_file(__FILE__);代码审计过滤了"flag"关键词&#xff0c;但限制较弱&#xff0c;容易绕过 ?csystem("ls&…

自动化发布工具CI/CD实践Jenkins介绍!

1. 认识Jenkins 1.1 Jenkins是什么&#xff1f; Jenkins 是一个开源的自动化服务器&#xff0c;主要用于持续集成和持续部署&#xff08;CI/CD&#xff09;。 它由Java编写&#xff0c;因此它可以在Windows、Linux和macOS等大多数操作系统上运行。 Jenkins 提供了一个易于使用…

TCP协议与wireshark抓包分析

一、tcp协议格式 1. 源端口号 &#xff1a; 发送方使用的端口号 2. 目的端口号 &#xff1a; 接收方使用的端口号 3. 序号: 数据包编号 &#xff0c; tcp 协议为每个数据都设置编号,用于确认是否接收到相应的包 4. 确认序列号 : 使用 tcp 协议接收到数据包&#xff0c…

《HelloGitHub》第 108 期

兴趣是最好的老师&#xff0c;HelloGitHub 让你对开源感兴趣&#xff01; 简介 HelloGitHub 分享 GitHub 上有趣、入门级的开源项目。 github.com/521xueweihan/HelloGitHub 这里有实战项目、入门教程、黑科技、开源书籍、大厂开源项目等&#xff0c;涵盖多种编程语言 Python、…

制作cass高程点块定义——cad c#二次开发——待调试

public class Demo{[CommandMethod("xx")]public void Demo1(){using var tr1 new DBTrans();var doc Application.DocumentManager.MdiActiveDocument; var db doc.Database;var ed doc.Editor;var 圆心 new Point3d(0, 0, 0); var 半径 10.0;using (var tr …

04 单目标定实战示例

看文本文,您将获得以下技能: 1:使用opencv进行相机单目标定实战 2:标定结果参数含义和数值分析 3:Python绘制各标定板姿态,查看图像采集多样性 4:如果相机画幅旋转90,标定输入参数该如何设置? 5:图像尺寸缩放,标定结果输出有何影响? 6:单目标定结果应用类别…

DevEco Studio编辑器的使用-代码code Linter检查

Code Linter代码检查 Code Linter针对ArkTS/TS代码进行最佳实践/编程规范方面的检查。检查规则支持配置&#xff0c;配置方式请参考配置代码检查规则。 开发者可根据扫描结果中告警提示手工修复代码缺陷&#xff0c;或者执行一键式自动修复&#xff0c;在代码开发阶段&#x…

wokwi arduino mega 2560 - 模数与数模转换AD和DA

截图&#xff1a; 20.53 黄灯灭 不报警 205.77 黄灯亮 报警 链接&#xff1a; https://wokwi.com/projects/415345595312267265 代码&#xff1a; 详细注释版&#xff1a;AD和I2C仿真实验案例程序 cpp #include <LiquidCrystal_I2C.h>// 定义I2C地址和LCD的行列数 #de…

虚拟机(一):Java 篇

虚拟机&#xff08;一&#xff09;&#xff1a;Java 篇 虚拟机&#xff08;二&#xff09;&#xff1a;Android 篇 架构 运行时数据区&#xff1a; 栈&#xff1a; 堆&#xff1a; 堆&#xff1a;通过new创建的对象都在堆中分配。OutOfMemoryError TLAB(Thread Local All…

硬件基础--14_电功率

电功率 电功率:指电流在单位时间内做的功(表示用电器消耗电能快慢的一个物理量)。 单位:瓦特(W)&#xff0c;简称瓦。 公式:PUI(U为电压&#xff0c;单位为V&#xff0c;i为电流&#xff0c;单位为A&#xff0c;P为电功率&#xff0c;单位为W)。 单位换算:进位为1000&#xff…

更高的效率——MyBatis-plus

一、什么是MyBatis-plus&#xff1f; MyBatis-plus是MyBatis的增强工具&#xff0c;在MyBatis基础上只做增强不做改变&#xff0c;可以简化基础的CRUD操作&#xff08;通过继承 BaseMapper 接口可直接使用预定义的增删改查方法&#xff09; 二、MyBatis-plus快速入门 2.1 准备…

【算法基础】递归与递推

目录 递归实现指数型枚举 题目 算法解析 递归实现排列型枚举 题目 算法解析 费解的开关 题目 算法解析 递归实现组合型枚举 题目 算法解析 带分数 题目 算法解析 飞行员兄弟 题目 算法解析 翻硬币 题目 算法解析 递归实现指数型枚举 题目 算法…