新增导入Markdown文集对yaml文档元数据的支持

This commit is contained in:
zmister 2021-02-13 11:38:44 +08:00
parent 99ea1309a8
commit e44707f0b6
3 changed files with 183 additions and 31 deletions

View File

@ -5,17 +5,19 @@
# 博客地址zmister.com
# 文集导入相关方法
import shutil
import os
import time
import re
from app_doc.models import Doc,Project,Image
from app_doc.util_upload_img import upload_generation_dir
from django.db import transaction
from django.conf import settings
from loguru import logger
import mammoth
from markdownify import markdownify
import mammoth
import shutil
import os
import time
import re
import yaml
# 导入Zip文集
class ImportZipProject():
@ -52,33 +54,95 @@ class ImportZipProject():
# print(root, new_file)
os.rename(os.path.join(root, file), os.path.join(root, new_file))
# 读取yaml文件
try:
with open(os.path.join(self.temp_dir ,'mrdoc.yaml'),'r',encoding='utf-8') as yaml_file:
yaml_str = yaml.load(yaml_file.read())
project_name = yaml_str['project_name']
project_desc = yaml_str['project_desc']
project_role = yaml_str['project_role']
editor_mode = yaml_str['editor_mode']
project_toc = yaml_str['toc']
toc_item_list = []
for toc in project_toc:
# print(toc)
item = {
'name': toc['name'],
'file': toc['file'],
'parent': 0,
}
toc_item_list.append(item)
if 'children' in toc.keys():
for b in toc['children']:
item = {
'name': b['name'],
'file': b['file'],
'parent': toc['name']
}
toc_item_list.append(item)
if 'children' in b.keys():
for c in b['children']:
item = {
'name': c['name'],
'file': c['file'],
'parent': b['name']
}
toc_item_list.append(item)
except:
logger.error("未发现yaml文件")
project_name = zip_file_path[:-4].split('/')[-1]
project_desc = ''
project_role = 1
editor_mode = 1
project_toc = False
# 开启事务
with transaction.atomic():
save_id = transaction.savepoint()
try:
# 新建文集
project = Project.objects.create(
name=zip_file_path[:-4].split('/')[-1],
intro='',
role=1,
name=project_name,
intro=project_desc,
role=project_role,
create_user=create_user
)
# 遍历临时文件夹中的所有文件和文件夹
for f in os.listdir(self.temp_dir):
# 获取 .md 文件
if f.endswith('.md'):
# print(f)
# 读取 .md 文件文本内容
with open(os.path.join(self.temp_dir,f),'r',encoding='utf-8') as md_file:
if project_toc is False:
# 遍历临时文件夹中的所有文件和文件夹
for f in os.listdir(self.temp_dir):
# 获取 .md 文件
if f.endswith('.md'):
# print(f)
# 读取 .md 文件文本内容
with open(os.path.join(self.temp_dir,f),'r',encoding='utf-8') as md_file:
md_content = md_file.read()
md_content = self.operat_md_media(md_content,create_user)
# 新建文档
doc = Doc.objects.create(
name = f[:-3],
pre_content = md_content,
top_doc = project.id,
status = 0,
editor_mode = editor_mode,
create_user = create_user
)
else:
for i in toc_item_list:
with open(os.path.join(self.temp_dir,i['file']),'r',encoding='utf-8') as md_file:
md_content = md_file.read()
md_content = self.operat_md_media(md_content,create_user)
md_content = self.operat_md_media(md_content, create_user)
# 新建文档
doc = Doc.objects.create(
name = f[:-3],
pre_content = md_content,
top_doc = project.id,
status = 0,
create_user = create_user
name=i['name'],
pre_content=md_content,
top_doc=project.id,
parent_doc = (Doc.objects.get(top_doc=project.id,name=i['parent'])).id \
if i['parent'] != 0 else 0,
status=0,
editor_mode=editor_mode,
create_user=create_user
)
except:
logger.exception("解析导入文件异常")
@ -94,7 +158,6 @@ class ImportZipProject():
logger.exception("删除临时文件异常")
return None
# 处理MD内容中的静态文件
def operat_md_media(self,md_content,create_user):
# 查找MD内容中的静态文件

View File

@ -54,11 +54,71 @@ def import_project(request):
zip_file.write(chunk)
if os.path.exists(temp_file_path):
import_file = ImportZipProject()
project = import_file.read_zip(temp_file_path,request.user)
project = import_file.read_zip(temp_file_path,request.user) # 返回文集id或None
if project:
pro = Project.objects.get(id=project)
docs = Doc.objects.filter(top_doc=project).values_list('id','name')
doc_list = [doc for doc in docs]
return JsonResponse({'status':True,'data':doc_list,'id':project})
# 查询存在上级文档的文档
parent_id_list = Doc.objects.filter(top_doc=project).exclude(
parent_doc=0).values_list('parent_doc', flat=True)
# 获取存在上级文档的上级文档ID
doc_list = []
# 获取一级文档
top_docs = Doc.objects.filter(
top_doc=project,
parent_doc=0).values('id','name').order_by('sort')
for doc in top_docs:
top_item = {
'id': doc['id'],
'field': doc['name'],
'title': doc['name'],
'spread': True,
'level': 1
}
# 如果一级文档存在下级文档,查询其二级文档
if doc['id'] in parent_id_list:
sec_docs = Doc.objects.filter(
top_doc=project,
parent_doc=doc['id']).values('id','name').order_by('sort')
top_item['children'] = []
for doc in sec_docs:
sec_item = {
'id': doc['id'],
'field': doc['name'],
'title': doc['name'],
'level': 2
}
# 如果二级文档存在下级文档,查询第三级文档
if doc['id'] in parent_id_list:
thr_docs = Doc.objects.filter(
top_doc=project,
parent_doc=doc['id'],).values('id','name').order_by('sort')
sec_item['children'] = []
for doc in thr_docs:
item = {
'id': doc['id'],
'field': doc['name'],
'title': doc['name'],
'level': 3
}
sec_item['children'].append(item)
top_item['children'].append(sec_item)
else:
top_item['children'].append(sec_item)
doc_list.append(top_item)
# 如果一级文档没有下级文档,直接保存
else:
doc_list.append(top_item)
return JsonResponse({
'status':True,
'data':doc_list,
'project':{
'id':project,
'name':pro.name,
'desc':pro.intro
}
})
else:
return JsonResponse({'status':False,'data':'上传失败'})
else:

View File

@ -63,10 +63,39 @@
done: function(res){
//上传完毕回调
layer.closeAll('loading'); //关闭loading
// 写入文集数据
$('input[name="project-name"]').val(res.project.name)
$('input[name="project-desc"]').val(res.project.desc)
// 遍历文集的文档
layui.each(res.data,function(index,item){
layui.each(res.data,function(index,item){ // 遍历一级文档
// console.log(index,item)
var doc_ele = '<li data-sortable-id="'+ item[0] +'" class="list-group-item">'+item[1]+'<ul class="list-group nested-sortable"></ul></li>'
// var doc_ele = '<li data-sortable-id="'+ item[0] +'" class="list-group-item">'+item[1]+'<ul class="list-group nested-sortable"></ul></li>'
var doc_ele = '<li data-sortable-id="'+ item['id'] + '" class="list-group-item">'+item['title']
if(item['children'] != undefined){
let li = '<i class="layui-icon layui-icon-down switch-toc"></i><ul class="list-group nested-sortable">';
doc_ele += li;
layui.each(item['children'],function(index,item){ // 遍历二级文档
let li = '<li data-sortable-id="'+ item['id'] + '" class="list-group-item">'+item['title'];
doc_ele += li;
if(item['children'] != undefined){
let li = '<i class="layui-icon layui-icon-down switch-toc"></i><ul class="list-group nested-sortable">';
doc_ele += li;
layui.each(item['children'],function(index,item){
let li = '<li data-sortable-id="'+ item['id'] + '" class="list-group-item">'+item['title'] + '</li>';
})
doc_ele += '</ul>'
}else{
let li = '<ul class="list-group nested-sortable"></ul>'
doc_ele += li;
}
doc_ele += '</li>'
})
doc_ele += '</ul>'
}else{
let li = '<ul class="list-group nested-sortable"></ul>'
doc_ele += li
}
doc_ele += '</li>'
$("#nestedDemo").append(doc_ele)
});
docSort();// 动态添加元素之后,调用一次
@ -79,16 +108,16 @@
btn:['保存文档','发布文档'],
yes:function(index,layero){
// 保存文档
console.log(serialize(root))
// console.log(serialize(root))
var sort_data = {
'pid':res.id,
'pid':res.project.id,
'title':$('input[name="project-name"]').val(),
'desc':$('input[name="project-desc"]').val(),
'role':$(':radio[name="role"]:checked').val(),
'sort_data':JSON.stringify(serialize(root)),
'status':0,
}
console.log(sort_data)
// console.log(sort_data)
$.post('{% url "project_doc_sort" %}',sort_data,function(r){
if(r.status){
layer.msg("完成文集导入",function(){
@ -105,7 +134,7 @@
// 发布文档
console.log(serialize(root))
var sort_data = {
'pid':res.id,
'pid':res.project.id,
'title':$('input[name="project-name"]').val(),
'desc':$('input[name="project-desc"]').val(),
'role':$(':radio[name="role"]:checked').val(),