博客圖牀遷移記

微博圖牀一時爽,遷移火葬場python

前幾天在羣裏看到說新浪微博圖牀掛掉了,圖牀上的圖片連接單獨訪問還能夠,可是在博客文章上就顯示不出來了。web

去本身網站上看一下,果真,連博客首頁圖片都加載不出來了,極大地影響了閱讀體驗呀。正則表達式

還好圖片連接是能夠訪問的,這就意味着圖片還在,還來得及作遷移和備份。json

回顧以前用了好多免(hao)費(yang)圖(mao)牀,從最先的 七牛,到 Cloudinary,再到 微博圖牀。七牛因爲是臨時域名,沒有及時備份圖片,致使圖都沒了,而 Cloudinary 和 微博圖牀 倒仍是能夠繼續訪問的。不過這種薅羊毛總不是個辦法,萬一服務商政策變了,又得再遷移圖片了。api

果真,免費的纔是最貴的。服務器

利用 VPS 搭建圖牀

考慮到還有個 VPS 主機每月都在續費呢,而且 15 G 的存儲空間和 1T 的流量也徹底夠用了,就在 VPS 上面搭建 本身的圖牀微信

正式搭建以前,還有一些準備工做,首先就是要有本身的 VPS ,若是你也想使用 Vultr 的主機,能夠經過以下的連接進行註冊,得到 $50 的優惠~~~網絡

https://www.vultr.com/?ref=7845784-4F
複製代碼

將本身的域名解析到服務器地址,同時還須要安裝配置好 NginxPHP 等環境。網站

服務器的配置能夠使用 LNMP一鍵安裝包 一鍵安裝包。ui

域名的話,我在萬網註冊的,可是 DSN 解析使用的是 cloudflare ,這樣就能夠使用 HTTPS 了,因爲我是在子域名上搭建的圖牀程序,因此還得在 cloudflare 中添加子域名的解析才行。

完成以上工做,就能夠利用 Chevernote 程序來搭建圖牀了。

Chevernote 的安裝過程仍是比較簡單的,基本上按照步驟就行了,中間可能要設置一些權限問題和 Nginx 配置。

自動遷移圖片到 Chevernote 圖牀

安裝好 Chevernote 以後就能夠開始將圖片遷移到圖牀上了。

Chevernote 有個 API 接口,正好能夠經過圖片連接,將圖片上傳到圖牀上,經過這個接口就能搞定遷移了,前提的要拿到本身的 api key 。

// 經過該接口上傳圖片
GET http://mysite.com/api/1/upload/?key=12345&source=http://somewebsite/someimage.jpg&format=json
複製代碼

簡單地寫了個 Python 腳原本實現自動替換:

import os
import re
import requests

class ReplaceImage:

    path = ''
    lineNum = 0
    s = r'http[s]?://(?:ws1.sinaimg.cn|res.cloudinary.com)/.*?(?:jpg|png)'
    subpath = ''
    key=''
    upload_url = ''
    failednum = 0
    payload = {'key': key, 'source': upload_url, 'format': 'json'}

    website = 'https://image.glumes.com/api/1/upload/'

    def __init__(self):
        self.url_re = re.compile(self.s)

    def search(self, path,key):
        self.path = path
        self.handleDir(path)
        self.key = key

    def handleDir(self, path):
        dirs = os.listdir(path)
        for d in dirs:
            subpath = os.path.join(path, d)
            if os.path.isfile(subpath) and subpath.endswith(".md"):
                self.handleFile(subpath)
            elif os.path.isdir(subpath):
                self.handleDir(subpath)

        print("program end")

    def handleFile(self, fileName):
        print("\n")
        print("start read file %s..." % fileName)
        self.subpath = fileName

        f = open(fileName, 'r+')
        self.lineNum = 1
        data = ""
        while True:
            line = f.readline()
            if not line:
                break
            line = self.replaceImage(line)
            self.lineNum = self.lineNum + 1
            data += line
        f.close()

        with open(fileName, "w+") as f:
            f.writelines(data)

    def replaceImage(self, line):

        searchResult = self.searchImage(line)

        if not searchResult:
            return line
        oldline = line

        for result in searchResult:
            replace_url = self.uploadImage(result)
            line = self.replaceLine(line, result, replace_url)

        print("before replace is %s" % oldline)
        print("after replace is %s" % line)

        return line

    def searchImage(self, line):
        if self.url_re.search(line):
            all_search = search.url_re.findall(line)
            return all_search
        else:
            return []

    def replaceLine(self, line, search, url):
        return line.replace(search, url)

    def uploadImage(self, url):

        print("start uploadImage and file name is %s line num is %d..." % (self.subpath, self.lineNum))

        self.payload['source'] = url
        r = requests.get(self.website, self.payload)
        res = r.json()

        statuscode = res['status_code']

        if statuscode == 400:
            print("upload failed and code is %d and msg is %s" % (statuscode,res['error']['message']))
            print("upload image failed is %s and linenum is %d" % (url, self.lineNum))
            self.failednum += 1
            return url
        else:
            print("upload success and code is %d" % statuscode)
            print("upload img %s to %s" % (url, res['image']['url']))
            return res['image']['url']

if __name__ == "__main__":
    search = ReplaceImage()
    print("please input dir path and api key:\n")
    dir = input("dir:")
    key = input("key:")
    search.search(dir, key)
複製代碼

實現思路也比較簡單:

  1. 首先是要遍歷給定目錄中的全部文件夾和文件。
  2. 逐行讀取文件內容,而後利用正則表達式匹配 Cloudinary 和微博圖牀的圖片連接,找到該行中符合條件的連接。
  3. 再使用 requests 庫作網絡請求,向 Chevernote 的 API 發送 GET 請求,解析返回的 JSON 數據,獲得上傳圖牀後的連接。
  4. 將該行中匹配的圖片連接替換成上傳圖牀後獲得的連接,並寫入文件中。
  5. 讀取完當前文件後,重複步驟二,繼續讀取文件,直到讀取結束。

代碼的實現也比較簡單,主要就是一個正則表達式的匹配了:

s = r'http[s]?://(?:ws1.sinaimg.cn|res.cloudinary.com)/.*?(?:jpg|png)'
複製代碼

使用上面的表達式,就能夠匹配到想要的內容,要注意在括號 () 表示或的匹配前面有 ?: ,不然拿到的匹配內容不對。

執行上述的代碼,輸入正確的文件地址和 api key,而後等待一段時間,就完成了上傳到圖牀並自動轉換的功能。

不足之處

用本身的圖牀也有不足之處,除了訪問速度沒有國內的圖牀速度快,還有就是萬一 VPS 掛了,那圖牀又 GG 了,一個方案就是:把 GitHub 當作備份的圖牀。

由於圖片是存儲在 VPS 具體目錄下的,能夠把圖片所在目錄當作工程,而後上傳到 Github ,萬一哪天 VPS 掛了,就把文章中的連接替換成 Github 上的連接就行了。

歡迎關注微信公衆號:【紙上淺談】,得到最新文章推送~~~

掃碼關注
相關文章
相關標籤/搜索