push本地仓库中的文档至远程mrdoc平台
push前自动查找本地仓库中的文档与平台文集内文档名字的差异
可通过指定本地文档仓库中的地址来更新网站的文档
可直接通过选项-a来自动查找本地与远程有差异的文档进行更新
由于没有delete的api所以不能同步进行delete操作
目前此脚本只适用于windows
解决了打包的时候本地上传到平台上字符集乱码、更新旧文档麻烦、上传新文档麻烦的问题一行命令就可以完成想要的操作
QQ群:766160484
# V0.2.3 2022-10-27
修复了在-a,--updatelall指令执行时文集不存在导致的报错问题
=============
# V0.2.2 2022-9-8
发布了一个Pyinstaller打包的exe版本
将配置信息移到json文件了
=============
# V0.2.1 2022-8-28
修复了文件名特殊字符导致的找不到文件、抛异常
建议更新
=============
# V0.2.0 2022-8-27
新增两条选项-a --updateall
解决:修改文档内容较多的时候一个一个上传较麻烦的问题
-a选项:拿本地所有文档内容和远程文档内容作差异比较 将有差异的文档更新
--updateall选项:指定一个仓库的子目录(二级目录) 在此目录下的文档和远程文档做差异比较将有差异的文档更新
优化代码逻辑,修复文件名有若干空格导致的报错和重复上传问题
=============
# V0.1.2 2022-8-25
新增一条命令选项-s
解决:本地文档改名后与网站文档名不一致导致的更新失败
新增自动创建文集功能
解决:本地新建 文集(子文件夹) 后网站文集未更新的问题
将原有的复杂命令现在改为选项
修复有文档在本地仓库主目录时的报错问题(现在不允许有文档在主目录了)
在push之前会检查本地文集与网站文集是否都存在,不存在则会先创建再进行文档检查
=============
# V0.1.1 2022-8-24
新增文档更新功能
命令:doctools --update ${文档路径}
=============
# V0.1.0 2022-8-23
开始编写
支持一键push
命令:doctools --push
==========
1.下载MrDocTools.zip解压后存放在单独的文件夹内
2.将此文件夹添加到系统环境变量 名字:DOCTOOLS_HOME 再将 %DOCTOOLS_HOME% 添加到path
3.编辑config.json文件 配置指定内容详情查看2.3
1.下载MrDocToolsExe.zip解压后存放在单独的文件夹内
2.将此文件夹添加到系统环境变量 名字:DOCTOOLS_HOME 再将 %DOCTOOLS_HOME% 添加到path
3.编辑config.json文件 配置指定内容详情查看2.3
)
d 现在你就可以打开cmd输入 doctools -h会有以下输出信息
w 然后请确认您的本地文档仓库存放目录是否是以下结构
d 注意! 子目录名称就是网站上对应的文集名称
d 注意! 存放图片视频等文件的文件夹务必命名成src 否则脚本会当成文档上传导致报错!
# 主目录
- 子目录1
- 分目录1
- 分目录2
- 分目录n...
- 子目录2
- 分目录1
- 分目录n...
- 子目录3
- 分目录n...
- 子目录n...
w 我的目录结构:
# F:\.md\mrdoc
- F:\.md\mrdoc\Java高级知识笔记
- F:\.md\mrdoc\Java高级知识笔记\Java常用类
- F:\.md\mrdoc\Java高级知识笔记\多线程
- 目录n......
- F:\.md\mrdoc\Java基础部分笔记
- F:\.md\mrdoc\Java基础部分笔记\总和
- F:\.md\mrdoc\Java基础部分笔记\接口
- F:\.md\mrdoc\部分自动化脚本共享
- 目录n......
d 目录需要有三层结构 主目录-子目录-分目录 (可以有无数个上述目录,但是分目录下还有子目录就不获取了,并且仓库根目录不能存放文档)
d 当你完成了上述操作再将你的文档按照文件目录规范放进去,就可以使用脚本来push了
s 在cmd中输入
doctools -p
如果push成功会有日志输出并且在网站刷新后会有本地仓库push上去的文档
i 命令: doctools
i -h | --help: 帮助
i -p | --push: doctools -p
s 将本地文档仓库内的文档全部推送
i -u | --update: doctools -u <要更新的文档本地文档仓库路径>
s 指定一个已存在网站上的文档 在本地仓库内的文档地址,更新至网站
i -s | --updates: doctools -s <旧的文档名> <新文档的文档本地文档仓库路径>
s 如果你的新文档与网页上的文档文档名不一致会无法更新 此命令第一个参数是旧文档名字 第二个参数是本地新文档地址
i -a | --updateall: doctools -a
s 本地文档与远程文档进行差异比较,将有差异的文档更新
s doctools --updateall
s 指定一个本地文档仓库的子目录(二级目录)与远程文档进行差异比较,将有差异的文档更新
# coding:utf-8
import getopt
import json
import sys
import requests
import os
global base_url # 网站地址
global token # 用户token 在个人中心处获得
global file_path # 设置本地文档仓库位置
ExistsEocCount = 0
SonFolder = ''
folder = ''
tFileCopy = []
address = []
allAddress = []
idCount = []
wrongFile = []
cmdin = sys.argv
# 获取文档标题(暂时弃用)
def getFileTiitle(f1):
with open(f1, encoding='utf-8') as f:
try:
firstLine = f.readlines()[0].rstrip()
except:
firstLine = '# TEST'
return firstLine
# 过滤掉地址和后缀返回文档名称
def getUrlFileName(f):
return os.path.basename(f).split('.')[0]
# 获取文档内容
def getFile(f):
filen = ''
try:
with open(f, encoding='utf-8') as file_obj:
for line in file_obj:
filen += line
return filen
except FileNotFoundError:
print('路径"{}"错误'.format(f))
sys.exit(0)
# 子目录下文档查找
def addIsFile(docfile, tl, name, dir, id, existsEocCount):
count = 0
for docFileData in docfile['data']:
if tl.split('.')[0].replace(" ", "") == docFileData['name']:
count += 1
existsEocCount += 1
continue
if count == 0:
allAddress.append(dir + '\\' + name + "\\" + tl)
idCount.append(id)
return existsEocCount
# 获取指定Url文档夹下的所有文档
def getFileList(u):
result = [f for f in os.listdir(u)
if os.path.isfile(os.path.join(u, f))]
return result
# 获取当前token用户现有文集
def getAnthology():
url = base_url + '/api/get_projects/?token={}'.format(token)
resp = requests.get(url=url)
return resp.json()
# 获取网站文档的所有集合
def getDocList(pid):
url = base_url + '/api/get_docs/?token={}'.format(token)
data = {
'pid': pid,
'sort': 0
}
resp = requests.get(url=url, params=data)
return resp.json()
def getDoc(did):
url = base_url + '/api/get_doc/?token={}'.format(token)
data = {
'did': did,
}
resp = requests.get(url=url, params=data)
return resp.json()
# 推送新的文档
def pushDoc(pid, title, doc):
url = base_url + '/api/create_doc/?token={}'.format(token)
data = {
'pid': pid,
'title': title.strip('#').rstrip().replace(" ", ""),
'doc': doc
}
resp = requests.post(url=url, data=data)
return resp.json()
# 更新文档
def setUpdate(pid, did, title, doc):
url = base_url + '/api/modify_doc/?token={}'.format(token)
data = {
'pid': pid,
'did': did,
'title': title.strip('#').rstrip(),
'doc': doc
}
resp = requests.post(url=url, data=data)
return resp.json()
# 创建文集
def createAnthology(name, desc):
url = base_url + '/api/create_project/?token={}'.format(token)
data = {
'name': name,
'desc': desc,
'role': 0
}
resp = requests.post(url=url, data=data)
return resp.json()
# 检测文集是否创建 如果没有会自动创建
def testingAnthology():
global tmp
anthology = getAnthology()['data']
localFolder = os.listdir(file_path)
for i in localFolder:
if os.path.isfile(file_path + "\\" + i):
value = '仓库根目录下不允许存在文档!此文档目录无法有效获取!请将仓库根目录下文档移动至子目录!'
print(f"\033[0;31m{value}\033[0m")
print("仓库根目录下:" + file_path + " 有文档:" + i)
print("请将文档放置在子目录下")
print("地址:" + file_path + "\\" + i)
sys.exit()
tmp = False
for j in anthology:
if j['name'] == i:
tmp = True
break
else:
tmp = False
if not tmp:
status = createAnthology(i, '系统自动创建,请及时修改简介')['status']
if status:
print('已创建文集: "{}"'.format(i))
def push(news):
# 获取文集
if news: print("获取远程文集中")
anthology = getAnthology()
anthologyPidNameJson = {}
anthologyNamePidJson = {}
for data in anthology['data']:
anthologyNamePidJson[data['name']] = data['id']
anthologyPidNameJson[data['id']] = data['name']
# 获取本地仓库文集列表
if news: print("获取本地文集中")
localAnyhologyNameJson = {}
localDocNameLink = {}
dir = os.listdir(file_path)
for name in dir:
link = file_path + '\\' + name
if not os.path.isfile(link):
dir1 = os.listdir(link)
for name2 in dir1:
if os.path.isfile(link + '\\' + name2) and name2.split('.')[1] == 'md':
localAnyhologyNameJson[name2.split('.')[0]] = name
localDocNameLink[name2.split('.')[0]] = link + '\\' + name2
continue
else:
dir2 = os.listdir(link + '\\' + name2)
for name3 in dir2:
if os.path.isfile(link + '\\' + name2 + '\\' + name3) and name3.split('.')[1] == 'md':
localAnyhologyNameJson[''.join(name3.split()).split('.')[0]] = name
localDocNameLink[''.join(name3.split()).split('.')[0]] = link + '\\' + name2 + '\\' + name3
# 获取远程文档和文集列表
if news: print("正在对比")
anyhologyNameJson = {}
for data in anthologyPidNameJson:
docJson = getDocList(data)
for data1 in docJson['data']:
anyhologyNameJson[''.join(data1['name'].split())] = anthologyPidNameJson[data]
addJson = {}
for name in localAnyhologyNameJson:
if name not in anyhologyNameJson:
addJson[name] = anthologyNamePidJson[localAnyhologyNameJson[name]]
docCount = len(addJson)
print("本地共有:{}篇文档 {}篇文档待推送".format(len(localDocNameLink), docCount))
if docCount > 0:
okCOunt = 0
errCount = 0
for data in addJson:
print("正在推送:{}---{}".format(addJson[data], data))
status = pushDoc(addJson[data], getUrlFileName(localDocNameLink[data]), getFile(localDocNameLink[data]))
if status['status']:
okCOunt += 1
else:
print("{}---{}推送失败 原因:{}".format(addJson[data], data, status))
print("共:{}篇 成功:{} 失败{}".format(len(addJson), okCOunt, errCount))
return True
else:
return False
# 更新文档
def update(arg):
folder = arg.split('\\')
home = file_path.split('\\')
if len(folder) > len(folder):
anthologyName = folder[len(folder)]
else:
anthologyName = folder[len(home)]
folder2 = "".join(os.path.basename(arg).split())
data = getAnthology()['data']
pid = 0
did = 0
for i in data:
if i['name'] == anthologyName:
pid = i['id']
data = getDocList(pid)['data']
for j in data:
if j['name'] + '.md' in folder2:
did = j['id']
result = setUpdate(pid, did, "".join(getUrlFileName(arg).split()), getFile(arg))
if result['status']:
print('更新文档: "{}" 成功'.format("".join(getUrlFileName(arg).split())))
else:
print('更新文档: "{}" 失败'.format("".join(getUrlFileName(arg).split())) + '-原因: {}'.format(result))
# 更新所有本地与远程有差异的文档
def updateAll(dir):
print("正在进行更新前push操作")
if not push(False):
print("没有可上传文档")
print("==================================")
print("正在获取本地仓库中的文档")
if len(dir) > 0:
localDocLinkList = []
dirList = os.listdir(dir)
for data in dirList:
if os.path.isfile(dir + '\\' + data) and data.split('.')[1] == 'md':
localDocLinkList.append(dir + '\\' + data)
continue
dirList1 = os.listdir(dir + '\\' + data)
for data1 in dirList1:
if os.path.isfile(dir + '\\' + data + '\\' + data1) and data1.split('.')[1] == 'md':
localDocLinkList.append(dir + '\\' + data + '\\' + data1)
else:
firstLevelDir = os.listdir(file_path)
dirList = []
localDocLinkList = []
# 获取本地文档仓库中的文集列表
for dir in firstLevelDir:
if os.path.isfile(file_path + '\\' + dir):
continue
dirList.append(dir)
# 从本地文集列表中拿到所有文档的地址
for docName in dirList:
secondLevelDir = os.listdir(file_path + '\\' + docName)
for docFileLink in secondLevelDir:
if os.path.isfile(file_path + '\\' + docName + '\\' + docFileLink) and docFileLink.split(".")[
1] == 'md':
localDocLinkList.append(file_path + '\\' + docName + '\\' + docFileLink)
continue
threeLevelDir = os.listdir(file_path + '\\' + docName + '\\' + docFileLink)
for docFileLink1 in threeLevelDir:
if os.path.isfile(file_path + '\\' + docName + '\\' + docFileLink + '\\' + docFileLink1) and \
docFileLink1.split('.')[1] == 'md':
localDocLinkList.append(file_path + '\\' + docName + '\\' + docFileLink + '\\' + docFileLink1)
cloudDidJson = {}
# 将本地的文档名提取出来
docNameList = []
for name in localDocLinkList:
tlist = name.split('\\')
tlist = tlist[len(tlist) - 1].split('.')
docNameList.append(tlist[0])
# 吧文档名和对应的路径转换为json数据
docNameJson = {}
i = 0
for add in docNameList:
docNameJson[add] = localDocLinkList[i]
i += 1
# 通过传统的update方法更新
# for link in docNameJson:
# update(docNameJson[link])
# 过滤去重文集name列表
newList = []
for name in localDocLinkList:
folder = name.split('\\')
home = file_path.split('\\')
if len(folder) > len(folder):
anthologyName = folder[len(folder)]
else:
anthologyName = folder[len(home)]
newList.append(anthologyName)
newList = list(set(newList))
print("正在获取远程文档信息")
# 远程去获取文集id
anthology = getAnthology()
for data in anthology['data']:
for name1 in newList:
if data['name'] == name1:
cloudDidJson[name1] = data['id']
break
# 拿一下远程所有文档的信息保存为json数据
docJson = {}
for wName in cloudDidJson:
docJson[wName] = getDocList((cloudDidJson.get(wName)))
print("正在获取本地文档内容")
localdocNameDataJson = {}
for localDocName in docNameJson:
localdocNameDataJson[localDocName] = getFile(docNameJson[localDocName])
print("差异比较中......")
# 通过拿到的文档信息再拿一下文档的id和文档内容
docNameDidJson = {} # docName : Did
docNamePidJson = {} # docName : Pid
anthologyPidNameJson = {}
docNameDataJson = {}
for data in docJson:
for data1 in docJson[data]['data']:
docNameDidJson["".join(data1['name'].split())] = data1['id']
docNamePidJson["".join(data1['name'].split())] = cloudDidJson[data]
anthologyPidNameJson[cloudDidJson[data]] = data
docData = getDoc(data1['id'])['data']
docNameDataJson[''.join(docData['name'].split())] = docData['md_content']
updateDocNameJson = {}
for docName in docNameJson:
try:
if localdocNameDataJson[docName] != docNameDataJson[''.join(docName.split())]:
updateDocNameJson[docName] = docNameJson[docName]
except KeyError:
print('文档名有特殊字符或空格 请修改后上传 文档名=”{}“ '.format(docName))
print("本地共有文档{} 有差异的文档:{}".format(len(localdocNameDataJson), len(updateDocNameJson)))
if len(updateDocNameJson) > 0:
okCount = 0
ErrCount = 0
for j in updateDocNameJson:
pid = docNamePidJson["".join(j.split())]
did = docNameDidJson["".join(j.split())]
docName = getUrlFileName(updateDocNameJson[j])
print("推送 '{}' : '{}' 中".format(anthologyPidNameJson[pid], j))
result = setUpdate(pid, did, docName, getFile(updateDocNameJson[j]))
if result['status']:
okCount += 1
else:
ErrCount += 1
print("文集 '{}' : '{}' 更新失败,原因{}".format(anthologyPidNameJson[pid], docName, result))
print("==================================")
print("推送完成 共:{}个差异 成功:{}个 失败:{}个".format(len(updateDocNameJson), okCount, ErrCount))
# 旧文档名字和新文档不一致的更新方法
def ifNameUpdate(oldName, newAddress):
essayName = newAddress[0].split('\\')
home = file_path.split('\\')
if len(folder) > len(essayName):
anthologyName = essayName[len(essayName)]
else:
anthologyName = essayName[len(home)]
try:
if oldName.split('.')[1] == 'md':
oldName = oldName.split('.')[0]
except Exception:
pass
data = getAnthology()['data']
pid = 0
did = 0
for i in data:
if i['name'] == anthologyName:
pid = i['id']
data = getDocList(pid)['data']
for j in data:
if j['name'] in oldName:
did = j['id']
tmpi = len(newAddress[0].split("\\"))
result = setUpdate(pid, did, getUrlFileName(newAddress[0].split("\\")[tmpi - 1]), getFile(newAddress[0]))
if result['status']:
print('更新文档: 旧:"{}" ---->>'.format(oldName) + '新: "{}" 成功!'.format(newAddress[0].split("\\")[tmpi - 1]))
else:
print('更新文档: "{}" 失败'.format(oldName) + '-原因: {}'.format(result))
print("可能是旧文档名不正确!")
def main(argv):
global args
try:
opts, args = getopt.getopt(argv[1:], "hpau:s:", ["help", "push", "update=", "updates=", "updateall="])
except Exception:
opts = [('-h', '')]
print("命令错误")
for opt, arg in opts:
if opt in ("-h", "--help"):
print('-选项后带: --选项后带= 代表有参数')
print('-h | --help: 帮助')
print('-p | --push: doctools -p'
' \n 将本地文档仓库内的文档全部推送')
print('-u: | --update=: doctools -u <Local address of documentation>'
' \n 指定一个本地仓库内的文档地址,更新至网站')
print('-s: | --updates=: doctools -s <Old document name> <New document local address>'
' \n 如果你的新文档与网页上的文档文档名不一致会无法更新 此命令第一个参数是旧文档名字 第二个参数是本地新文档地址')
print('-a | --updateall=: doctools -a '
' \n 本地文档与远程文档进行差异比较,将有差异的文档更新'
' \n : doctools --updateall <Specify a sub warehouse>'
' \n 指定一个本地文档仓库的子目录(二级目录)与远程文档进行差异比较,将有差异的文档更新')
sys.exit()
elif opt in ("-p", "--push"):
# 本地文件夹(文集)与平台文集做查找 没有就新增
testingAnthology()
if not push(True):
print('没有任何新的文档,如需获取帮助可以-h 或 --help')
elif opt in ("-u", "--update"):
try:
update(arg)
except IndexError:
print("参数错误")
os.system('doctools -h')
elif opt in ("-s", "--updates"):
ifNameUpdate(arg, args)
elif opt in ("-a", "--updateall"):
testingAnthology()
updateAll(arg)
else:
print("没有{}此选项".format(opt))
if __name__ == "__main__":
env = os.environ.get("DOCTOOLS_HOME")
if env is None:
print("请在系统内配置脚本所在路径的环境变量:DOCTOOLS_HOME")
sys.exit()
try:
with open('{}/config.json'.format(env), 'r', encoding='utf8') as fp:
json_data = json.load(fp)
base_url = json_data['base_url']
token = json_data['token']
file_path = json_data['file_path']
except KeyError:
print("json config file key is not exists")
sys.exit(0)
except FileNotFoundError:
print("json config file is not exists")
sys.exit(0)
except:
print("配置文件有误")
sys.exit(0)
if sys.argv[1] == '-h' or sys.argv[1] == '--help':
main(sys.argv)
elif len(file_path) == 0 or len(token) == 0 or len(base_url) == 0:
print("首次使用脚本请在 {} 目录下的config.json内配置对应信息".format(env))
else:
try:
main(sys.argv)
except KeyboardInterrupt:
print("程序被手动终止!")
sys.exit(0)
except Exception as e:
print('请检查您 的参数 如果有bug可将问题和报错信息复现发送至邮箱:2784404835@qq.com qq群:766160484')
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。