From cdac25869c867f25a39e1b3a67b57fdba9daf768 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9F=B3=E7=A5=9E?= <3162475700@qq.com> Date: Tue, 2 Jul 2024 21:48:56 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=98=AE=E4=BD=BF=E7=94=A8GitHub=20api?= =?UTF-8?q?=E6=8F=90=E5=8F=96=E5=88=B0=E6=95=B0=E6=8D=AE=EF=BC=8C=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=E6=8F=90=E5=8F=96=E5=87=BD=E6=95=B0=E4=BB=A5=E5=8F=8A?= =?UTF-8?q?=E5=AF=B9=E6=AF=94=E6=9B=B4=E6=96=B0=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- conf.yml | 23 ++++- dev_test/last_articles.json | 44 ++++++++ dev_test/main.ipynb | 60 +++++++++++ .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 199 bytes .../__pycache__/get_info.cpython-311.pyc | Bin 0 -> 11526 bytes push_rss_update/__init__.py | 0 push_rss_update/send_email.py | 0 rss_subscribe/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 194 bytes .../push_article_update.cpython-311.pyc | Bin 0 -> 4907 bytes rss_subscribe/last_articles.json | 44 ++++++++ rss_subscribe/push_article_update.py | 96 ++++++++++++++++++ 12 files changed, 264 insertions(+), 3 deletions(-) create mode 100644 dev_test/last_articles.json create mode 100644 friend_circle_lite/__pycache__/__init__.cpython-311.pyc create mode 100644 friend_circle_lite/__pycache__/get_info.cpython-311.pyc create mode 100644 push_rss_update/__init__.py create mode 100644 push_rss_update/send_email.py create mode 100644 rss_subscribe/__init__.py create mode 100644 rss_subscribe/__pycache__/__init__.cpython-311.pyc create mode 100644 rss_subscribe/__pycache__/push_article_update.cpython-311.pyc create mode 100644 rss_subscribe/last_articles.json create mode 100644 rss_subscribe/push_article_update.py diff --git a/conf.yml b/conf.yml index 412bf28..58a4e35 100644 --- a/conf.yml +++ b/conf.yml @@ -1,6 +1,23 @@ # 爬虫相关配置 spider_settings: - enable: true # 是否启用爬虫 - json_url: "https://blog.qyliu.top/friend.json" # 请填写对应格式json的地址,仅支持网络地址 - article_count: 5 # 请填写每个博客需要获取的最大文章数量 + enable: true # 是否启用爬虫 + json_url: "https://blog.qyliu.top/friend.json" # 请填写对应格式json的地址,仅支持网络地址 + article_count: 5 # 请填写每个博客需要获取的最大文章数量 + +# 邮箱推送功能配置 +email_push: + enabled: true # 是否启用邮箱推送功能 + to_email: recipient@example.com # 收件人邮箱地址 + subject: "今天的 RSS 订阅更新" # 邮件主题 + body_template: "rss_template.html" # 邮件正文的 HTML 模板文件 + +# SMTP 配置 +smtp: + email: your_email@example.com # 发件人邮箱地址 + server: smtp.example.com # SMTP 服务器地址 + port: 587 # SMTP 端口号 + use_tls: true # 是否使用 TLS 加密 + username: your_smtp_username # SMTP 用户名 + password: your_smtp_password # SMTP 密码 + diff --git a/dev_test/last_articles.json b/dev_test/last_articles.json new file mode 100644 index 0000000..e5ea8d0 --- /dev/null +++ b/dev_test/last_articles.json @@ -0,0 +1,44 @@ +{ + "articles": [ + { + "title": "东软软件园实习日记", + "author": "", + "link": "https://blog.qyliu.top/posts/13e6e155/", + "published": "2024-07-01 08:39", + "summary": "大学生累成狗,今天我终于理解了为什么这么说,好不容易结束了为期七天的实训课程,又要写实验报告加小组作业,好不容易完成了小组作业,这不,十五天实习又来了!烦!并且还要天天写学习日志?我直接当作日记写好不好!", + "content": "大学生累成狗,今天我终于理解了为什么这么说,好不容易结束了为期七天的实训课程,又要写实验报告加小组作业,好不容易完成了小组作业,这不,十五天实习又来了!烦!并且还要天天写学习日志?我直接当作日记写好不好!" + }, + { + "title": "Github Action实现友链状态检测", + "author": "", + "link": "https://blog.qyliu.top/posts/c2262998/", + "published": "2024-06-23 17:00", + "summary": "随着友情链接数量的增加,人工检测变得繁琐,我最初尝试通过爬取数据进行检测,但数据更新滞后。在群友安小歪的启发下,我采用了GitHub Action自动运行检测脚本,比较有效实现了友链有效性的自动化监测,同时将数据展示在了友情链接页面中,除此之外,原有的摸鱼页面也被我整合到了友链朋友圈页面中。", + "content": "随着友情链接数量的增加,人工检测变得繁琐,我最初尝试通过爬取数据进行检测,但数据更新滞后。在群友安小歪的启发下,我采用了GitHub Action自动运行检测脚本,比较有效实现了友链有效性的自动化监测,同时将数据展示在了友情链接页面中,除此之外,原有的摸鱼页面也被我整合到了友链朋友圈页面中。" + }, + { + "title": "安全跳转页面·插件版", + "author": "", + "link": "https://blog.qyliu.top/posts/1dfd1f41/", + "published": "2024-06-16 17:00", + "summary": "经过两个月的努力,我终于找到了完美的外链跳转解决方案!初始版本使用外置JS存在诸多bug,如图片灯箱、友链和站内跳转链接等问题。经过一段时间的学习和代码调整,我取得了阶段性进展,现在能够实现各种所需功能。最近,我在hexo-external-link插件的基础上进行了底层重构,最终实现了真正的插件版外链替换,不再依赖JS,功能更加完善,且使用更加方便!", + "content": "经过两个月的努力,我终于找到了完美的外链跳转解决方案!初始版本使用外置JS存在诸多bug,如图片灯箱、友链和站内跳转链接等问题。经过一段时间的学习和代码调整,我取得了阶段性进展,现在能够实现各种所需功能。最近,我在hexo-external-link插件的基础上进行了底层重构,最终实现了真正的插件版外链替换,不再依赖JS,功能更加完善,且使用更加方便!" + }, + { + "title": "Alist宝塔部署及其美化", + "author": "", + "link": "https://blog.qyliu.top/posts/a84f5e47/", + "published": "2024-06-04 11:24", + "summary": "Alist 是一个轻量级的目录列表程序,可以用于管理文件索引。将 Alist 部署在宝塔面板中,并进行美化,可以提升用户体验。在本教程中,将介绍我的部署经过,并给出相应的美化代码。", + "content": "Alist 是一个轻量级的目录列表程序,可以用于管理文件索引。将 Alist 部署在宝塔面板中,并进行美化,可以提升用户体验。在本教程中,将介绍我的部署经过,并给出相应的美化代码。" + }, + { + "title": "计算机网络期末总复习", + "author": "", + "link": "https://blog.qyliu.top/posts/8dfa25e1/", + "published": "2024-05-30 16:48", + "summary": "应该注意到标题的改变了吧,本来是一章节一章节的复习,奈何我突然发现,老师画的重点和考研的重点并不是很符合,没办法咯,于是我决定将计算机网络考研复习部分的内容暂时搁置,后面逐步更新,反正一定是会更新的,因为408必考呀!然后将期末复习内容先整理出来,按照老师的考点进行复习。", + "content": "应该注意到标题的改变了吧,本来是一章节一章节的复习,奈何我突然发现,老师画的重点和考研的重点并不是很符合,没办法咯,于是我决定将计算机网络考研复习部分的内容暂时搁置,后面逐步更新,反正一定是会更新的,因为408必考呀!然后将期末复习内容先整理出来,按照老师的考点进行复习。" + } + ] +} \ No newline at end of file diff --git a/dev_test/main.ipynb b/dev_test/main.ipynb index 2f20836..f2d672b 100644 --- a/dev_test/main.ipynb +++ b/dev_test/main.ipynb @@ -195,6 +195,66 @@ "print(f\"feedparser 版本: {feedparser.__version__}\")\n" ] }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "# 将系统路径设置为../\n", + "import sys\n", + "sys.path.append(\"../\")" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{\n", + " \"emails\": [\n", + " \"3162475700@qq.com\"\n", + " ]\n", + "}\n" + ] + } + ], + "source": [ + "from rss_subscribe.push_article_update import extract_emails_from_issues\n", + "import json\n", + "\n", + "api_url = \"https://api.github.com/repos/willow-god/Friend-Circle-Lite/issues\"\n", + "emails = extract_emails_from_issues(api_url)\n", + "print(json.dumps(emails, indent=2))" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "从 https://blog.qyliu.top/ 获取到 5 篇文章,其中 0 篇为新文章\n", + "None\n" + ] + } + ], + "source": [ + "from rss_subscribe.push_article_update import get_latest_articles_from_link\n", + "import json\n", + "\n", + "url = \"https://blog.qyliu.top/\"\n", + "articles = get_latest_articles_from_link(url, last_articles_path=\"../rss_subscribe/last_articles.json\")\n", + "print(articles)" + ] + }, { "cell_type": "code", "execution_count": null, diff --git a/friend_circle_lite/__pycache__/__init__.cpython-311.pyc b/friend_circle_lite/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d0d08520dbf7b6d6e744d8e3c25f49244612cfdd GIT binary patch literal 199 zcmZ3^%ge<81biLMX(0MBh=2h`DC095kTIPhg&~+hlhJP_LlF~@{~09tD=O70CZH%k zy(lp^H#09i#v{bnC*CJ9FTFG|JvGLyC^I!LMb|mAC^;up*C(?iH6|ssEWRYQxFkkT zFD4Bv9iI%Aj?V!}$H!;pWtPOp>lIY~;;_lhPbtkwwJTx;S_N`UF+Y&_z|6?V_<;dN I6fpzE0KK|1<^TWy literal 0 HcmV?d00001 diff --git a/friend_circle_lite/__pycache__/get_info.cpython-311.pyc b/friend_circle_lite/__pycache__/get_info.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0edce972c81f927461e685bc2d9f3fba80c265eb GIT binary patch literal 11526 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 XugHyLeu~H?elm}=q=?xBtKk0t+8DS* literal 0 HcmV?d00001 diff --git a/push_rss_update/__init__.py b/push_rss_update/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/push_rss_update/send_email.py b/push_rss_update/send_email.py new file mode 100644 index 0000000..e69de29 diff --git a/rss_subscribe/__init__.py b/rss_subscribe/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/rss_subscribe/__pycache__/__init__.cpython-311.pyc b/rss_subscribe/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..188f927fb38712524f322ccf0165952e1b101c14 GIT binary patch literal 194 zcmZ3^%ge<81k691(?IlN5CH>>P{wCAAY(d13PUi1CZpdAx zUQAJOaeQ%UQgL!oW>RWQe0*kJW=VX!UP0wA4x8Nkl+v73yCPPgEg*Lk^8<+w%#4hT M9~fXn5i?K>0N=PWY5)KL literal 0 HcmV?d00001 diff --git a/rss_subscribe/__pycache__/push_article_update.cpython-311.pyc b/rss_subscribe/__pycache__/push_article_update.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..600191dbd5a4bf283e7e6180a2b47e044ef35dea GIT binary patch literal 4907 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