如何用 Python 制作 GitHub 消息助手
作者:邵可佳 发布时间:2021-05-15 03:54:44
目录
GitHub 消息的问题
解决方案
代码实现
0.环境准备
1、模拟登录github
2.模拟进入Inbox
3.检查僵尸项目
4.取消关注僵尸项目
5.删除僵尸项目消息
后记
在互联网2.0时代,工程师解决业务问题主要依赖的是自己掌握的各种工具和软件伴随着席卷全球的开源浪潮,开源工具和软件也迅猛增长。工程师需要关注的技术和软件也随之越来越多,学习负担越来越大,大脑也越来越不够用。但工程师们也很无奈,因为谁掌握的技术和软件越多,谁就能更高效的解决问题。于是工程师们开始借助互联网外脑工具:尤其是搜索引擎、书签、github、scihub等 而工程师们解决问题的能力就体现在了对外脑工具的利用上。
但是,随着工程师们要解决的问题增长以及自身知识的积累,外脑工具也逐渐变得臃肿:书签越来越多,github的订阅越来越多,多到最后就约等于没有书签、没有订阅了。为了解决这些问题,我们需要更智能灵活的外脑工具,能让我们从信息的海洋中解放出来,让我们能更加专注自身业务。
GitHub 消息的问题
有没有发现你的 Github 消息 Inbox 过几天不处理,就会堆积成山呢?相信有的同学 Inbox 里的数字比这个还要夸张,甚至有的同学已经绝望的放弃了 Inbox 这个功能。
为什么会这样?
因为每个Coder内心大多都会喜欢收藏喜爱的作品,而github的项目主页右上角最醒目的位置总是摆着这三个按钮:
相信工程师们看到喜爱的项目,就会毫不犹豫的一键三连:watch、start、fork。
悲剧也就从这里开始了。
1、工程师喜欢的项目越来越多;
2、项目会有自己的生命周期,有的变得活跃,有的逐渐消亡;
3、工程师越来越忙,无暇顾及Inbox。
然后,Inbox就变这样了:
看着满是堆积的消息,是不是有种崩溃的感觉。那github的功能到底出了什么问题?
我认为是 watch、star、fork 需要工程师投入的关注程度搞错了。当然现在github也在积极改进,相比以前,我们可以发现有了更多的 watch 选项:
但是仅仅这些就够了吗?看着 Inbox 动辄上万条的消息,难道要将自己关注的项目一个个的修改为 Ignore?
工程师的内心依然是崩溃的!
有没有办法拯救工程师的Inbox?
有!来吧,自己动手拯救我的收件箱。
解决方案
用 python 做一个 GitHub 消息助手,自动帮工程师关闭和删除不必要的消息。这不也就是真正意义上的Watch吗?你看它的时候,会接收它的信息,你不看了它就消失了。那么仔细想想,到底哪些消息真正对工程师有用呢?
1、已经很久没更新的项目,是不是就可以不关注了?
2、已经不是工作范围和兴趣点的项目,是不是也可以不关注了?
3、已经很久都没人反馈问题的项目,是不是也可以不关注了?
而python有一个优势就是可以很方便的实现用户操作的自动化 嗯,看起来这些僵尸项目都可以用python自动化的方式清除掉 说干就干,让我们开始吧!
代码实现
我们知道Python有一款很棒的Web自动化测试框架:Selenium,但 Selenium 主要还是用于测试,调用还是略显复杂。所以笔者在github上搜刮了一番,终于找到一款合适的Python包:PyChrome 项目地址:
https://github.com/siversalih/pyChrome-Web-Automation
下面我们就用这款非主流的自动化工具包,完成我们的小助手 看主页,这个作者很懒,几年前就没有更新了,但幸好说明帮助还是挺全的:
https://pychrome.wordpress.com/usage/
所以我们就可以 happy 的按照说明书来组装机器人了。
0.环境准备
首先需要准备Python 3.8环境,然后按照网上说明安装 Selenium,接下来将PyChrome项目 clone到本地。ok,环境准备完成。
1、模拟登录github
使用PyChrome访问github有个小麻烦,每次都会启动一个全新的Chrome浏览器实例。这就导致无法重复利用保存在本地的cookie信息,所以每次要模拟登陆下。github有一个特点,如果ip变更,需要输入验证码,如果ip不变则不需要,所以第一次我们只能先手工输入一次。
不过github的登录页面相对简单,只需要找到Username和password对应的表单组件就可以了。所以登录的代码可以非常简洁,如下所示:
browser.open("https://github.com/login")
# name="login"
name_locator = "//*[@name='login']"
el_name = browser.findElementByXPath(name_locator)
browser.sendTextToElement(username, el_name)
# name="password"
pass_locator = "//*[@name='password']"
el_pass = browser.findElementByXPath(pass_locator)
browser.sendTextToElement(password,el_pass)
login_locator = "//*[@name='commit']"
el_login = browser.findElementByXPath(login_locator)
browser.clickElement(el_login)
2.模拟进入Inbox
登录完成后,我们需要进入收件箱,查看到底有哪些未读消息。收件箱有点小复杂,不过也还能很方便的区分。
找到了正确的xpath,相信定位也不是难事。这里我又取了个巧,我们被困扰的其实是有消息的项目,如果一个项目不发消息,我们其实也不会被骚扰到。所以直接选取左下角的 Repositories 区域似乎效率更高一些。
代码如下:
browser.open("https://github.com/notifications")
# 获取有消息的Repositories列表
locator = "js-notification-sidebar-repositories"
el_repos = browser.findElementByClass(locator)
repos_list = browser.findElementsByTag("li", el_repos)
3.检查僵尸项目
我选用第三条策略,已经很久没人反馈问题的项目作为判断僵尸项目的标准(纯粹只是因为方便实现),首先访问issue,然后判断issue里的更新日期,恰好有一个详细的日期字段。下面代码目的很简单,就是获取最后一条issue更新了多久。
browser.newTab("https://github.com/" + repos_name + "/pulls?q=")
# 判断最近的 pull request
locator = "//div[@aria-label='Issues']"
el_pulls = browser.findElementByXPath(locator)
pull_list = browser.findElementsByTag("relative-time", el_pulls)
timedelta = 0
if type(pull_list)==list and len(pull_list)>0:
# 2020-11-10T00:55:39Z
# last_pull_time_str = pull_list[0].getAttribute("datetime")
last_pull_time_str = pull_list[0].get_attribute("datetime")
last_time = datetime.strptime(last_pull_time_str, "%Y-%m-%dT%H:%M:%SZ")
timedelta = (datetime.now() - last_time).days
logger.debug(repos_name + " timedelta: " + str(timedelta) + " days")
4.取消关注僵尸项目
如果issue已经超过了1年,自然就应该取消关注了,毕竟目前信息更新的速度太快了。
# 取消不活跃项目的订阅(1年以上没有pull request)
if unsubscribe and timedelta > 366:
el_notify_button =browser.findElementsByTag("notifications-list-subscription-form")
browser.clickElement(el_notify_button)
time.sleep(1)
# data-target="notifications-list-subscription-form.menu"
locator = "//*[@data-target='notifications-list-subscription-form.menu']"
el_notify_menus = browser.findElementByXPath(locator)
# value="ignore"
sub_locator = "//*[@value='ignore']"
el_ignore_button =browser.findElementByXPath(sub_locator, el_notify_menus)
browser.clickElement(el_ignore_button)
logger.debug(repos_name + " cancel subscribed")
5.删除僵尸项目消息
最后,该是解除困扰的时候了,这种不再更新的项目,工程师自然也不要再被它的消息骚扰。
el_repos_link = browser.findElementByTag("a", repos)
browser.clickElement(el_repos_link)
# mr-1 js-notifications-mark-all-prompt
time.sleep(1)
el_sel_all =browser.findElementByClass("js-notifications-mark-all-prompt")
browser.clickElement(el_sel_all)
time.sleep(1)
# title="Done"
done_locator = "//*[@title='Done']"
el_done = browser.findElementByXPath(done_locator)
browser.clickElement(el_done)
logger.debug(repos_name + " remove notifiy")
以上代码就是模拟 Done 按钮的操作:
到这里就完成了GitHub消息助手的全部逻辑,整个Inbox终于清静了,是不是可以喝杯咖啡惬意一下了。
后记
Python自动化工具的确是给工程师们带来了便捷,使得工程师能应对各种日常不同的挑战。为方便各位工程师小伙伴们早日解脱、得偿所愿,以上代码已开源,完整的代码地址:
https://gitee.com/knifecms/puppetry/blob/master/github-agent/resp_notify.py
另外,该项目下,还有几个其他有意思的自动化助手和工具哟,大家感兴趣的话也可以研究研究。
希望得到你的更多好点子!
来源:https://mp.weixin.qq.com/s/MW03yGN65nTucOEslLcLoA


猜你喜欢
- 本文实例讲述了mysql实现合并同一ID对应多条数据的方法。分享给大家供大家参考,具体如下:如 :CREATE TABLE `c_class
- 刚刚上网搜了一下如何用python统计列表中不同元素的数量,发现很少,找了半天。我自己来写一种方法。代码如下list=[1,1,2,2,3]
- 惊云JS随机排序程序随机显示信息-每次新闻显示顺序都不一样<script type=text/javascript>//////
- 很多朋友在论坛和留言区域问mysql在什么情况下才需要进行分库分表,以及采用何种设计方式才是最优的选择,根据这些问题,小编为大家整理了关于M
- RateLimit 限流中间件为什么需要限流中间件在大数据量高并发访问时,经常会出现服务或接口面对大量的请求而导致数据库崩溃的情况,甚至引发
- 在讲CSS优先级之前,我们得要了解什么是CSS,CSS是用来做什么的。首先,我们对CSS作一个简单的说明:CSS是层叠样式表(Cascadi
- 背景介绍作为一款产品,往往希望能得到用户的反馈,从而通过对用户行为的分析进行功能、交互等方面的改进。然而直接的一对一的用户交流是低效且困难的
- innerHTML,outerHTML innerHTML检索或设置标签内的内容;outerHTML检索或设置整个标签的内容(包含标签)。&
- 前言本篇文章介绍如何查询 Binlog 的生成时间。云上 RDS 有日志管理,但是自建实例没有,该脚本可用于自建实例闪回定位 Binlog
- 最近写的资源策略管理,在ceilometer 中创建alarm时,name要求是不能重复的,所以在创建policy的时候,要对policy的
- 本文介绍了两个asp实用的技巧,一是使用asp强制刷新页面,二是判断一个文件是否存在强制刷新网页 强制性刷新随机验证码 ,让随机验
- python字符串字符串是 Python 中最常用的数据类型。我们可以使用引号('或")来创建字符串。创建字符串很简单,只
- 用Python画一个平面的太阳系得到一些朋友的欣赏,然后有同学提出了绘制三维太阳系的要求。从Python画图的角度来说,三维太阳系其实并不难
- 本文实例讲述了JavaScript实现的鼠标跟随特效。分享给大家供大家参考,具体如下:鼠标是现在电脑的基本配置之一,也是最常用的输入命令的工
- 前言:不知道有多少同学跟我一样,最初接触编程的动机就是为了自己做个游戏玩?今天要给大家分享的是一个 pygame 写的“
- 最近在重构公司以前产品的前端代码,摈弃了以前的session-cookie鉴权方式,采用token鉴权,忙里偷闲觉得有必要对几种常见的鉴权方
- pytorch查看模型model参数parameters示例1:pytorch自带的faster r-cnn模型import torchim
- Filed under 数据库技术Leave a commentSQL Server命令行导数据两种方式bcp和sqlcmd先说一下bcp:
- list解析先看下面的例子,这个例子是想得到1到9的每个整数的平方,并且将结果放在list中打印出来>>> power2
- kruskal算法基本思路:先对边按权重从小到大排序,先选取权重最小的一条边,如果该边的两个节点均为不同的分量,则加入到最小生成树,否则计算