-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathfbs_generator.py
203 lines (186 loc) · 6.88 KB
/
fbs_generator.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# -*- coding:utf-8 -*-
# auth:evan xu
# date:2019-10-17
import xlrd
import sys
import os
from common import utils, base
class FbsGenerator(base.Generator):
"""
生成fbs类
"""
__name_space_tpl = """
namespace %s;
"""
__row_code_tpl = """
table %s {
%s
}
"""
__group_tpl = """
table %s {
datalist:[%s];
}
"""
__root_type_tpl = """
root_type %s;
"""
@classmethod
def clean_directory(cls, target_path):
"""
:param target_path:
:return:
"""
if not os.path.isdir(target_path):
os.mkdir(target_path)
try:
for root, dirs, files in os.walk(target_path):
for file in files:
path = os.path.join(root, file)
os.remove(path)
print("清理文件: ", path)
except:
print('旧数据清理失败,请关掉已打开的旧文件')
sys.exit()
def export_all_excel_to_fbs(self):
"""
excel到fbs
:return:
"""
PWD = os.path.dirname(os.path.abspath(__file__))
excel_root_path = os.path.join(PWD, self.get_config().get("excel_rootPath"))
if not excel_root_path:
print("没有配置excel文件夹的路径,请手动创建一个!")
sys.exit()
for root, dirs, files in os.walk(excel_root_path, topdown=True):
print(root, dirs, files)
for name in files:
file_path = os.path.join(root, name)
if file_path.endswith(self.get_config().get("excel_extension")) and not name.startswith('~'):
self.export_excel_to_fbs(file_path)
def export_excel_to_fbs(self, excel_path):
"""
:param excel_path:
:return:
"""
# 打开excel,分别将每一个sheet导出fbs
wb = xlrd.open_workbook(excel_path)
sheet_count = len(wb.sheet_names())
for x in range(0, sheet_count):
sheet = wb.sheet_by_index(x)
self.export_sheet_to_fbs(sheet)
def export_sheet_to_fbs(self, sheet):
"""
excel的sheet导出为fbs
:param sheet:
:return:
"""
sheet_name = sheet.name
if sheet_name.find("|") != -1:
sheet_name = sheet_name.split("|")[1]
row_table_name = sheet_name + 'RowData'
group_table_name = sheet_name
# check if length of row equals
header_length = self.get_config().get("header_length")
if not isinstance(header_length, int):
print('header_length 不是数字类型')
print('异常退出')
sys.exit()
if not utils.checkRowHeaderLength(sheet, header_length):
print('表头长度各列不一致, 仔细检查')
print('异常退出')
sys.exit()
variable_dict = self.load_sheet2_dict(sheet)
if not variable_dict:
print('无法获取sheet表单数据,请检查excel表中的%s结构' %sheet_name)
print('异常退出')
sys.exit()
#print(variable_name, data_type, data_type in __support_datatypes)
# 组合变量定义代码字符串
variables_str = ''
for variable in variable_dict:
data_type = variable_dict[variable]
variables_str += ' %s:%s;\n' % (variable, data_type)
variables_str = variables_str.strip(' \t\n\t')
# 拼接fbs文本结构
name_space_str = self.__name_space_tpl % sheet_name
row_data_table_code_str = self.__row_code_tpl % (row_table_name, variables_str)
group_data_table_code_str = self.__group_tpl % (group_table_name, row_table_name)
root_type_str = self.__root_type_tpl % group_table_name
# 写入文件
fbs_root_path = self.get_config().get("output_fbs_rootPath")
fbs_file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), fbs_root_path + "/" + group_table_name + '.fbs')
print('生成: ', fbs_file_path)
write_str = name_space_str \
+ row_data_table_code_str\
+ group_data_table_code_str\
+ root_type_str
with open(fbs_file_path, 'w') as f:
f.write(write_str)
@classmethod
def get_all_fbs_file(cls, root_path):
"""
:param root_path:
:return:
"""
file_list = []
for root, dirs, files in os.walk(root_path):
for file in files:
file_path = os.path.join(root, file)
file_list.append(file_path)
return file_list
def exe_generate_cmd(self, fbs_file, target_path, language_sign):
"""
执行生成语句
:param fbs_file:
:param target_path:
:param language_sign:
:return:
"""
# flatc所在目录
work_root = os.path.dirname(os.path.abspath(__file__))
flatc_path = os.path.join(work_root, self.get_config().get("flat_path"))
if language_sign == "bins" or language_sign == "fbs" or language_sign == "exec":
return
print('生成 {} 代码'.format(language_sign))
command = '{} --{} -o {} {} --gen-onefile'.format(flatc_path, language_sign, target_path, fbs_file)
print(command)
os.system(command)
def generate_target(self, target_path, language_sign):
"""
:param target_path:
:param language_sign:
:return:
"""
fbs_path_list = self.get_all_fbs_file(self.get_config().get("output_fbs_rootPath"))
for file_path in fbs_path_list:
self.exe_generate_cmd(file_path, target_path, language_sign)
def clean(self):
"""
清理上次的数据
:return:
"""
# 本工具的根目录
work_root = os.path.dirname(os.path.abspath(__file__))
lang_types = self.get_config().get("generate_lang_type")
for lang in lang_types:
lang_str = "generated_%s" % lang
lang_root_path = os.path.join(work_root, lang_str)
FbsGenerator.clean_directory(lang_root_path)
def run(self):
"""
执行生成fbs文件
:return:
"""
print('---------------- 清理旧文件 ----------------')
self.clean()
print('---------------- 生成fbs文件, 生成不同语言代码 ----------------')
self.export_all_excel_to_fbs()
# 本工具的根目录
work_root = os.path.dirname(os.path.abspath(__file__))
lang_types = self.get_config().get("generate_lang_type")
for lang in lang_types:
lang_str = "generated_%s" %lang
lang_root_path = os.path.join(work_root, lang_str)
self.generate_target(lang_root_path, lang) # 生成Python代码是必须的,因为要用来打包数据
# 还可以自己扩展,生成指定语言的代码