前言
几天前我搭建了自己的wiki网站,打算有时间就把本地的笔记(md格式)上传到网站上去,这样方便我方便地查看我的知识体系。我wiki网站用的是hexo+github+Wikitten主题,支持md,而且能通过github很方便地更新。本地笔记用的是vnote
,这个笔记软件非常好用,就有一点:因为我做笔记的时候为了方便和数据安全,所有的图片全都存在本地,vnote为我生成的链接是类似![](_v_images/20191012183346115_26004.png =500x)
的,我还不能手动下载笔记内的图片,只能到_v_images
文件夹内找到它。
试想一下,我要把我的笔记传到wiki上需要几步?
有图片的情况下,首先要在vnote中打开笔记,切换成编辑模式,看一下图片的名字,然后打开图片文件夹,搜索到这张图片,上传到图床,返回链接替换本地链接……想想就兴致全无。
基于此,我用python写了一个小程序,可以帮我自动做以上的事。
思路
给定一个文件夹,需要遍历文件夹内所有md文件,这个好做,只要判断后缀就行了。
file[-2:] == 'md'
接下来要复制到目标路径中,毕竟我不想改动原文件,这个用shutil.copy
。
然后打开md文件,搜索本地图片链接,这里需要用到正则表达式,但是我不知道如何全文替换,只能用最笨的方法,找到一个替换一个。
pattern = re.compile(r'_v_images/.+\s??=??\d*?x??')
replacelist = pattern.findall(content)
for each in replacelist:
content = pattern.sub(pic_url +')',content,count = 1)
这里面有个小问题,我不知道为什么正则会替换掉本地图片格式的最后一个括号,只能手动加上一个了。
替换的中间,还需要一个上传到图床的函数,我首先找了支持api的图床,发现免费的没多少,最后选择了sm.ms。它的api有两种,api1是不需要账号的,但是似乎有频率的限制,api2需要账号,每个账号给5g的空间。先拿api1练练手。
url='https://sm.ms/api/upload'
file_obj=open(pic_path,'rb')
file={'smfile':file_obj} # 参数名称必须为smfile
pic_url = data_result['data']['url']
但是每次都要上传图片太傻了,因为我可能会经常改动笔记,再次转化的时候会有大量已经上传过的图片,不说图床的频率限制,上传图片也要比较长的时间,更何况即使上传了sm.ms也会提示你图片重复,所以最好有个图片检测机制,如果已经上传过,就获取存储在本地的已经上传好的图片链接。
于是我选择了mongodb数据库,配合hashlib
生成的图片hash值进行检测。
这下程序就基本完成了。
代码
# -*- coding: utf-8 -*-
"""
Created on Fri Sep 13 13:14:22 2019
self.
@author: 雁陎
"""
import os
import re
from shutil import copy
from requests import post
from hashlib import sha1
import pymongo
def copyfile(org_path,copy_path):
current_folder = os.listdir(org_path) # 路径下所有文件组成一个列表
for file in current_folder:
if file[-2:] == 'md':
file_path = org_path+'\\'+ file # 拼接出要存放的文件夹的路径
copy(file_path,copy_path) # 将指定的文件file复制到file_dir的文件夹里面
def openmd(org_path,copy_path): # 替换url链接
myclient = pymongo.MongoClient("mongodb://localhost:27017/") # 连接数据库
mydb = myclient["mdpicture"] # 创建数据库
mycol = mydb["hash_url"] # 创建集合(数据表)
pattern = re.compile(r'_v_images/.+\s??=??\d*?x??')
for file in os.listdir(copy_path):
file_path = copy_path+'\\'+ file
with open(file_path,'r+',encoding = "utf-8") as handler:
content = handler.read()
handler.seek(0)
handler.truncate()
replacelist = pattern.findall(content)
for each in replacelist:
pic_name = each[:int(each.index(r'.')+4)]
pic_path = org_path+'\\'+pic_name.replace('/','\\')
pic_url = upload(mycol,pic_path,pic_name)
if pic_url:
content = pattern.sub(pic_url +')',content,count = 1)
# 不知为什么正则替换会把最后一个括号替换掉,所以只能手动加了一个
handler.write(content)
print(file,"链接已经转化完毕")
def calchash(filepath): # 计算图片hash值
with open(filepath,'rb') as f:
sha1obj = sha1()
sha1obj.update(f.read())
hash = sha1obj.hexdigest()
return hash
def upload(mycol,pic_path,pic_name): # 上传图片至sm.ms
url='https://sm.ms/api/upload'
try:
file_obj=open(pic_path,'rb')
file={'smfile':file_obj} # 参数名称必须为smfile
pic_hash = calchash(pic_path)
# 先检查是否上传过,若无才进行上传
if mycol.find_one({"hash": pic_hash}):
print('查询mongodb,图片',pic_name,'已存在')
result = mycol.find_one({"hash": pic_hash})['url']
else:
data_result=post(url,data=None,files=file).json()
if data_result['message'] == 'Upload success.':
mycol.insert_one({"hash":pic_hash,"url":data_result['data']['url'],"delete":data_result['data']['delete']})
print(pic_name,'上传成功,链接为',data_result['data']['url'],'删除链接为',data_result['data']['delete'])
result = data_result['data']['url']
elif data_result['message'][0:21] == 'Image upload repeated':
print(pic_name,'上传失败,图片已存在')
result = None
else:
print('其他错误')
result = None
except FileNotFoundError:
print(pic_name,'图片未找到,请检查该图是否存在')
result = None
return result
def main():
org_path = r'E:\vnote笔记数据\待转区' # 原始路径
copy_path = r'E:\vnote笔记数据\转化完成区' # 目标路径,原始路径的md会将所有图片转为url后放到这里
copyfile(org_path,copy_path)
openmd(org_path,copy_path)
if __name__ == '__main__':
main()
版权属于:作者名称
本文链接:https://www.sitstars.com/archives/35/
转载时须注明出处及本声明