如何用 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模拟登录百度贴吧(百度贴吧登录)实例
Dec 18 Python
python目录操作之python遍历文件夹后将结果存储为xml
Jan 27 Python
python控制台英汉汉英电子词典
Apr 23 Python
解决Python print 输出文本显示 gbk 编码错误问题
Jul 13 Python
django项目搭建与Session使用详解
Oct 10 Python
详解Django的model查询操作与查询性能优化
Oct 16 Python
修改默认的pip版本为对应python2.7的方法
Nov 06 Python
实例讲解Python中浮点型的基本内容
Feb 11 Python
python实现的按要求生成手机号功能示例
Oct 08 Python
python配置文件写入过程详解
Oct 19 Python
Python搭建HTTP服务过程图解
Dec 14 Python
关于python的缩进规则的知识点详解
Jun 22 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 缓存函数代码
2008/08/27 PHP
怎样去阅读一份php源代码
2009/08/21 PHP
linux下删除7天前日志的代码(php+shell)
2011/01/02 PHP
php 5.4 全新的代码复用Trait详解
2017/01/05 PHP
JS getStyle获取最终样式函数代码
2010/04/01 Javascript
js下关于onmouseout、事件冒泡的问题经验小结
2010/12/09 Javascript
javascript中的对象创建 实例附注释
2011/02/08 Javascript
js 判断浏览器使用的语言示例代码
2014/03/22 Javascript
JavaScript中统计Textarea字数并提示还能输入的字符
2014/06/10 Javascript
教你如何使用firebug调试功能了解javascript闭包和this
2015/03/04 Javascript
在JavaScript的正则表达式中使用exec()方法
2015/06/16 Javascript
jQuery实现的网页左侧在线客服效果代码
2015/10/23 Javascript
Jquery1.9.1源码分析系列(六)延时对象应用之jQuery.ready
2015/11/24 Javascript
JS清除文本框内容离开在恢复及鼠标离开文本框时触发js的方法
2016/01/12 Javascript
Javascript实现图片轮播效果(一)让图片跳动起来
2016/02/17 Javascript
详解Vue自定义过滤器的实现
2017/01/10 Javascript
js插件实现图片滑动验证码
2020/09/29 Javascript
浅谈使用mpvue开发小程序需要注意和了解的知识点
2018/05/23 Javascript
详解easyui 切换主题皮肤
2019/04/04 Javascript
JavaScript实现五子棋游戏的方法详解
2019/07/08 Javascript
[02:03]《现实生活中的DOTA2》—林书豪&DOTA2职业选手出演短片
2015/08/18 DOTA
怎样使用Python脚本日志功能
2016/08/14 Python
对python 生成拼接xml报文的示例详解
2018/12/28 Python
解决Pycharm界面的子窗口不见了的问题
2019/01/17 Python
pyinstaller将含有多个py文件的python程序做成exe
2020/04/29 Python
英国最大的百货公司:Harrods
2016/08/18 全球购物
GLAMGLOW香港官网:明星出镜前的秘密武器
2017/03/16 全球购物
JNI的定义
2012/11/25 面试题
JVM是一个编译程序还是解释程序
2012/09/11 面试题
超市业务员岗位职责
2013/12/05 职场文书
大学生专科学习生活的自我评价
2013/12/07 职场文书
大四本科生的自我评价
2013/12/30 职场文书
网络编辑岗位职责
2014/03/18 职场文书
幼儿园开学寄语
2014/04/03 职场文书
新颖的化妆品活动方案
2014/08/21 职场文书
2014年医院后勤工作总结
2014/12/06 职场文书