转换本地obsidian markdown路径为图床url
动机和作用
写博客, 本地的markdown. 比如要把本地用obsidian写的笔记上传到博客园或者其它的地方, 以前特别麻烦, 那就是一张一张打开图片, 然后拷贝到剪切板, 然后在博客编辑器粘贴. 下面这个脚本解决了这个问题. 执行方式是script_name markdown文件的path -o 目标路径
, -o可以省略, 这样就是输出到终端.
你们可能会说, typora不就已经提供了图床功能么?
但我不能接受如果不联网, 自己的笔记都查看不了了.
代码是在这个基础上改的. 用的是sm.ms图床. 需要先注册, 获得api token.
代码
需要修改绝对路径(搜索quebec), api key. 以及, 如果你不是obsidian, 还需要改一下正则表达式, 和Replace中的逻辑.
TU
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
# 使用sm.ms 实现图床上传脚本
import requests
import json
import sys
import os
import re
import argparse
# 引入PIL库,实现图片缩放
# from PIL import Image
# 图片缩放
def zoom(origin_file, width):
set_width = width
im = Image.open(origin_file)
# 获得图像尺寸:
w, h = im.size
# 缩放倍率
prop = w / set_width
set_height = h / prop
# 缩放
im.thumbnail((set_width, set_height))
# 返回image对象
return im
class Replace:
def __init__(self):
self.count = 0
self.db=DB('/Users/quebec/box/image_hosting/image_url_sm_ms.sqlite')
def __call__(self, mo):
full_path = "/Users/quebec/notes/vx_attachments/" + mo.group(1)
ret = self.db.get(full_path)
if(ret):
new_path = ret
else:
ret = self.upload(full_path)
# self.count+=1
if(ret["status"]):
new_path = ret['data']
self.db.put(full_path, new_path)
else:
raise TypeError(f"error: {ret['data']}")
# return f"![]({new_path})"
width = mo.group(4) if mo.group(4) else 600
return f'<img src="{new_path}" alt="drawing" width="{width}"/>'
@classmethod
def upload(cls,path):
upload_url='https://sm.ms/api/v2/upload'
files = {'smfile': open(path, 'rb')}
# 发起请求
headers = {'Authorization': ''} # 这里填你的api
r = requests.post(upload_url, files=files, headers=headers)
if r.status_code == requests.codes.ok:
# 把字符串装换成字典
return_data = json.loads(r.text)
if return_data['code'] == 'success':
return {'status': True, 'data': return_data['data']['url']}
else:
return_data = json.loads(r.text)
# sys.exit(return_data)
return {'status': False, 'data': return_data}
def main():
parser = argparse.ArgumentParser(description='convert local obsidian path to url')
parser.add_argument('source_path', help='obsidian markdown file')
parser.add_argument('-o', dest='target_path', required = False, help='target path')
args = parser.parse_args()
fh = open(args.source_path, 'rt', encoding='utf8')
text=fh.read()
fh.close()
# text = "![[Pasted image 20211004220118.png|600]] and more"
repl = Replace()
new_text = re.sub(r"!?\[\[([^\]]+.(png|jpg|jpeg))(\|(\d+))?\]\]", repl, text, flags=re.IGNORECASE)
# 检查图片参数是否输入
if(args.target_path):
fh_o = open(args.target_path, 'wt', encoding='utf8')
fh_o.write(new_text)
fh_o.close()
else:
print(new_text)
#%%
# 图片上传
class DB:
def __init__(self, sqlite_db_path):
from sqlitedict import SqliteDict
self.mydict = SqliteDict(sqlite_db_path, autocommit=True)
self.db_path = sqlite_db_path
def put(self, key, value):
self.mydict[key] = value
def get(self, key):
return self.mydict.get(key)
def __del__(self):
self.mydict.close()
if __name__ == "__main__":
main()