- 获取opml文件
- 解析opml文件
- 按表格格式写入MarkDown中
- 每次运行时,将自动修改README.md
- fork本仓库
- 添加一个Repository secret。
- 点击“New repository secret”按钮,添加变量:Name为
MY_CONFIG_JSON
,value请参考config.json.example
。
- 使用GithubAction实现定时更新
- 当添加新的订阅时自动更新
- 每次运行时,将自动修改README.md
- 将订阅列表同步到博客中。
- 大部分时间是花在了如何获取opml文件上。Tiny Tiny RSS所给的文档较为精简,而网上相关的资料大都仅局限于如何部署。所以这一段只能是自己摸索。
- TinyTinyRSS的网页版有给一个按钮能导出OPML,而这个按钮所指向的网址是
http://example.com/tt-rss/backend.php?op=opml&method=export'
。但它是有个鉴权操作的。需要登录。 - 它的示例中有提供了一个登录的api调用,所以我开始的想法也是顺着这个来。想着直接添加data参数。但尝试了多种添加方式无果。
- 后来注意到登录成功是会返回session值的,于是先用curl试验了下。
# 登录并获取Session ID SESSION=$(curl -s -d '{"op":"login","user":"user","password":"password"}' http://example.com/tt-rss/api/ | python -c "import sys, json; print(json.load(sys.stdin)['content']['session_id'])") #获得opml文件 curl -o my_tiny_tiny_rss.opml 'http://example.com/tt-rss/backend.php?op=opml&method=export' --cookie "ttrss_sid=${SESSION}"
- 转写成python是用的request。其实现在回头想想,这应该是蛮基础的操作,而且session之前也有接触过。如果早点想起来的话是可以少花些时间的。
- TinyTinyRSS的网页版有给一个按钮能导出OPML,而这个按钮所指向的网址是
- opml的解析有现成的库,用就是了。
- 然后就是把一些个人信息抽出来写在配置文件中。这里踩了一个坑。
data = {'op': 'login', 'user': user, 'password': password}
,我开始的时候是这样写的data = f"{{'op': 'login', 'user': {user}, 'password': {password}}}"
。后者虽然在形式上看着一样,但前者是json对象,后者是字符串。这里也给我提了个醒:Python虽然有动态类型这个特性,但还是要注意类型错误。 - 最后是使用Github Action。之前也有使用过,但是是直接用的别人写好的workflow。所以也花了些时间学习了下。遇到的几个问题是
- Yml文件的格式问题。这个可以用YAML Validator来检查。Vscode应该也有相应的插件吧。
- 运行时需要用到的变量,是用的secret。我之前以为secret的value只能是字符串。但Github Action中python获取仓库的secrets中提到,可以把一整个yml文件放在value里面。所以我就想那json文件应该也可以。试了下确实能行。这样我的代码需要修改的地方就很少了。
- workflow的触发方式,要添加手动触发,需加上
workflow_dispatch:
- 尝试实现功能4:每次运行时,将自动修改README.md;
-
先是用正则表达式实现:读取文件内容到一个字符串中,再去匹配
r'## 我的订阅(.*)\n'
并替换。这里踩了一个坑:刚开始我写的是r'## 我的订阅(.*?)\n'
,非贪婪匹配,只匹配了一个换行。 -
感觉这个方法不是很好,就想着查找所要替换的内容的开头在文件中的位置,然后直接在那里开始写。这个折腾了比较久。尝试了如下写法:
- 这个的问题是还是将一整个文件的内容都赋给了一个字符串
readme = f.read() start = readme.find('## 我的订阅\n') f.seek(start)
- 写之前我看不出来代码有什么问题,但运行结果是在文件的末尾追加replace。觉得是write的问题,但不知道为什么
if '## 我的订阅\n' in line: start_line_num = line_num # 记录所在行号 f.seek(0) # 重新定位到文件开头 for i in range(start_line_num): f.readline() # 读取到标题所在行 # print(f.tell()) 此时文件指针位于所需位置 f.write(replace) # 文件指针自动变到了末尾 break
- 使用了seek
if '## 我的订阅\n' in line: title_pos = f.tell() # 使用f.tell()记录标题行位置 #print(title_pos) f.seek(title_pos) # 定位到标题行位置 replace2 = md_text + md_table+'\n' f.write(replace2) break
-
- 添加了运行时参数,这样开发的时候就不用特地去注释代码了。
- 尝试实现自动推送到其他仓库的Github Action,最后发现我实际的需求其实没必要这样做。但从中收获了几点:
actions/checkout@v3
的使用:- name: clone EuDs63/EuDs63.github.io uses: actions/checkout@v3 with: repository: 'EuDs63/EuDs63.github.io'
actions/checkout@v3
后,路径实例/home/runner/work/TinyTinyRSS-OPML-to-MD-Table/TinyTinyRSS-OPML-to-MD-Table
更新时间:2024-10-06