def load_from_rawxls(file_path): """从 xlsx 文件恢复数据到 lang.csv 的格式 xlsx 文件可能是 <name, desc> 模式,也可能是 list<text> 模式。 Args: file_path (str): xlsx 文件路径 Returns: category (str): category from lang_def csv_data (list[str]): list of [file_id, unknown, index, text],不带前导0 """ data = load_xls(file_path)[1:] # 判断文件模式 id_split = data[0][1].split('-') if len(id_split) > 3 and id_split[-1].isdigit() and id_split[-2].isdigit( ) and id_split[-3].isdigit(): # list of text return load_from_list_category(data) elif len(id_split) > 1 and id_split[-1].isdigit(): # name_desc return load_from_pair_category(data) else: log.error('load %s failed.' % file_path) return '', []
def main(): lang = 'zh' if len(sys.argv) != 2: usage() sys.exit(2) xls_path = sys.argv[1] cd = sys.path[0] translation_path = os.path.join(cd, '../translation') translate_file = os.path.join(translation_path, '%s_translate.txt' % lang) ui_mgr = UiMgr() # load lua pregame_src = os.path.join(translation_path, 'en_pregame.lua') ui_mgr.load_lua_file(pregame_src) client_src = os.path.join(translation_path, 'en_client.lua') ui_mgr.load_lua_file(client_src) # load translation data_from_xls = load_xls(xls_path) ui_mgr.apply_translate_from_xls(data_from_xls, need_check=False) # save result txt_lines = ui_mgr.get_txt_lines(replace=True) with open(translate_file, 'wt', encoding='utf-8') as fp: fp.writelines(txt_lines) log.info('save translate file succeed.')
def main(): lang = 'zh' if len(sys.argv) != 2: usage() sys.exit(2) xls_path = sys.argv[1] cd = sys.path[0] translation_path = os.path.join(cd, '../translation') translate_file = os.path.join(translation_path, '%s_translate.txt' % lang) ui_mgr = UiMgr() # load lua pregame_src = os.path.join(translation_path, 'en_pregame.lua') ui_mgr.load_lua_file(pregame_src) client_src = os.path.join(translation_path, 'en_client.lua') ui_mgr.load_lua_file(client_src) # load translation data_from_xls = load_xls(xls_path) ui_mgr.apply_translate_from_xls(data_from_xls) ui_mgr.apply_translate_from_xls(data_from_xls) # save result txt_lines = ui_mgr.get_txt_lines(replace=True) with open(translate_file, 'wt', encoding='utf-8') as fp: fp.writelines(txt_lines) print('save translate file succeed.')
def load_from_langxls(file_path, lang, need_check=False, load_ui=False): """从 xlsx 文件中读取 lang.csv 的翻译 xlsx 文件可能是 <name, desc> 模式,也可能是 list<text> 模式。 Args: file_path (str): xlsx 文件路径 lang (str): "zh"/"en", 读中文还是英文 need_check (bool): 是否检查 load_ui (bool): 是否读取ui汉化文件的内容 Returns: category (str): category from lang_def translated_data (list[str]): list of [file_id, unknown, index, text],不带前导0 """ data = load_xls(file_path)[1:] # 判断文件模式 id_split = data[0][1].split('-') if len(id_split) > 3 and id_split[-1].isdigit() and id_split[-2].isdigit() and id_split[-3].isdigit(): # list of text return load_from_list_category(data, lang, need_check) elif len(id_split) > 1 and id_split[-1].isdigit(): # name_desc return load_from_pair_category(data, lang, need_check) elif len(id_split) == 1 and '_' in id_split[0] \ and id_split[0][0].isalpha() and id_split[0][-1].isalpha(): if load_ui: return load_from_ui_fake(data, lang, need_check) else: log.info('skip ui file %s.' % file_path) return '', [] else: log.error('load %s failed.' % file_path) return '', []
def load_from_rawxls(file_path): """从 xlsx 文件恢复数据到 lang.csv 的格式 xlsx 文件可能是 <name, desc> 模式,也可能是 list<text> 模式。 Args: file_path (str): xlsx 文件路径 Returns: category (str): category from lang_def csv_data (list[str]): list of [file_id, unknown, index, text],不带前导0 """ data = load_xls(file_path)[1:] # 判断文件模式 id_split = data[0][1].split('-') if len(id_split) > 3 and id_split[-1].isdigit() and id_split[-2].isdigit() and id_split[-3].isdigit(): # list of text return load_from_list_category(data) elif len(id_split) > 1 and id_split[-1].isdigit(): # name_desc return load_from_pair_category(data) else: log.error('load %s failed.' % file_path) return '', []
def check_xls(src_path, column_id, origin_column_id): """检查xls Args: src_path (str): 待检查的 xlsx 文件的路径 column_id (int): 翻译后的列的 id origin_column_id (int): 原文的列的 id """ data = load_xls(src_path) for line in data: text_is_ok = False try: text_to_check = line[column_id] # skip empty line if text_to_check == '': continue text_is_ok = check_string(text_to_check) if origin_column_id is not None: text_is_ok &= check_string_with_origin(line[column_id], line[origin_column_id]) except Exception as e: log.warning(line) log.warning(e) if not text_is_ok: log.warning('Failed when checking:\n%s\n' % ', '.join(line))
def join_all_xls(file_path): """合并文件夹里的所有 xls 文件,合并成两类 Args: file_path (str): 要遍历的路径 Returns: data_pair (list): pair 格式的数据 data_list (list): list 格式的数据 """ data_pair = [] data_list = [] for filename in walk_xlsx_files(file_path): # 读取数据 data = load_xls(filename) category = get_category_of_id(data[1][1]) # 判断是哪一类 if category in lang_def.file_id_of_pair: if len(data_pair) > 0: # header 只留一次 data = data[1:] data_pair.extend(data) else: if len(data_list) > 0: data = data[1:] data_list.extend(data) return data_pair, data_list
def merge_translation_file(dest_xls_path, src_xls_path, conflict_xls_file, check_category=True): """合并两个文件中的数据,写回 dest 文件 Args: dest_xls_path (str): 合并目标文件路径,当发生冲突时以此文件为准 src_xls_path (str): 合并源文件路径 conflict_xls_file (str | None): 冲突数据存放文件 check_category (bool): 检查类型是否相等 """ # check category if check_category: category = get_category(dest_xls_path) category_src = get_category(src_xls_path) if category != category_src: log.error('category not equal.') raise RuntimeError('category not equal.') # load log.info('load %s' % dest_xls_path) dest_data = load_xls(dest_xls_path) header, dest_data = dest_data[0], dest_data[1:] log.info('load %s' % src_xls_path) src_data = load_xls(src_xls_path)[1:] category = get_category_of_id(dest_data[0][1]) # merge merged_data, conflict_data = merge_translation_data( category, dest_data, src_data) # sort merged_data = sorted(merged_data, key=lambda row: row[1]) conflict_data = sorted(conflict_data, key=lambda row: row[1]) # save log.info('%d conflicts.' % len(conflict_data)) log.info('save %s' % dest_xls_path) save_xlsx(dest_xls_path, merged_data, header=header) if conflict_xls_file is not None and len(conflict_data) > 0: log.info('save %s' % conflict_xls_file) save_xlsx(conflict_xls_file, conflict_data, header=header)
def merge_translation_file(dest_xls_path, src_xls_path, conflict_xls_file, check_category=True): """合并两个文件中的数据,写回 dest 文件 Args: dest_xls_path (str): 合并目标文件路径,当发生冲突时以此文件为准 src_xls_path (str): 合并源文件路径 conflict_xls_file (str | None): 冲突数据存放文件 check_category (bool): 检查类型是否相等 """ # check category if check_category: category = get_category(dest_xls_path) category_src = get_category(src_xls_path) if category != category_src: log.error('category not equal.') raise RuntimeError('category not equal.') # load log.info('load %s' % dest_xls_path) dest_data = load_xls(dest_xls_path) header, dest_data = dest_data[0], dest_data[1:] log.info('load %s' % src_xls_path) src_data = load_xls(src_xls_path)[1:] category = get_category_of_id(dest_data[0][1]) # merge merged_data, conflict_data = merge_translation_data(category, dest_data, src_data) # sort merged_data = sorted(merged_data, key=lambda row: row[1]) conflict_data = sorted(conflict_data, key=lambda row: row[1]) # save log.info('%d conflicts.' % len(conflict_data)) log.info('save %s' % dest_xls_path) save_xlsx(dest_xls_path, merged_data, header=header) if conflict_xls_file is not None and len(conflict_data) > 0: log.info('save %s' % conflict_xls_file) save_xlsx(conflict_xls_file, conflict_data, header=header)
def apply_format(file_path): """xlsx 套用格式""" data = load_xls(file_path) if len(data) < 2: return header = data[0] data = data[1:] if len(header) in (8, 9, 12): save_xlsx_template(file_path, data, header=header) else: print('unknown xls %s.' % file_path) print('save %s' % file_path)
def apply_format(file_path): """xlsx 套用格式""" log.debug('start %s' % file_path) data = load_xls(file_path) if len(data) < 2: return header = data[0] data = data[1:] if len(header) in (8, 9, 12): save_xlsx_template(file_path, data, header=header) log.info('save %s' % file_path) else: log.error('unknown xls %s.' % file_path)
def merge_translation_file(dest_xls_path, src_xls_path, conflict_xls_file): """合并两个文件中的数据,写回 dest 文件 Args: dest_xls_path (str): 合并目标文件路径,当发生冲突时以此文件为准 src_xls_path (str): 合并源文件路径 conflict_xls_file (str | None): 冲突数据存放文件 """ # load print('load %s' % dest_xls_path) dest_data = load_xls(dest_xls_path) header, dest_data = dest_data[0], dest_data[1:] print('load %s' % src_xls_path) src_data = load_xls(src_xls_path)[1:] # check if not (dest_data[0][1].startswith('SI_') and src_data[0][1].startswith('SI_')): raise RuntimeError('invalid ui xls file') # merge merged_data, conflict_data = merge_translation_by_col( dest_data, src_data, id_col=1, origin_col_ids=[ 2, ], translation_col_ids=[3, 4, 5, 6, 7]) # save print('%d conflicts.' % len(conflict_data)) print('save %s' % dest_xls_path) save_xlsx(dest_xls_path, merged_data, header=header) if conflict_xls_file is not None and len(conflict_data) > 0: print('save %s' % conflict_xls_file) save_xlsx(conflict_xls_file, conflict_data, header=header)
def merge_diff_files(files, output_path): """按要求合并翻译文件,并写入文件""" if len(files) <= 0: return header = None all_diff_data = [] for filename in files: log.info('loading %s...' % os.path.basename(filename)) diff_data = load_xls(filename) header, diff_data = diff_data[0], diff_data[1:] all_diff_data.extend(diff_data) # 去空 category = get_category_of_id(all_diff_data[0][1]) if category in lang_def.file_id_of_array or category in lang_def.file_id_of_list: all_diff_data = [row for row in all_diff_data if row[4] != ''] elif category in lang_def.file_id_of_pair: all_diff_data = [row for row in all_diff_data if row[4] + row[7] != ''] else: log.error('unknown category %s.' % category) raise RuntimeError('unknown category') # 去重 all_diff_data_by_id = {} for row in all_diff_data: row = tuple(row) key = row[0] if key not in all_diff_data_by_id: all_diff_data_by_id[key] = {row} else: if row not in all_diff_data_by_id: all_diff_data_by_id[key].add(row) # 按顺序重排 all_diff_data = [] for _, rows_set in sorted(all_diff_data_by_id.items()): all_diff_data.extend(rows_set) output_name = os.path.basename(output_path) if len(all_diff_data) > 0: log.info('saving %s...' % output_name) save_xlsx(output_path, all_diff_data, header=header) else: log.info('skip %s' % output_name)
def main(): if len(sys.argv) not in (2, 3): usage() sys.exit(2) # init path input_path = sys.argv[1] if len(sys.argv) == 3: output_path = sys.argv[2] else: if input_path.lower().endswith('.xlsx'): output_path = input_path[:-5] + '.csv' else: output_path = input_path + '.csv' # convert print(input_path, output_path) csv_data = load_xls(input_path) lines = [] for row in csv_data: lines.append('\t'.join(row) + '\n') with open(output_path, 'wt', encoding='utf-8') as fp: fp.writelines(lines)
def main(): if len(sys.argv) not in (2, 3): usage() sys.exit(2) # init path input_path = sys.argv[1] if len(sys.argv) == 3: output_path = sys.argv[2] else: if input_path.lower().endswith('.xlsx'): output_path = input_path[:-5] + '.csv' else: output_path = input_path + '.csv' # convert log.info('input path: %s' % input_path) log.info('out path: %s' % output_path) csv_data = load_xls(input_path) lines = [] for row in csv_data: lines.append('\t'.join(row) + '\n') with open(output_path, 'wt', encoding='utf-8') as fp: fp.writelines(lines)
def gen_chs(): """1. 简体""" NEED_CLEAR = True log.info(os.getcwd()) if NEED_CLEAR: print('### 正在清理...') log.debug('正在清理...') # 清理输出目录 dirs = ('../../输出/生成简体插件/', ) for dir in dirs: if os.path.exists(dir): log.info('clear %s' % dir) shutil.rmtree(dir) # 清理翻译中间目录 log.info('clear csv and xlsx') for root, dirs, files in os.walk('../../translation/lang/translated/'): for f in files: if f.endswith('.csv') or f.endswith('.xlsx') or f.endswith( '.lang'): filename = os.path.join(root, f) log.debug('remove %s' % filename) os.remove(filename) break for root, dirs, files in os.walk('../../translation/'): for f in files: if f.endswith('.csv') or f.endswith('.xlsx'): filename = os.path.join(root, f) log.debug('remove %s' % filename) os.remove(filename) break files = ( '../../translation/zh_translate.txt', '../../translation/zh_translate.xlsx', ) for f in files: if os.path.exists(f): log.debug('remove %s' % f) os.remove(f) print('### 创建目录...') log.debug('创建目录...') dirs = ('../../输出/生成简体插件/', ) for dir in dirs: if not os.path.isdir(dir): log.info('create %s' % dir) os.makedirs(dir) print('### 拷贝文件...') log.debug('拷贝文件...') for root, dirs, files in os.walk('汉化xlsx/'): for f in files: if f.endswith('.xlsx') and not f.startswith('~'): filename = os.path.join(root, f) data = load_xls(filename) if len(data[1]) == 8: # ui 汉化文件 dst = '../../translation/' ui_xls_file = f log.info('copy %s to %s' % (filename, dst)) shutil.copy(filename, dst) dst = '../../translation/lang/translated/' log.info('copy %s to %s' % (filename, dst)) shutil.copy(filename, dst) os.chdir('../../scripts/') log.info(os.getcwd()) print('### 转换UI文本...') log.debug('转换UI文本...') execute('python export_uixls_to_txt.py ../translation/%s' % ui_xls_file) execute('python convert_txt_to_str.py -m translation') print('### 转换其他文本...') log.debug('转换其他文本...') execute('python export_langxls_to_csv.py') os.chdir('../translation/lang/translated/') log.info(os.getcwd()) print('### 正在编码...') log.debug('正在编码...') execute('EsoExtractData.exe -x zh.lang.csv') print('### 正在校验...') log.debug('正在校验...') shutil.copy('zh.lang', 'zh1.lang') execute('EsoExtractData -l zh1.lang') num1 = get_linenum('../en.lang.csv') num2 = get_linenum('zh.lang.csv') num3 = get_linenum('zh1.lang.csv') log.info('validate line num: %d, %d, %d' % (num1, num2, num3)) if not num1 == num2 == num3: log.error('校验失败') sys.exit(-1) os.chdir('../../../') log.info(os.getcwd()) print('### 正在打包...') log.debug('正在打包...') log.info('copy AddOns') shutil.copytree('AddOns/', '输出/生成简体插件/AddOns') log.info('copy lang') shutil.copy('translation/lang/translated/zh.lang', '输出/生成简体插件/AddOns/gamedata/lang/') log.info('copy readme') shutil.copy('工具/生成插件/README_chs.txt', '输出/生成简体插件/README.txt') log.info('clear AddOns') os.remove('输出/生成简体插件/AddOns/EsoUI/lang/.gitignore') os.remove('输出/生成简体插件/AddOns/EsoZH/fonts/README.md') os.remove('输出/生成简体插件/AddOns/gamedata/lang/.gitignore') os.chdir('输出/生成简体插件/') log.info(os.getcwd()) with open('README.txt', 'rt', encoding='utf-8') as fp: desc = fp.read() zip_name = 'ESO汉化插件.zip' zipf = zipfile.ZipFile(zip_name, 'w', zipfile.ZIP_DEFLATED) zipf.comment = bytes(desc, encoding='gbk') for root, dirs, files in os.walk('.'): for f in files: if f != zip_name: zipf.write(os.path.join(root, f)) zipf.close()
def gen_chs(): """1. 简体""" NEED_CLEAR = True log.info(os.getcwd()) if NEED_CLEAR: print('### 正在清理...') log.debug('正在清理...') # 清理输出目录 dirs = ( '../../输出/生成简体插件/', ) for dir in dirs: if os.path.exists(dir): log.info('clear %s' % dir) shutil.rmtree(dir) # 清理翻译中间目录 log.info('clear csv and xlsx') for root, dirs, files in os.walk('../../translation/lang/translated/'): for f in files: if f.endswith('.csv') or f.endswith('.xlsx') or f.endswith('.lang'): filename = os.path.join(root, f) log.debug('remove %s' % filename) os.remove(filename) break for root, dirs, files in os.walk('../../translation/'): for f in files: if f.endswith('.csv') or f.endswith('.xlsx'): filename = os.path.join(root, f) log.debug('remove %s' % filename) os.remove(filename) break files = ( '../../translation/zh_translate.txt', '../../translation/zh_translate.xlsx', ) for f in files: if os.path.exists(f): log.debug('remove %s' % f) os.remove(f) print('### 创建目录...') log.debug('创建目录...') dirs = ( '../../输出/生成简体插件/', ) for dir in dirs: if not os.path.isdir(dir): log.info('create %s' % dir) os.makedirs(dir) print('### 拷贝文件...') log.debug('拷贝文件...') for root, dirs, files in os.walk('汉化xlsx/'): for f in files: if f.endswith('.xlsx') and not f.startswith('~'): filename = os.path.join(root, f) data = load_xls(filename) if len(data[1]) == 8: # ui 汉化文件 dst = '../../translation/' ui_xls_file = f log.info('copy %s to %s' % (filename, dst)) shutil.copy(filename, dst) dst = '../../translation/lang/translated/' log.info('copy %s to %s' % (filename, dst)) shutil.copy(filename, dst) os.chdir('../../scripts/') log.info(os.getcwd()) print('### 转换UI文本...') log.debug('转换UI文本...') execute('python export_uixls_to_txt.py ../translation/%s' % ui_xls_file) execute('python convert_txt_to_str.py -m translation') print('### 转换其他文本...') log.debug('转换其他文本...') execute('python export_langxls_to_csv.py') os.chdir('../translation/lang/translated/') log.info(os.getcwd()) print('### 正在编码...') log.debug('正在编码...') execute('EsoExtractData.exe -x zh.lang.csv') print('### 正在校验...') log.debug('正在校验...') shutil.copy('zh.lang', 'zh1.lang') execute('EsoExtractData -l zh1.lang') num1 = get_linenum('../en.lang.csv') num2 = get_linenum('zh.lang.csv') num3 = get_linenum('zh1.lang.csv') log.info('validate line num: %d, %d, %d' % (num1, num2, num3)) if not num1 == num2 == num3: log.error('校验失败') sys.exit(-1) os.chdir('../../../') log.info(os.getcwd()) print('### 正在打包...') log.debug('正在打包...') log.info('copy AddOns') shutil.copytree('AddOns/', '输出/生成简体插件/AddOns') log.info('copy lang') shutil.copy('translation/lang/translated/zh.lang', '输出/生成简体插件/AddOns/gamedata/lang/') log.info('copy readme') shutil.copy('工具/生成插件/README_chs.txt', '输出/生成简体插件/README.txt') log.info('clear AddOns') os.remove('输出/生成简体插件/AddOns/EsoUI/lang/.gitignore') os.remove('输出/生成简体插件/AddOns/EsoZH/fonts/README.md') os.remove('输出/生成简体插件/AddOns/gamedata/lang/.gitignore') os.chdir('输出/生成简体插件/') log.info(os.getcwd()) with open('README.txt', 'rt', encoding='utf-8') as fp: desc = fp.read() zip_name = 'ESO汉化插件.zip' zipf = zipfile.ZipFile(zip_name, 'w', zipfile.ZIP_DEFLATED) zipf.comment = bytes(desc, encoding='gbk') for root, dirs, files in os.walk('.'): for f in files: if f != zip_name: zipf.write(os.path.join(root, f)) zipf.close()