Skip to content

Commit

Permalink
fix
Browse files Browse the repository at this point in the history
  • Loading branch information
Light-Beacon committed May 25, 2024
1 parent b1df7f5 commit 22873d1
Show file tree
Hide file tree
Showing 8 changed files with 657 additions and 0 deletions.
97 changes: 97 additions & 0 deletions Core/code_formatter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
'''
该模块用于格式化代码
'''
from typing import Dict
from .debug import log_warning
from .module_manager import invoke_script

def format_code(code:str,card:Dict[str,object],
project,children_code:str='',stack:list = None):
'''格式化代码'''
if not stack:
stack = []
matches = findall_placeholders(code)
for match in matches:
#LogDebug(str(match))
qurey_tuple = split_args(match)
attr_name = qurey_tuple[0]
if attr_name in stack:
log_warning(f'[Formatter] 检测到循环调用: {stack}')
return code
for item in qurey_tuple[1:]:
# 格式化参数
item = format_code(code=item,card=card,project=project,
children_code=children_code,stack=stack)
if attr_name.startswith('$') or attr_name.startswith('@'):
replacement = invoke_script(script_name=qurey_tuple[0][1:],
project=project,card=card,args=qurey_tuple[1:],
children_code=children_code)
elif attr_name in card:
replacement = str(card[attr_name])
else:
if len(qurey_tuple) >= 1:
replacement = qurey_tuple[-1]
else:
log_warning(f'[Formatter] 访问了不存在的属性,并且没有设定默认值: {attr_name}')
continue
stack.append(attr_name)
try:
replacement = format_code(replacement,card,project,children_code,stack)
finally:
stack.pop()
code = code.replace(f'${{{match}}}',replacement,1)
return code

def split_args(string:str):
'''分离参数'''
args = []
in_qoute = False
pare_deepth = 0
buffer = ''
for c in string:
buffer += c
if in_qoute:
if c == '"':
in_qoute = False
else:
if c == '{':
pare_deepth += 1
if pare_deepth > 0:
if c == '}':
pare_deepth -= 1
else:
match c:
case '|':
args.append(buffer[:-1])
buffer = ''
case '"':
in_qoute = True
args.append(buffer)
return args

def findall_placeholders(string:str):
'''寻找全部占位符'''
if not string:
return []
placeholders = []
pare_deepth = 0
sp_mode = False
buffer = ''
for c in string:
if pare_deepth > 0:
if c == '}':
pare_deepth -= 1
if pare_deepth == 0:
placeholders.append(buffer)
buffer = ''
else:
buffer += c
else:
buffer += c
if c == '{' and (sp_mode or pare_deepth > 0):
pare_deepth += 1
if c == '$':
sp_mode = True
else:
sp_mode = False
return placeholders
63 changes: 63 additions & 0 deletions Core/debug.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
'''
该模块用于输出调试与日志信息
'''

TAB_TEXT = ' '
CONSOLE_CLEAR = '\033[0m'
CONSOLE_BLACK = '\033[30m'
CONSOLE_RED = '\033[31m'
CONSOLE_GREEN = '\033[32m'
CONSOLE_YELLOW = '\033[33m'
CONSOLE_BLUE = '\033[34m'
CONSOLE_MAGENTA = '\033[35m'
CONSOLE_CYAN = '\033[36m'
CONSOLE_WHITE = '\033[37m'

class Logger:
'''日志记录器'''
def __init__(self,source_name):
self.source = source_name

def info(self,infomation:str):
'''输出信息'''
print(f'{CONSOLE_BLUE}[INFO]{CONSOLE_CLEAR}[{self.source}] {infomation}')

def warning(self,infomation:str):
'''输出警告'''
print(f'{CONSOLE_YELLOW}[WARNING]{CONSOLE_CLEAR}[{self.source}] {infomation}')

def debug(self,infomation:str):
'''输出调试信息'''
print(f'{CONSOLE_GREEN}[DEBUG]{CONSOLE_CLEAR}[{self.source}] {infomation}')

def error(self,infomation:str):
'''输出错误信息'''
print(f'{CONSOLE_RED}[ERROR][{self.source}] {infomation}')
return infomation

def fatal(self,infomation:str):
'''输出致命错误信息'''
print(f'{CONSOLE_RED}[FATAL][{self.source}] {infomation}')
return infomation

def log_info(infomation:str):
'''输出信息'''
print(f'{CONSOLE_BLUE}[INFO]{CONSOLE_CLEAR}{infomation}')

def log_warning(infomation:str):
'''输出警告'''
print(f'{CONSOLE_YELLOW}[WARNING]{CONSOLE_CLEAR}{infomation}')

def log_debug(infomation:str):
'''输出调试信息'''
print(f'{CONSOLE_GREEN}[DEBUG]{CONSOLE_CLEAR}{infomation}')

def log_error(infomation:str):
'''输出错误信息'''
print(f'{CONSOLE_RED}[ERROR]{infomation}')
return infomation

def log_fatal(infomation:str):
'''输出致命错误信息'''
print(f'{CONSOLE_RED}[FATAL]{infomation}')
return infomation
22 changes: 22 additions & 0 deletions Core/encode.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
'''
编码与反编码字符串模块
'''
esc_chars = {
'&':'&',
'<':'&lt;',
'>':'&gt;',
'"':'&quot;',
"'":'&apos;'
}

def decode_escape(string:str):
'''反编码转义字符'''
for key,value in esc_chars.items():
string = string.replace(value,key)
return string

def encode_escape(string:str):
'''编码转义字符'''
for key,value in esc_chars.items():
string = string.replace(key,value)
return string
125 changes: 125 additions & 0 deletions Core/library.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
'''
该模块内存放了卡片库类
'''
import os
from typing import Tuple
from .io import scan_dire,scan_sub_dire
from .debug import Logger
from .i18n import locale as t

logger = Logger('Library')
class Library:
'''卡片库类'''
def __init__(self,data:dict):
self.name= data['name']
logger.info(t('library.load',name=self.name))
self.fill = data.get('fill',{})
self.cover = data.get('cover',{})
self.card_mapping = {} # 卡片索引
self.libs_mapping = {} # 子库索引
self.sub_libraries = {} # 子库
self.cards = {}
self.location = os.path.dirname(data['file_path'])
for file_tuple in scan_dire(self.location,r'^(?!^__LIBRARY__.yml$).*$'): # 库所拥有的卡片
self.add_card_from_file_tuple(file_tuple)
self.add_sub_libraries(scan_sub_dire(self.location,'__LIBRARY__.yml')) # 遍历添加子库

@classmethod
def decorate_card(cls,card,fill,cover):
'''用 fill 和 cover 修饰卡片'''
if fill:
cloned_fill = fill.copy()
else:
cloned_fill = {}
if cover:
card.update(cover)
cloned_fill.update(card)
return cloned_fill

def __decorate_card(self,card):
'''用本卡片库的 fill 和 cover 修饰卡片'''
return self.decorate_card(card,self.fill,self.cover)

def __get_card_decoless(self,card_ref:str,is_original:bool):
'''获取未经 fill 和 cover 的卡片'''
if card_ref in self.cards:
return self.cards[card_ref]
if ':' in card_ref:
libname,cardname = card_ref.split(':',2)
if libname == self.name:
card_ref = cardname
else:
return self.get_card_from_lib_mapping(libname,cardname,is_original)
return self.get_card_from_card_mapping(card_ref,is_original)

def get_card(self,card_ref:str,is_original:bool):
'''获取卡片'''
target = self.__get_card_decoless(card_ref,is_original)
if is_original:
return target
else:
return self.__decorate_card(target)

def get_card_from_card_mapping(self,card_ref:str,is_original:bool):
'''通过库内的卡片映射获取卡片'''
if card_ref in self.cards:
return self.cards[card_ref].copy()
elif card_ref in self.card_mapping:
return self.card_mapping[card_ref].get_card(card_ref,is_original)
else:
raise KeyError(logger.error(f'[Library] Cannot find card "{card_ref}"'))

def get_card_from_lib_mapping(self,lib_name,card_ref,is_original):
'''通过库内的库映射获取卡片'''
if lib_name == 'T':
return {'templates':[card_ref]}
if lib_name in self.libs_mapping:
return self.libs_mapping[lib_name].get_card(card_ref,is_original)
else:
raise KeyError(logger.error(f'[Library] Cannot find library "{card_ref}"'))

def add_card_from_file_tuple(self,file_info_tuple:Tuple[object,str,str]):
'''通过文件元组添加卡片'''
data, filename, exten = file_info_tuple
name = filename
if isinstance(data,dict):
if 'name' in data:
name = data['name']
self.cards[name] = data
else:
self.cards[name] = {'data':data }
self.cards[name].update({'data':data,'file_name':filename,'file_exten':exten,
'card_id':f'{self.name}:{name}','card_lib':self.name,
'card_name':name})

def add_sub_libraries(self,yamldata):
'''增加子库'''
def add_sub_library(self,yamldata):
sublib = Library(yamldata)
self.sub_libraries.update({sublib.name:sublib})
# 将子库的卡片索引加入父库并映射到该子库
for cardname in sublib.card_mapping:
self.card_mapping.update({cardname:sublib})
# 将子库的所有卡片加入父库并映射到该子库
for cardname in sublib.cards:
self.card_mapping.update({cardname:sublib})
# 将子库的子库引加入父库并映射到该子库
for libname in sublib.libs_mapping:
self.libs_mapping.update({libname:sublib})
# 将该子库加入父库的子库索引
self.libs_mapping.update({sublib.name:sublib})
if isinstance(yamldata,list):
for data in yamldata:
self.add_sub_libraries(data)
elif isinstance(yamldata,tuple):
add_sub_library(self,yamldata[0])
else:
add_sub_library(self,yamldata)
# DEV NOTICE 如果映射的内存占用太大了就将每一个卡片和每一个子库的路径压成栈,交给根库来管理

def get_all_cards(self):
'''获取该库的所有卡片'''
result = [self.__decorate_card(card) for card in self.cards.values()]
for lib in self.sub_libraries.values():
result += [self.__decorate_card(card) for card in lib.get_all_cards()]
return result
Loading

0 comments on commit 22873d1

Please sign in to comment.