需求背景:
因为最近写blog用markdown,本地写图片不知上传到哪里合适,有以下几个备选方案:
- 自己搭一个图床服务器(pass, 因为要考虑持久性)
- github(pass, 因为项目必须开源,挂载git上实在太难看了)
- 留一个图床的文章(pass, 操作过于繁琐, 还要切浏览器)
- 公有图床(应用方案)
最后选用的图床api是: SM.MS, api简单易用, 可以自主上传和删除, 自15年开始运营至现在,持久性还不错
功能实现:
- 封装api
没什么好说的,python的requests包,分别封装了上传,最近上传列表和删除接口,代码如下:
LIST_URL = "https://sm.ms/api/list"
UPLOAD_URL = "https://sm.ms/api/upload"
CLEAR_URL = "https://sm.ms/api/clear"
def get_history():
params = {'ssl': 0, 'format': 'json'}
r = requests.get(LIST_URL, params)
print(r.json())
def upload(filePath):
if not os.path.isfile(filePath):
print('要上传的文件不存在')
return
data = {'smfile': open(filePath, 'rb')}
r = requests.post(UPLOAD_URL, files=data)
print(r.json())
log(r.json())
def clear_history():
r = requests.get(CLEAR_URL);
print(r.json())
log(r.json())
日志记录:
因为文件的链接和删除链接都在上传成功后返回的json中,需要记录上传后的结果, 这里做的比较简单, 做了一个日志文件追加写入.参数解析:
因为要做成脚本运行,需要对参数进行解析,python原生的获取参数的方法是sys.argv,没有参数解析和校验,这里使用自带的getopt包解析参数.
getopt包的使用方法:
语法格式: opt, arg = getopt.getopt(args, options [,long_options])
参数说明:
- args: 要解析的命令行参数, 用sys获取时需要从第一个参数获取, 因为第0个参数是启动的文件名, 既
args = sys.argv[1:]
- options: 以字符串格式定义的-短参数,option后的(:)表示选项需要有附件参数, 不带(:) 表示选项不需要附加参数
- long_options: 已列表形式定义的--长参数, long_options后的(=) 表示选项需要附加参数
- 返回一个由(opt,value)元组的列表和一个参数列表
脚本运行方法:
- 上传文件:
python3 gallery.py -u [filepath]
运行结果:
- 查看最近上传列表:
python3 gallery.py -l
- 删除上传文件
python3 gallery.py -d
完整的脚本代码:
#!/usr/bin/env python3
import os
import sys
import getopt
from datetime import date, datetime
import requests
LIST_URL = "https://sm.ms/api/list"
UPLOAD_URL = "https://sm.ms/api/upload"
CLEAR_URL = "https://sm.ms/api/clear"
LOG_FILE_PATH = "gallery.log"
def get_history():
params = {'ssl': 0, 'format': 'json'}
r = requests.get(LIST_URL, params)
print(r.json())
def upload(filePath):
if not os.path.isfile(filePath):
print('要上传的文件不存在')
return
data = {'smfile': open(filePath, 'rb')}
r = requests.post(UPLOAD_URL, files=data)
print(r.json())
log(r.json())
def clear_history():
r = requests.get(CLEAR_URL);
print(r.json())
log(r.json())
def log(message):
logFile = os.path.join(os.path.curdir, LOG_FILE_PATH)
with open(logFile, 'w+') as f:
f.write(datetime.now().strftime('%Y-%m-%d %H:%M:%S') + '%s%s' % (message, '\r\n'))
if __name__ == '__main__':
args = sys.argv[1:]
try:
opts, arg = getopt.getopt(args, "u:ld", ["upload=", "list", "delete"])
except getopt.GetoptError:
print('参数解析错误')
for opt, arg in opts:
if opt in ('-u', '--upload'):
upload(arg)
elif opt in ('-l', '--list'):
get_history()
elif opt in ('-d', '--delete'):
clear_history()
else:
print('''参数错误, 参数选项为:
上传文件: -u | --upload=[filePath]
查看最近上传列表: -l | --list
删除最近上传: -d | --delete ''')
附:
参数解析的参考用例
import sys
import getopt
def main(argv):
"""
通过 getopt模块 来识别参数demo, http://blog.csdn.net/ouyang_peng/
"""
username = ""
password = ""
try:
"""
options, args = getopt.getopt(args, shortopts, longopts=[])
参数args:一般是sys.argv[1:]。过滤掉sys.argv[0],它是执行脚本的名字,不算做命令行参数。
参数shortopts:短格式分析串。例如:"hp:i:",h后面没有冒号,表示后面不带参数;p和i后面带有冒号,表示后面带参数。
参数longopts:长格式分析串列表。例如:["help", "ip=", "port="],help后面没有等号,表示后面不带参数;ip和port后面带冒号,表示后面带参数。
返回值options是以元组为元素的列表,每个元组的形式为:(选项串, 附加参数),如:('-i', '192.168.0.1')
返回值args是个列表,其中的元素是那些不含'-'或'--'的参数。
"""
opts, args = getopt.getopt(argv, "hu:p:", ["help", "username=", "password="])
except getopt.GetoptError:
print('Error: test_arg.py -u -p ')
print(' or: test_arg.py --username= --password=')
sys.exit(2)
# 处理 返回值options是以元组为元素的列表。
for opt, arg in opts:
if opt in ("-h", "--help"):
print('test_arg.py -u -p ')
print('or: test_arg.py --username= --password=')
sys.exit()
elif opt in ("-u", "--username"):
username = arg
elif opt in ("-p", "--password"):
password = arg
print('username为:', username)
print('password为:', password)
# 打印 返回值args列表,即其中的元素是那些不含'-'或'--'的参数。
for i in range(0, len(args)):
print('参数 %s 为:%s' % (i + 1, args[i]))
if __name__ == "__main__":
# sys.argv[1:]为要处理的参数列表,sys.argv[0]为脚本名,所以用sys.argv[1:]过滤掉脚本名。
main(sys.argv[1:])