如何用 Python 制作 GitHub 消息助手


Posted in Python onFebruary 20, 2021

在互联网2.0时代,工程师解决业务问题主要依赖的是自己掌握的各种工具和软件伴随着席卷全球的开源浪潮,开源工具和软件也迅猛增长。工程师需要关注的技术和软件也随之越来越多,学习负担越来越大,大脑也越来越不够用。但工程师们也很无奈,因为谁掌握的技术和软件越多,谁就能更高效的解决问题。于是工程师们开始借助互联网外脑工具:尤其是搜索引擎、书签、github、scihub等 而工程师们解决问题的能力就体现在了对外脑工具的利用上。
但是,随着工程师们要解决的问题增长以及自身知识的积累,外脑工具也逐渐变得臃肿:书签越来越多,github的订阅越来越多,多到最后就约等于没有书签、没有订阅了。为了解决这些问题,我们需要更智能灵活的外脑工具,能让我们从信息的海洋中解放出来,让我们能更加专注自身业务。

GitHub 消息的问题

如何用 Python 制作 GitHub 消息助手

有没有发现你的 Github 消息 Inbox 过几天不处理,就会堆积成山呢?相信有的同学 Inbox 里的数字比这个还要夸张,甚至有的同学已经绝望的放弃了 Inbox 这个功能。
为什么会这样?
因为每个Coder内心大多都会喜欢收藏喜爱的作品,而github的项目主页右上角最醒目的位置总是摆着这三个按钮:

如何用 Python 制作 GitHub 消息助手

相信工程师们看到喜爱的项目,就会毫不犹豫的一键三连:watch、start、fork。
悲剧也就从这里开始了。
1、工程师喜欢的项目越来越多;
2、项目会有自己的生命周期,有的变得活跃,有的逐渐消亡;
3、工程师越来越忙,无暇顾及Inbox。
然后,Inbox就变这样了:

如何用 Python 制作 GitHub 消息助手

看着满是堆积的消息,是不是有种崩溃的感觉。那github的功能到底出了什么问题?
我认为是 watch、star、fork 需要工程师投入的关注程度搞错了。当然现在github也在积极改进,相比以前,我们可以发现有了更多的 watch 选项:

如何用 Python 制作 GitHub 消息助手

但是仅仅这些就够了吗?看着 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不变则不需要,所以第一次我们只能先手工输入一次。

如何用 Python 制作 GitHub 消息助手

不过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

登录完成后,我们需要进入收件箱,查看到底有哪些未读消息。收件箱有点小复杂,不过也还能很方便的区分。

如何用 Python 制作 GitHub 消息助手

找到了正确的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 按钮的操作:

如何用 Python 制作 GitHub 消息助手

到这里就完成了GitHub消息助手的全部逻辑,整个Inbox终于清静了,是不是可以喝杯咖啡惬意一下了。

如何用 Python 制作 GitHub 消息助手

后记

Python自动化工具的确是给工程师们带来了便捷,使得工程师能应对各种日常不同的挑战。为方便各位工程师小伙伴们早日解脱、得偿所愿,以上代码已开源,完整的代码地址:
https://gitee.com/knifecms/puppetry/blob/master/github-agent/resp_notify.py
另外,该项目下,还有几个其他有意思的自动化助手和工具哟,大家感兴趣的话也可以研究研究。
希望得到你的更多好点子!

以上就是如何用 Python 制作 GitHub 消息助手的详细内容,更多关于Python 制作 GitHub 消息助手的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
21行Python代码实现拼写检查器
Jan 25 Python
利用Python脚本生成sitemap.xml的实现方法
Jan 31 Python
用python结合jieba和wordcloud实现词云效果
Sep 05 Python
解决python中 f.write写入中文出错的问题
Oct 31 Python
Python实现爬取亚马逊数据并打印出Excel文件操作示例
May 16 Python
通过字符串导入 Python 模块的方法详解
Oct 27 Python
Python for循环搭配else常见问题解决
Feb 11 Python
Python逐行读取文件内容的方法总结
Feb 14 Python
PyCharm2020最新激活码+激活码补丁(亲测最新版PyCharm2020.2激活成功)
Nov 25 Python
在python中对于bool布尔值的取反操作
Dec 11 Python
Python自动化之批量处理工作簿和工作表
Jun 03 Python
python文件与路径操作神器 pathlib
Apr 01 Python
详解tf.device()指定tensorflow运行的GPU或CPU设备实现
Feb 20 #Python
Python 的 f-string 可以连接字符串与数字的原因解析
Feb 20 #Python
安装不同版本的tensorflow与models方法实现
Feb 20 #Python
python爬虫scrapy基本使用超详细教程
Feb 20 #Python
解决pip安装tensorflow中出现的no module named tensorflow.python 问题方法
Feb 20 #Python
conda安装tensorflow和conda常用命令小结
Feb 20 #Python
TensorFlow低版本代码自动升级为1.0版本
Feb 20 #Python
You might like
整合了前面的PHP数据库连接类~~做成一个分页类!
2006/11/25 PHP
php whois查询API制作方法
2011/06/23 PHP
php通过字符串调用函数示例
2014/03/02 PHP
windows下配置apache+php+mysql时出现问题的处理方法
2014/06/20 PHP
php去掉URL网址中带有PHPSESSID的配置方法
2014/07/08 PHP
php实现文件预览功能
2017/05/23 PHP
为Yahoo! UI Extensions Grid增加内置的可编辑器
2007/03/10 Javascript
jquery选择器使用详解
2014/04/08 Javascript
四种参数传递的形式——URL,超链接,js,form表单
2015/07/24 Javascript
js创建数组的简单方法
2016/07/27 Javascript
JS中的hasOwnProperty()、propertyIsEnumerable()和isPrototypeOf()
2016/08/11 Javascript
javascript 内置对象及常见API详细介绍
2016/11/01 Javascript
vue使用Axios做ajax请求详解
2017/06/07 Javascript
JavaScript实现跟随滚动缓冲运动广告框
2017/07/15 Javascript
Vue页面跳转动画效果的实现方法
2018/09/23 Javascript
JavaScript事件对象深入详解
2018/12/30 Javascript
vue中watch和computed为什么能监听到数据的改变以及不同之处
2019/12/27 Javascript
JavaScript基于面向对象实现的无缝滚动轮播示例
2020/01/17 Javascript
js实现单元格拖拽效果
2020/02/10 Javascript
[02:30]联想杯DOTA2完美世界全国高校联赛—北京站现场
2015/11/16 DOTA
python 实现归并排序算法
2012/06/05 Python
Python描述器descriptor详解
2015/02/03 Python
Python字符串逐字符或逐词反转方法
2015/05/21 Python
python实现超简单的视频对象提取功能
2018/06/04 Python
pytorch之添加BN的实现
2020/01/06 Python
python开发一个解析protobuf文件的简单编译器
2020/11/17 Python
python 实现socket服务端并发的四种方式
2020/12/14 Python
css3实现书本翻页效果的示例代码
2021/03/08 HTML / CSS
HTML5 video标签(播放器)学习笔记(一):使用入门
2015/04/24 HTML / CSS
公司年会策划方案
2014/05/17 职场文书
饭店服务员岗位职责
2015/02/09 职场文书
重阳节慰问信
2015/02/15 职场文书
篮球赛闭幕式主持词
2015/07/03 职场文书
婚宴来宾致辞
2015/07/28 职场文书
2016年教师党员创先争优承诺书
2016/03/24 职场文书
sql server偶发出现死锁的解决方法
2022/04/10 SQL Server