提交 d0e60e3c 编写于 作者: L luxin

add keywords_must and keywords_forbid

上级 33fdf4a7
{
"node_id": "gml-62c30f9c31f64a1d96af732c47c93f04",
"keywords": [
"Git历史",
"你了解版本控制系统吗?",
"什么是本地版本控制系统",
"什么是集中化的版本控制系统",
"什么是分布式版本控制系统",
"Git 诞生的故事"
"Git历史",
"你了解版本控制系统吗?",
"什么是本地版本控制系统",
"什么是集中化的版本控制系统",
"什么是分布式版本控制系统",
"Git 诞生的故事"
],
"children": [],
"export": [
"learn.json"
]
],
"keywords_must": [
"简介",
"历史"
],
"keywords_forbid": []
}
\ No newline at end of file
{
"node_id": "gml-17121b66f9a942629bc455f320b28910",
"keywords": [
"msys git",
"5分钟教你学会 git 安装",
"不同操作系统的安装介绍",
"Git 的环境配置",
"Git 的自定义设置",
"Git 自定义别名"
"msys git",
"5分钟教你学会 git 安装",
"不同操作系统的安装介绍",
"Git 的环境配置",
"Git 的自定义设置",
"Git 自定义别名"
],
"children": [],
"export": [
"learn.json"
]
"learn.json"
],
"keywords_must": [
"安装",
"环境配置"
],
"keywords_forbid": []
}
\ No newline at end of file
{
"node_id": "gml-598d225d1a78453d8992345f8f7902ba",
"keywords": [
"Git基本用法",
"创建仓库: git init / git clone",
"添加文件: git add / git commit",
"查看修改: git status / git diff",
"恢复文件: git log / git reset"
"Git基本用法",
"创建仓库: git init / git clone",
"添加文件: git add / git commit",
"查看修改: git status / git diff",
"恢复文件: git log / git reset"
],
"children": [],
"export": [
"learn.json"
]
],
"keywords_must": [
[
"Git",
"基本用法"
],
[
"git",
"使用"
]
],
"keywords_forbid": []
}
\ No newline at end of file
{
"node_id": "gml-f0d68868583b48d0851c7add33e2f8ff",
"keywords": [
"Git 撤销",
"Git 删除"
"Git 撤销",
"Git 删除"
],
"children": [],
"export": [
"learn.json"
]
],
"keywords_must": [
[
"git",
"撤销"
],
[
"git",
"删除"
],
[
"git",
"版本管理"
]
],
"keywords_forbid": []
}
\ No newline at end of file
......@@ -13,5 +13,12 @@
"children": [],
"export": [
"learn.json"
]
],
"keywords_must": [
[
"git",
"分支管理"
]
],
"keywords_forbid": []
}
\ No newline at end of file
{
"node_id": "gml-7b2351b6989f4ec19655498bbb4bafb1",
"keywords": [
"git tag"
"git tag"
],
"children": [],
"export": [
"learn.json"
]
],
"keywords_must": [
"标签"
],
"keywords_forbid": []
}
\ No newline at end of file
{
"node_id": "gml-426d7dad0f844c6d9bc1d6c4c860585c",
"keywords": []
"keywords": [],
"keywords_must": [],
"keywords_forbid": []
}
\ No newline at end of file
......@@ -2,10 +2,17 @@
"node_id": "gml-e67e64c1c880432ab6bc1b0452124ec0",
"keywords": [
"认识 Markdown",
"使用 Markdown 的误区"
"使用 Markdown 的误区"
],
"children": [],
"export": [
"learn.json"
]
],
"keywords_must": [
[
"MarkDown",
"介绍"
]
],
"keywords_forbid": []
}
\ No newline at end of file
......@@ -2,13 +2,36 @@
"node_id": "gml-627f564073834c8d86e45f126ac628df",
"keywords": [
"MarkDown段落",
"MarkDown段落的换行",
"MarkDown斜体",
"MarkDown粗体",
"MarkDown删除线"
"MarkDown段落的换行",
"MarkDown斜体",
"MarkDown粗体",
"MarkDown删除线"
],
"children": [],
"export": [
"learn.json"
]
],
"keywords_must": [
[
"MarkDown",
"段落"
],
[
"MarkDown",
"斜体"
],
[
"MarkDown",
"粗体"
],
[
"MarkDown",
"删除线"
],
[
"MarkDown",
"强调"
]
],
"keywords_forbid": []
}
\ No newline at end of file
......@@ -2,10 +2,17 @@
"node_id": "gml-30e9989f9a5f44fab349734a8e4479a3",
"keywords": [
"Setext 标题",
"Atx 标题"
"Atx 标题"
],
"children": [],
"export": [
"learn.json"
]
],
"keywords_must": [
[
"MarkDown",
"标题"
]
],
"keywords_forbid": []
}
\ No newline at end of file
......@@ -2,10 +2,17 @@
"node_id": "gml-3cb459e3d1a147a8b89291c1ef4147c7",
"keywords": [
"行内链接",
"参考样式链接"
"参考样式链接"
],
"children": [],
"export": [
"learn.json"
]
],
"keywords_must": [
[
"MarkDown",
"链接"
]
],
"keywords_forbid": []
}
\ No newline at end of file
......@@ -2,10 +2,17 @@
"node_id": "gml-2f1e2810b721429dba664414438b6d87",
"keywords": [
"行内图片",
"参考样式图片"
"参考样式图片"
],
"children": [],
"export": [
"learn.json"
]
],
"keywords_must": [
[
"MarkDown",
"图片"
]
],
"keywords_forbid": []
}
\ No newline at end of file
......@@ -2,11 +2,18 @@
"node_id": "gml-b4a4f06aa5114c3fa6a590d659037370",
"keywords": [
"无序列表",
"有序列表",
"任务列表"
"有序列表",
"任务列表"
],
"children": [],
"export": [
"learn.json"
]
],
"keywords_must": [
[
"MarkDown",
"列表"
]
],
"keywords_forbid": []
}
\ No newline at end of file
......@@ -2,10 +2,21 @@
"node_id": "gml-b6b6f01fb86141768c5b242327f1e0fa",
"keywords": [
"分隔线",
"区块引用"
"区块引用"
],
"children": [],
"export": [
"learn.json"
]
],
"keywords_must": [
[
"MarkDown",
"分隔线"
],
[
"MarkDown",
"引用"
]
],
"keywords_forbid": []
}
\ No newline at end of file
......@@ -2,12 +2,19 @@
"node_id": "gml-2e87affacacd4078a3ba55a5a15a8f7a",
"keywords": [
"行内代码",
"代码缩进",
"代码高亮",
"代码 Diff"
"代码缩进",
"代码高亮",
"代码 Diff"
],
"children": [],
"export": [
"learn.json"
]
],
"keywords_must": [
[
"MarkDown",
"代码块"
]
],
"keywords_forbid": []
}
\ No newline at end of file
......@@ -7,5 +7,12 @@
"children": [],
"export": [
"learn.json"
]
],
"keywords_must": [
[
"MarkDown",
"表格"
]
],
"keywords_forbid": []
}
\ No newline at end of file
{
"node_id": "gml-e5b1eb56008b451699a9e7e6d941c8ca",
"keywords": []
"keywords": [],
"keywords_must": [],
"keywords_forbid": []
}
\ No newline at end of file
{
"node_id": "gml-3acda6f103e94664800f91494aff4099",
"keywords": []
"keywords": [],
"keywords_must": [],
"keywords_forbid": []
}
\ No newline at end of file
{
"node_id": "gml-a94f8931a29e42749c65af33b5f00ffa",
"keywords": []
"keywords": [],
"keywords_must": [],
"keywords_forbid": []
}
\ No newline at end of file
{
"node_id": "gml-ec7eb3a512204261a14eafc36bc55188",
"keywords": []
"keywords": [],
"keywords_must": [],
"keywords_forbid": []
}
\ No newline at end of file
{
"tree_name": "gml",
"keywords": [],
"node_id": "gml-2edf9242568f4812bda2dd5913c09bd3"
"node_id": "gml-2edf9242568f4812bda2dd5913c09bd3",
"keywords_must": [],
"keywords_forbid": []
}
\ No newline at end of file
......@@ -24,7 +24,12 @@
"什么是分布式版本控制系统",
"Git 诞生的故事"
],
"children": []
"children": [],
"keywords_must": [
"简介",
"历史"
],
"keywords_forbid": []
}
},
{
......@@ -38,7 +43,12 @@
"Git 的自定义设置",
"Git 自定义别名"
],
"children": []
"children": [],
"keywords_must": [
"安装",
"环境配置"
],
"keywords_forbid": []
}
},
{
......@@ -51,7 +61,18 @@
"查看修改: git status / git diff",
"恢复文件: git log / git reset"
],
"children": []
"children": [],
"keywords_must": [
[
"Git",
"基本用法"
],
[
"git",
"使用"
]
],
"keywords_forbid": []
}
},
{
......@@ -61,7 +82,22 @@
"Git 撤销",
"Git 删除"
],
"children": []
"children": [],
"keywords_must": [
[
"git",
"撤销"
],
[
"git",
"删除"
],
[
"git",
"版本管理"
]
],
"keywords_forbid": []
}
},
{
......@@ -77,7 +113,14 @@
"cherry-pick 介绍及用法",
"git 的多人协作"
],
"children": []
"children": [],
"keywords_must": [
[
"git",
"分支管理"
]
],
"keywords_forbid": []
}
},
{
......@@ -86,10 +129,16 @@
"keywords": [
"git tag"
],
"children": []
"children": [],
"keywords_must": [
"标签"
],
"keywords_forbid": []
}
}
]
],
"keywords_must": [],
"keywords_forbid": []
}
},
{
......@@ -104,7 +153,14 @@
"认识 Markdown",
"使用 Markdown 的误区"
],
"children": []
"children": [],
"keywords_must": [
[
"MarkDown",
"介绍"
]
],
"keywords_forbid": []
}
},
{
......@@ -117,7 +173,30 @@
"MarkDown粗体",
"MarkDown删除线"
],
"children": []
"children": [],
"keywords_must": [
[
"MarkDown",
"段落"
],
[
"MarkDown",
"斜体"
],
[
"MarkDown",
"粗体"
],
[
"MarkDown",
"删除线"
],
[
"MarkDown",
"强调"
]
],
"keywords_forbid": []
}
},
{
......@@ -127,7 +206,14 @@
"Setext 标题",
"Atx 标题"
],
"children": []
"children": [],
"keywords_must": [
[
"MarkDown",
"标题"
]
],
"keywords_forbid": []
}
},
{
......@@ -137,7 +223,14 @@
"行内链接",
"参考样式链接"
],
"children": []
"children": [],
"keywords_must": [
[
"MarkDown",
"链接"
]
],
"keywords_forbid": []
}
},
{
......@@ -147,7 +240,14 @@
"行内图片",
"参考样式图片"
],
"children": []
"children": [],
"keywords_must": [
[
"MarkDown",
"图片"
]
],
"keywords_forbid": []
}
},
{
......@@ -158,7 +258,14 @@
"有序列表",
"任务列表"
],
"children": []
"children": [],
"keywords_must": [
[
"MarkDown",
"列表"
]
],
"keywords_forbid": []
}
},
{
......@@ -168,7 +275,18 @@
"分隔线",
"区块引用"
],
"children": []
"children": [],
"keywords_must": [
[
"MarkDown",
"分隔线"
],
[
"MarkDown",
"引用"
]
],
"keywords_forbid": []
}
},
{
......@@ -180,7 +298,14 @@
"代码高亮",
"代码 Diff"
],
"children": []
"children": [],
"keywords_must": [
[
"MarkDown",
"代码块"
]
],
"keywords_forbid": []
}
},
{
......@@ -190,29 +315,46 @@
"创建MarkDown表格",
"MarkDown表格对齐"
],
"children": []
"children": [],
"keywords_must": [
[
"MarkDown",
"表格"
]
],
"keywords_forbid": []
}
}
]
],
"keywords_must": [],
"keywords_forbid": []
}
}
]
],
"keywords_must": [],
"keywords_forbid": []
}
},
{
"gml中阶": {
"node_id": "gml-a94f8931a29e42749c65af33b5f00ffa",
"keywords": [],
"children": []
"children": [],
"keywords_must": [],
"keywords_forbid": []
}
},
{
"gml高阶": {
"node_id": "gml-ec7eb3a512204261a14eafc36bc55188",
"keywords": [],
"children": []
"children": [],
"keywords_must": [],
"keywords_forbid": []
}
}
]
],
"keywords_must": [],
"keywords_forbid": []
}
}
\ No newline at end of file
......@@ -2,10 +2,11 @@ import json
import logging
import os
import re
import subprocess
import sys
import uuid
import re
import git
id_set = set()
logger = logging.getLogger(__name__)
......@@ -14,11 +15,19 @@ handler = logging.StreamHandler(sys.stdout)
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
repo = git.Repo(".")
def user_name():
return repo.config_reader().get_value("user", "name")
def user_name(md_file, author_dict):
ret = subprocess.Popen([
"git", "log", md_file
], stdout=subprocess.PIPE)
lines = list(map(lambda l: l.decode(), ret.stdout.readlines()))
author_lines = []
for line in lines:
if line.startswith('Author'):
author_lines.append(line.split(' ')[1])
author_nick_name = author_lines[-1]
return author_dict.get(author_nick_name, "")
def load_json(p):
......@@ -77,7 +86,18 @@ def check_export(base, cfg):
class TreeWalker:
def __init__(self, root, tree_name, title=None, log=None):
def __init__(
self, root,
tree_name,
title=None,
log=None,
authors=None,
enable_notebook=None,
ignore_keywords=False
):
self.ignore_keywords = ignore_keywords
self.authors = authors if authors else {}
self.enable_notebook = enable_notebook
self.name = tree_name
self.root = root
self.title = tree_name if title is None else title
......@@ -89,7 +109,9 @@ class TreeWalker:
root_node = {
"node_id": root["node_id"],
"keywords": root["keywords"],
"children": []
"children": [],
"keywords_must": root["keywords_must"],
"keywords_forbid": root["keywords_forbid"]
}
self.tree[root["tree_name"]] = root_node
self.load_levels(root_node)
......@@ -144,6 +166,8 @@ class TreeWalker:
"node_id": config["node_id"],
"keywords": config["keywords"],
"children": [],
"keywords_must": config["keywords_must"],
"keywords_forbid": config["keywords_forbid"]
}
}
......@@ -195,6 +219,8 @@ class TreeWalker:
"tree_name": self.name,
"keywords": [],
"node_id": self.gen_node_id(),
"keywords_must": [],
"keywords_forbid": []
}
dump_json(config_path, config, exist_ok=True, override=True)
else:
......@@ -224,7 +250,9 @@ class TreeWalker:
if not os.path.exists(config_path):
config = {
"node_id": self.gen_node_id(),
"keywords": []
"keywords": [],
"keywords_must": [],
"keywords_forbid": []
}
dump_json(config_path, config, exist_ok=True, override=True)
else:
......@@ -290,6 +318,8 @@ class TreeWalker:
"node_id": config["node_id"],
"keywords": config["keywords"],
"children": [],
"keywords_must": config["keywords_must"],
"keywords_forbid": config["keywords_forbid"]
}
}
return num, result
......@@ -301,7 +331,9 @@ class TreeWalker:
name: {
"node_id": config["node_id"],
"keywords": config["keywords"],
"children": config.get("children", [])
"children": config.get("children", []),
"keywords_must": config["keywords_must"],
"keywords_forbid": config["keywords_forbid"]
}
}
# if "children" in config:
......@@ -318,7 +350,8 @@ class TreeWalker:
continue
mfile = base + ".json"
meta_path = os.path.join(section_path, mfile)
self.ensure_exercises_meta(meta_path, source)
md_file = os.path.join(section_path, e)
self.ensure_exercises_meta(meta_path, source, md_file)
export = config.get("export", [])
if mfile not in export and self.name != "algorithm":
export.append(mfile)
......@@ -339,7 +372,7 @@ class TreeWalker:
else:
id_set.add(exercise["exercise_id"])
def ensure_exercises_meta(self, meta_path, source):
def ensure_exercises_meta(self, meta_path, source, md_file):
_, mfile = os.path.split(meta_path)
meta = None
if os.path.exists(meta_path):
......@@ -354,26 +387,31 @@ class TreeWalker:
if "source" not in meta:
meta["source"] = source
if "author" not in meta:
meta["author"] = user_name()
meta["author"] = user_name(md_file, self.authors)
if "type" not in meta:
meta["type"] = "code_options"
if meta is None:
meta = {
"type": "code_options",
"author": user_name(),
"source": source,
"notebook_enable": self.default_notebook(),
"exercise_id": uuid.uuid4().hex
}
if meta is None:
meta = {
"type": "code_options",
"author": user_name(md_file, self.authors),
"source": source,
"notebook_enable": self.default_notebook(),
"exercise_id": uuid.uuid4().hex
}
dump_json(meta_path, meta, True, True)
def default_notebook(self):
if self.enable_notebook is not None:
return self.enable_notebook
if self.name in ["python", "java", "c"]:
return True
else:
return False
def check_section_keywords(self, full_path):
if self.ignore_keywords:
return
config = self.ensure_section_config(full_path)
if not config.get("keywords", []):
self.logger.error(f"节点 [{full_path}] 的关键字为空,请修改配置文件写入关键字")
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册