Python小程序之「读取站点地图 自动为Gitalk创建Issues」

首发于个人博客
想获得更好的阅读体验,烦请移步⬆️

前言

前些天给博客加了评论功能,试了Disqus、Valine等一干评论系统,最后还是选择了在大陆相对友好而且符合技术博客风格的Gitalk。但是由于Gitalk是利用Github里Repo的Issue实现评论功能,所以每篇博文都需要手动创建Issue,很是麻烦。于是就打算用Python写一个自动初始化的脚本。

Gitalk的原理

知己知彼,百战不殆。写脚本之前,我们得先知道Gitalk是通过什么确定文章和Issue之间的关系的。通过查看文档可以得到下面👇四个我们需要的参数。

参数 类型 说明 默认值
id String 页面的唯一标示,长度小于50 location.href
labels Array Issue的标签 ['Gitalk’]
title String Issue的标题 document.title
body String Issue的内容 location.href + header.meta[description]

那么再看看Gitalk初始化时自动生成的Issue:

在被这张图中,四个参数的值分别为:

title: "渲染测试 | Dicerorhinus"
labels: ['Gitalk','/post/themes-test.html']
body: "https://rhinoc.top/post/themes-test.html"

诶,id去哪了?
其实,labels中的第二个元素post/themes-test.html就是id了。

现在我们对这四个参数有了更好地理解,可以开始写程序了。

流程图

  +-----------------------------+
  |                             |
  |       get urls from         |
  |        sitemap.xml          |
  |                             |
  +--------------+--------------+
                 |
                 |
                 |
  +--------------v--------------+
  |                             |
  |     login into Github       |
  |     get the repository      |
  |                             |
  +--------------+--------------+
                 |
                 |
                 |
+----------------v-----------------+
|                                  |
|   for every url in urls          |
|   create issue                   |
|   if its issue haven't created   |
|                                  |
+----------------------------------+

几个要点

id须在50个字符以内

文档中已经指明了id和博文一对一的关系,并且在Gitalk自动生成的Issue中,id被设置为是博文所在的相对路径。由于id被限制在50个字符以内,所以当相对路径比较长时,就不适合作为id了,这时候可以使用MD5将相对路径编码:

def md5(s):
    hash = hashlib.md5()
    hash.update(s.encode('utf8'))
    return hash.hexdigest()

由于我的博客中博文的相对路径在50个字符以内,所以并未采用MD5编码。

防止重复创建Issue

由于程序每次运行都要遍历一遍sitemap.xml,而一遍来说我们的博客中只有新写的博文没有创建Issue,如果不对「已初始化」和「未初始化」的链接加以区分,就会重复创建Issue。

所以,我们需要有一个数据库来储存哪些链接是已初始化过的,遍历sitemap.xml时,将其中的网址和数据库内容对比,对不在数据库中的网址进行初始化并写入数据库。

代码

import bs4, requests
from github import Github
from urllib.parse import unquote

blogUrl = 'https://***.***.***'
sitemapUrl = 'https://***.***.***/sitemap.xml'
user = 'username'
token = ''
repoFullName = "user/repo"

session = requests.Session()
res = session.get(sitemapUrl)

readExistUrl = open('urls.txt','r')
writeExistUrl = open('urls.txt','a')
existList = readExistUrl.readlines()

# get urls from sitemap
def getSite(smUrl):
    html = requests.get(smUrl)
    soup = bs4.BeautifulSoup(html.text,"lxml")
    urls = soup.select('loc')
    urlset = []
    for url in urls:
        url = str(url)[5:-6]
        url = url.replace('http','https')
        urlset.append(url)
    return urlset

urls = getSite(sitemapUrl)
gh = Github(login_or_token = token)
repo = gh.get_repo(repoFullName)

for url in urls:
    if ((url + '\n') in existList) or (url in existList):
        continue
    title = url.rsplit('/',2)
    title = unquote(title[2])
    labels = ['Gitalk', url[18:]]
    repo.create_issue(title = title ,body = url,labels = labels)
    writeExistUrl.write('\n'+url)
    print(url + ' created')
    
readExistUrl.close()
writeExistUrl.close()
posted @ 2019-02-09 22:53  rhinoc  阅读(547)  评论(4编辑  收藏  举报