本帖最后由 逆风TO 于 2019-4-23 13:51 编辑
python 自动生成文档
python 自动生成文档
一、配置文档
二、protobuf
三、代码
python 自动生成文档
一、配置文档
register.temeprate
# Datetime: ${DATETIME}
from proto import ${FILENAME}_pb2
from proto import xCmd_pb2
def register_${WRITEFILE}(pbmap):
pbmap.register_command(
xCmd_pb2.${PROTTOCMD},
${FILENAME}_pb2.${PARAMNAME}Param) # ${NUMBER}
cmd.temperate
pbmap.register_descriptor(
xCmd_pb2.${PROTTOCMD},
${FILENAME}_pb2.${CMD}) # ${NUMBER}
</securityRealm>
二、protobuf
// scene -> client : puzzle item ntf
message PuzzleItemNtf
{
optional Command cmd = 1 [ default = PUZZLE_PROTOCMD ];
optional PuzzleParam param = 2 [ default = PUZZLEPARAM_ITEMNTF ];
repeated PuzzleItem items = 3;
}
// client <-> scene : get reward
message ActivePuzzleCmd
{
optional Command cmd = 1 [ default = PUZZLE_PROTOCMD ];
optional PuzzleParam param = 2 [ default = PUZZLEPARAM_ACTIVIEPUZZLE ];
optional uint32 actid = 3 [ default = 0 ];
optional uint32 puzzleid = 4 [ default = 0 ];
}
三、代码
# Author: Allan
# Datetime: 2019-03-15
# 遍历 proto 目录下使用文件,自动在 pbmap 目录下生成相应文件
import re
import os
from datetime import datetime
from string import Template
class AutoCreateFile:
def __init__(self):
self.file_path = r'./proto/{}.proto'
self.command, self.xCmds = self.get_params('xCmd.proto')
self.write_file = ''
def generate(self, filename):
"""
自动生成 pbmap 文件
:param filename: protobuf 文件
:return: None
"""
flag = False # 是否存在(PROTOCMD)命令
lines = []
current_datetime = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
file_path = self.file_path.format(filename)
cmds_detail, count = self.get_commands_detail(file_path)
if count > 1:
print('{} 存在 {} 个 PROTOCMD 命令'.format(filename, count))
if cmds_detail:
if filename.endswith('Cmd'):
self.write_file = filename.split('Cmd')[0]
else:
self.write_file = filename
number = self.get_protocmd_number(cmds_detail[0]['proto_cmd'])
with open(r'register.temperate', 'r') as f:
temp_param = Template(f.read())
lines.append(temp_param.substitute(
DATETIME=current_datetime,
WRITEFILE=self.write_file,
FILENAME=filename,
PARAMNAME=cmds_detail[0]['param_name'],
PROTTOCMD=cmds_detail[0]['proto_cmd'],
NUMBER=number))
with open(r'cmd.temperate', 'r') as f:
cmd_params = Template(f.read())
for command in cmds_detail:
lines.append(cmd_params.substitute(
FILENAME=filename,
PROTTOCMD=command['proto_cmd'],
PARAM=command['param'],
CMD=command['cmd_name']))
flag = True
if flag:
# 如果有命令(PROTOCMD),生成 pbmap 文件
self.write_pbmap(lines)
def get_params(self, filename):
"""
获取 protobuf 文件中的参数
:param filename: protobuf 文件
:return: param_name, params
"""
with open(filename, 'r') as f:
params = []
lines = f.readlines()
param_name = re.search(r'^enum .*', ''.join(lines), re.M)
param_name = param_name.group().split()[1].split('Param')[0]
flag = False
for param in lines:
# 遍历第一个enum,并过滤空行和注释行
if '{' in param:
flag = True
continue
elif "}" in param:
break
if flag and param != '\n' and not param.startswith('//'):
params.append(param.strip().split(';')[0])
return param_name, params
def get_protocmd_number(self, proto_param):
for param in self.xCmds:
if proto_param in param:
number = param.replace(' ', '').split('=')[1]
return number
def get_commands_detail(self, filename):
"""
获取 cmd 详细信息
:param filename: protobuf 文件
:param param: CmdParam (例如,AchiveParam)
:return: cmds_detail: [proto_cmd, cmd_name, param_name, param]
count: 大于1,则文件存在重复的PROTOCMD
"""
with open(filename, 'r') as f:
count = 0
cmds_detail = []
temp_proto_cmd = ""
lines = f.readlines()
for i in range(len(lines)):
if 'PROTOCMD' in lines and '//' not in lines:
cmd_detail = {'proto_cmd': '', 'cmd_name': '', 'param_name': '', 'param': ''}
proto_cmd = lines.replace(' ', '').split(']')[0].split('=')[-1]
cmd_name = lines[i-2].split()[1]
param = lines[i+1].replace(' ', '').split(']')[0].split('=')[-1]
if 'Param' not in lines[i+1]:
continue
param_name = lines[i+1].strip().split()[1]
cmd_detail['proto_cmd'] = proto_cmd
if temp_proto_cmd != proto_cmd:
"记录重复的PROTOCMD文件"
temp_proto_cmd = proto_cmd
count += 1
cmd_detail['cmd_name'] = cmd_name
cmd_detail['param'] = param
cmd_detail['param_name'] = param_name
cmds_detail.append(cmd_detail)
return cmds_detail, count
def write_pbmap(self, info):
"""
写入信息到 pbmap 文件
:param info: 信息
:return: None
"""
filename = r'./pbmap/{}.py'.format(self.write_file)
with open(filename, 'w') as f:
f.writelines(info)
def read_directory(self, path):
"""
遍历目录,查找使用文件名
:param path: 目标目录
:return: 所有文件名
"""
results = []
path = os.listdir(path)
for i, item in enumerate(path):
if item.endswith('.proto'):
results.append(item)
return results
if __name__ == '__main__':
acf = AutoCreateFile()
res = acf.read_directory(path=r'./proto')
for result in res:
path = result.split('.')[0]
acf.generate(path)
|
|