如何用 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 相关文章推荐
Python使用面向对象方式创建线程实现12306售票系统
Dec 24 Python
浅谈numpy库的常用基本操作方法
Jan 09 Python
Python实现的knn算法示例
Jun 14 Python
python实现网页自动签到功能
Jan 21 Python
Python 实现Numpy中找出array中最大值所对应的行和列
Nov 26 Python
python cv2读取rtsp实时码流按时生成连续视频文件方式
Dec 25 Python
关于Tensorflow使用CPU报错的解决方式
Feb 05 Python
如何利用Python动态模拟太阳系运转
Sep 04 Python
flask项目集成swagger的方法
Dec 09 Python
Python3利用openpyxl读写Excel文件的方法实例
Feb 03 Python
pytorch显存一直变大的解决方案
Apr 08 Python
Python编解码问题及文本文件处理方法详解
Jun 20 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中获取变量的变量名的一段代码的bug分析
2011/07/07 PHP
php打开远程文件的方法和风险及解决方法
2013/11/12 PHP
php中引用符号(&)的使用详解
2013/11/13 PHP
19个Android常用工具类汇总
2014/12/30 PHP
PHP实现的猴王算法(猴子选大王)示例
2018/04/30 PHP
纯JS实现动态时间显示代码
2014/02/08 Javascript
Jquery中find与each方法用法实例
2015/02/04 Javascript
jquery利用命名空间移除绑定事件的方法
2015/03/11 Javascript
SpringMVC框架下JQuery传递并解析Json格式的数据是如何实现的
2015/12/10 Javascript
全面解析JavaScript里的循环方法之forEach,for-in,for-of
2020/04/20 Javascript
js操作XML文件的实现方法兼容IE与FireFox
2016/06/25 Javascript
Angularjs中$http以post请求通过消息体传递参数的实现方法
2016/08/05 Javascript
JavaScript用构造函数如何获取变量的类型名
2016/12/23 Javascript
JS+canvas动态绘制饼图的方法示例
2017/09/12 Javascript
JS使用new操作符创建对象的方法分析
2019/05/30 Javascript
[42:06]2019国际邀请赛全明星赛 8.23
2019/09/05 DOTA
详解JavaScript编程中的window与window.screen对象
2015/10/26 Python
浅述python中argsort()函数的实例用法
2017/03/30 Python
JSONLINT:python的json数据验证库实例解析
2017/11/28 Python
selenium+python截图不成功的解决方法
2019/01/30 Python
Python正则表达式如何匹配中文
2020/05/27 Python
Keras自定义实现带masking的meanpooling层方式
2020/06/16 Python
Python  word实现读取及导出代码解析
2020/07/09 Python
Python使用shutil模块实现文件拷贝
2020/07/31 Python
现代家居用品及礼品:LBC Modern
2018/06/24 全球购物
日期和时间问题
2015/01/04 面试题
心理健康心得体会
2014/01/02 职场文书
护士自我评价范文
2014/01/25 职场文书
创业培训计划书
2014/05/03 职场文书
求职简历自荐信
2014/06/18 职场文书
先进教师事迹材料
2014/12/16 职场文书
2016年五一劳动节专题校园广播稿
2015/12/17 职场文书
2016应届毕业生就业指导课心得体会
2016/01/15 职场文书
详解gantt甘特图可拖拽、编辑(vue、react都可用 highcharts)
2021/11/27 Vue.js
Mysql中有关Datetime和Timestamp的使用总结
2021/12/06 MySQL
python使用shell脚本创建kafka连接器
2022/04/29 Python