1. 程式人生 > >Python小程序之「讀取站點地圖 自動為Gitalk創建Issues」

Python小程序之「讀取站點地圖 自動為Gitalk創建Issues」

lose lec des hashlib token ont repos 閱讀 md5

首發於個人博客
想獲得更好的閱讀體驗,煩請移步??

前言

前些天給博客加了評論功能,試了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()

Python小程序之「讀取站點地圖 自動為Gitalk創建Issues」