mirror of
https://github.com/sotam0316/brain_dogfood.git
synced 2026-04-25 03:48:38 +09:00
Initial Global Release v1.0 (Localization & Security Hardening)
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
import re
|
||||
from ..constants import GROUP_DEFAULT
|
||||
|
||||
def parse_metadata(text):
|
||||
"""
|
||||
텍스트에서 ##그룹명 과 #태그 추출 유틸리티.
|
||||
"""
|
||||
group_name = GROUP_DEFAULT
|
||||
tags = []
|
||||
|
||||
if not text:
|
||||
return group_name, tags
|
||||
|
||||
group_match = re.search(r'##(\S+)', text)
|
||||
if group_match:
|
||||
group_name = group_match.group(1)
|
||||
|
||||
tag_matches = re.finditer(r'(?<!#)#(\S+)', text)
|
||||
for match in tag_matches:
|
||||
tags.append(match.group(1))
|
||||
|
||||
return group_name, list(set(tags))
|
||||
|
||||
def extract_links(text):
|
||||
"""
|
||||
텍스트에서 [[#ID]] 형태의 내부 링크를 찾아 ID 목록(정수)을 반환합니다.
|
||||
"""
|
||||
if not text:
|
||||
return []
|
||||
|
||||
# [[#123]] 패턴 매칭
|
||||
links = re.findall(r'\[\[#(\d+)\]\]', text)
|
||||
return list(set([int(link_id) for link_id in links]))
|
||||
@@ -0,0 +1,41 @@
|
||||
import json
|
||||
import os
|
||||
from flask import current_app # type: ignore
|
||||
|
||||
class I18n:
|
||||
_locales = {}
|
||||
_default_lang = 'en'
|
||||
|
||||
@classmethod
|
||||
def load_locales(cls):
|
||||
locales_dir = os.path.join(current_app.static_folder, 'locales')
|
||||
for filename in os.listdir(locales_dir):
|
||||
if filename.endswith('.json'):
|
||||
lang = filename.split('.')[0]
|
||||
with open(os.path.join(locales_dir, filename), 'r', encoding='utf-8') as f:
|
||||
cls._locales[lang] = json.load(f)
|
||||
|
||||
@classmethod
|
||||
def t(cls, key, lang=None):
|
||||
if not lang:
|
||||
# 기본적으로 config에서 언어를 가져오거나 'en' 사용
|
||||
lang = current_app.config.get('lang', cls._default_lang)
|
||||
|
||||
if not cls._locales:
|
||||
cls.load_locales()
|
||||
|
||||
data = cls._locales.get(lang, cls._locales.get(cls._default_lang, {}))
|
||||
|
||||
# 중첩 키 지원 (예: "groups.done")
|
||||
parts = key.split('.')
|
||||
for p in parts:
|
||||
if isinstance(data, dict):
|
||||
data = data.get(p)
|
||||
else:
|
||||
return key
|
||||
|
||||
return data or key
|
||||
|
||||
# 숏컷 함수
|
||||
def _t(key, lang=None):
|
||||
return I18n.t(key, lang)
|
||||
Reference in New Issue
Block a user