feat: add category fields for BME.
- add category for BME prorotypes. - update validator and extractor for this change.
This commit is contained in:
@ -84,6 +84,7 @@
|
|||||||
"identifier": "floor_normal_1x1",
|
"identifier": "floor_normal_1x1",
|
||||||
"showcase": {
|
"showcase": {
|
||||||
"title": "Normal 1x1",
|
"title": "Normal 1x1",
|
||||||
|
"category": "1x1 Blocks",
|
||||||
"icon": "Normal1x1",
|
"icon": "Normal1x1",
|
||||||
"type": "floor",
|
"type": "floor",
|
||||||
"cfgs": [
|
"cfgs": [
|
||||||
@ -134,6 +135,7 @@
|
|||||||
"identifier": "floor_sink_1x1",
|
"identifier": "floor_sink_1x1",
|
||||||
"showcase": {
|
"showcase": {
|
||||||
"title": "Sink 1x1",
|
"title": "Sink 1x1",
|
||||||
|
"category": "1x1 Blocks",
|
||||||
"icon": "Sink1x1",
|
"icon": "Sink1x1",
|
||||||
"type": "floor",
|
"type": "floor",
|
||||||
"cfgs": [
|
"cfgs": [
|
||||||
|
@ -49,6 +49,7 @@
|
|||||||
"identifier": "floor_normal_border",
|
"identifier": "floor_normal_border",
|
||||||
"showcase": {
|
"showcase": {
|
||||||
"title": "Normal Border",
|
"title": "Normal Border",
|
||||||
|
"category": "Borders",
|
||||||
"icon": "NormalBorder",
|
"icon": "NormalBorder",
|
||||||
"type": "floor",
|
"type": "floor",
|
||||||
"cfgs": [
|
"cfgs": [
|
||||||
@ -112,6 +113,7 @@
|
|||||||
"identifier": "floor_sink_border",
|
"identifier": "floor_sink_border",
|
||||||
"showcase": {
|
"showcase": {
|
||||||
"title": "Sink Border",
|
"title": "Sink Border",
|
||||||
|
"category": "Borders",
|
||||||
"icon": "SinkBorder",
|
"icon": "SinkBorder",
|
||||||
"type": "floor",
|
"type": "floor",
|
||||||
"cfgs": [
|
"cfgs": [
|
||||||
@ -175,6 +177,7 @@
|
|||||||
"identifier": "floor_ribbon_border",
|
"identifier": "floor_ribbon_border",
|
||||||
"showcase": {
|
"showcase": {
|
||||||
"title": "Ribbon Border",
|
"title": "Ribbon Border",
|
||||||
|
"category": "Borders",
|
||||||
"icon": "RibbonBorder",
|
"icon": "RibbonBorder",
|
||||||
"type": "floor",
|
"type": "floor",
|
||||||
"cfgs": [
|
"cfgs": [
|
||||||
|
@ -149,6 +149,7 @@
|
|||||||
"identifier": "floor_normal_inner_corner",
|
"identifier": "floor_normal_inner_corner",
|
||||||
"showcase": {
|
"showcase": {
|
||||||
"title": "Normal Inner Corner",
|
"title": "Normal Inner Corner",
|
||||||
|
"category": "Half Block Corners",
|
||||||
"icon": "NormalInnerCorner",
|
"icon": "NormalInnerCorner",
|
||||||
"type": "floor",
|
"type": "floor",
|
||||||
"cfgs": [
|
"cfgs": [
|
||||||
@ -201,6 +202,7 @@
|
|||||||
"identifier": "floor_sink_inner_corner",
|
"identifier": "floor_sink_inner_corner",
|
||||||
"showcase": {
|
"showcase": {
|
||||||
"title": "Sink Inner Corner",
|
"title": "Sink Inner Corner",
|
||||||
|
"category": "Half Block Corners",
|
||||||
"icon": "SinkInnerCorner",
|
"icon": "SinkInnerCorner",
|
||||||
"type": "floor",
|
"type": "floor",
|
||||||
"cfgs": [
|
"cfgs": [
|
||||||
@ -253,6 +255,7 @@
|
|||||||
"identifier": "floor_ribbon_inner_corner",
|
"identifier": "floor_ribbon_inner_corner",
|
||||||
"showcase": {
|
"showcase": {
|
||||||
"title": "Ribbon Inner Corner",
|
"title": "Ribbon Inner Corner",
|
||||||
|
"category": "Half Block Corners",
|
||||||
"icon": "RibbonInnerCorner",
|
"icon": "RibbonInnerCorner",
|
||||||
"type": "floor",
|
"type": "floor",
|
||||||
"cfgs": [
|
"cfgs": [
|
||||||
@ -305,6 +308,7 @@
|
|||||||
"identifier": "floor_normal_outter_corner",
|
"identifier": "floor_normal_outter_corner",
|
||||||
"showcase": {
|
"showcase": {
|
||||||
"title": "Normal Outter Corner",
|
"title": "Normal Outter Corner",
|
||||||
|
"category": "Half Block Corners",
|
||||||
"icon": "NormalOutterCorner",
|
"icon": "NormalOutterCorner",
|
||||||
"type": "floor",
|
"type": "floor",
|
||||||
"cfgs": [
|
"cfgs": [
|
||||||
@ -357,6 +361,7 @@
|
|||||||
"identifier": "floor_sink_outter_corner",
|
"identifier": "floor_sink_outter_corner",
|
||||||
"showcase": {
|
"showcase": {
|
||||||
"title": "Sink Outter Corner",
|
"title": "Sink Outter Corner",
|
||||||
|
"category": "Half Block Corners",
|
||||||
"icon": "SinkOutterCorner",
|
"icon": "SinkOutterCorner",
|
||||||
"type": "floor",
|
"type": "floor",
|
||||||
"cfgs": [
|
"cfgs": [
|
||||||
@ -409,6 +414,7 @@
|
|||||||
"identifier": "floor_ribbon_outter_corner",
|
"identifier": "floor_ribbon_outter_corner",
|
||||||
"showcase": {
|
"showcase": {
|
||||||
"title": "Ribbon Outter Corner",
|
"title": "Ribbon Outter Corner",
|
||||||
|
"category": "Half Block Corners",
|
||||||
"icon": "RibbonOutterCorner",
|
"icon": "RibbonOutterCorner",
|
||||||
"type": "floor",
|
"type": "floor",
|
||||||
"cfgs": [
|
"cfgs": [
|
||||||
|
@ -228,6 +228,7 @@
|
|||||||
"identifier": "floor_normal_l_crossing",
|
"identifier": "floor_normal_l_crossing",
|
||||||
"showcase": {
|
"showcase": {
|
||||||
"title": "Normal L Crossing",
|
"title": "Normal L Crossing",
|
||||||
|
"category": "Floor Crossings",
|
||||||
"icon": "NormalLCrossing",
|
"icon": "NormalLCrossing",
|
||||||
"type": "floor",
|
"type": "floor",
|
||||||
"cfgs": [
|
"cfgs": [
|
||||||
@ -278,6 +279,7 @@
|
|||||||
"identifier": "floor_sink_l_crossing",
|
"identifier": "floor_sink_l_crossing",
|
||||||
"showcase": {
|
"showcase": {
|
||||||
"title": "Sink L Crossing",
|
"title": "Sink L Crossing",
|
||||||
|
"category": "Floor Crossings",
|
||||||
"icon": "SinkLCrossing",
|
"icon": "SinkLCrossing",
|
||||||
"type": "floor",
|
"type": "floor",
|
||||||
"cfgs": [
|
"cfgs": [
|
||||||
@ -328,6 +330,7 @@
|
|||||||
"identifier": "floor_normal_t_crossing",
|
"identifier": "floor_normal_t_crossing",
|
||||||
"showcase": {
|
"showcase": {
|
||||||
"title": "Normal T Crossing",
|
"title": "Normal T Crossing",
|
||||||
|
"category": "Floor Crossings",
|
||||||
"icon": "NormalTCrossing",
|
"icon": "NormalTCrossing",
|
||||||
"type": "floor",
|
"type": "floor",
|
||||||
"cfgs": [
|
"cfgs": [
|
||||||
@ -378,6 +381,7 @@
|
|||||||
"identifier": "floor_sink_t_crossing",
|
"identifier": "floor_sink_t_crossing",
|
||||||
"showcase": {
|
"showcase": {
|
||||||
"title": "Sink T Crossing",
|
"title": "Sink T Crossing",
|
||||||
|
"category": "Floor Crossings",
|
||||||
"icon": "SinkTCrossing",
|
"icon": "SinkTCrossing",
|
||||||
"type": "floor",
|
"type": "floor",
|
||||||
"cfgs": [
|
"cfgs": [
|
||||||
@ -428,6 +432,7 @@
|
|||||||
"identifier": "floor_normal_x_crossing",
|
"identifier": "floor_normal_x_crossing",
|
||||||
"showcase": {
|
"showcase": {
|
||||||
"title": "Normal X Crossing",
|
"title": "Normal X Crossing",
|
||||||
|
"category": "Floor Crossings",
|
||||||
"icon": "NormalXCrossing",
|
"icon": "NormalXCrossing",
|
||||||
"type": "floor",
|
"type": "floor",
|
||||||
"cfgs": [
|
"cfgs": [
|
||||||
@ -478,6 +483,7 @@
|
|||||||
"identifier": "floor_sink_x_crossing",
|
"identifier": "floor_sink_x_crossing",
|
||||||
"showcase": {
|
"showcase": {
|
||||||
"title": "Sink X Crossing",
|
"title": "Sink X Crossing",
|
||||||
|
"category": "Floor Crossings",
|
||||||
"icon": "SinkXCrossing",
|
"icon": "SinkXCrossing",
|
||||||
"type": "floor",
|
"type": "floor",
|
||||||
"cfgs": [
|
"cfgs": [
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
"identifier": "floor_flat",
|
"identifier": "floor_flat",
|
||||||
"showcase": {
|
"showcase": {
|
||||||
"title": "Flat",
|
"title": "Flat",
|
||||||
|
"category": "Miscellaneous",
|
||||||
"icon": "Flat",
|
"icon": "Flat",
|
||||||
"type": "floor",
|
"type": "floor",
|
||||||
"cfgs": [
|
"cfgs": [
|
||||||
|
@ -116,6 +116,7 @@
|
|||||||
"identifier": "floor_normal_platform",
|
"identifier": "floor_normal_platform",
|
||||||
"showcase": {
|
"showcase": {
|
||||||
"title": "Normal Platform",
|
"title": "Normal Platform",
|
||||||
|
"category": "Platforms",
|
||||||
"icon": "NormalPlatform",
|
"icon": "NormalPlatform",
|
||||||
"type": "floor",
|
"type": "floor",
|
||||||
"cfgs": [
|
"cfgs": [
|
||||||
@ -191,6 +192,7 @@
|
|||||||
"identifier": "floor_sink_platform",
|
"identifier": "floor_sink_platform",
|
||||||
"showcase": {
|
"showcase": {
|
||||||
"title": "Sink Platform",
|
"title": "Sink Platform",
|
||||||
|
"category": "Platforms",
|
||||||
"icon": "SinkPlatform",
|
"icon": "SinkPlatform",
|
||||||
"type": "floor",
|
"type": "floor",
|
||||||
"cfgs": [
|
"cfgs": [
|
||||||
@ -266,6 +268,7 @@
|
|||||||
"identifier": "floor_ribbon_platform",
|
"identifier": "floor_ribbon_platform",
|
||||||
"showcase": {
|
"showcase": {
|
||||||
"title": "Ribbon Platform",
|
"title": "Ribbon Platform",
|
||||||
|
"category": "Platforms",
|
||||||
"icon": "RibbonPlatform",
|
"icon": "RibbonPlatform",
|
||||||
"type": "floor",
|
"type": "floor",
|
||||||
"cfgs": [
|
"cfgs": [
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
"identifier": "floor_normal_straight",
|
"identifier": "floor_normal_straight",
|
||||||
"showcase": {
|
"showcase": {
|
||||||
"title": "Normal Floor",
|
"title": "Normal Floor",
|
||||||
|
"category": "Floors",
|
||||||
"icon": "NormalFloor",
|
"icon": "NormalFloor",
|
||||||
"type": "floor",
|
"type": "floor",
|
||||||
"cfgs": [
|
"cfgs": [
|
||||||
@ -142,6 +143,7 @@
|
|||||||
"identifier": "floor_sink_straight",
|
"identifier": "floor_sink_straight",
|
||||||
"showcase": {
|
"showcase": {
|
||||||
"title": "Sink Floor",
|
"title": "Sink Floor",
|
||||||
|
"category": "Floors",
|
||||||
"icon": "SinkFloor",
|
"icon": "SinkFloor",
|
||||||
"type": "floor",
|
"type": "floor",
|
||||||
"cfgs": [
|
"cfgs": [
|
||||||
|
@ -77,6 +77,7 @@
|
|||||||
"identifier": "floor_normal_terminal",
|
"identifier": "floor_normal_terminal",
|
||||||
"showcase": {
|
"showcase": {
|
||||||
"title": "Normal Floor Terminal",
|
"title": "Normal Floor Terminal",
|
||||||
|
"category": "Floors",
|
||||||
"icon": "NormalFloorTerminal",
|
"icon": "NormalFloorTerminal",
|
||||||
"type": "floor",
|
"type": "floor",
|
||||||
"cfgs": [
|
"cfgs": [
|
||||||
@ -127,6 +128,7 @@
|
|||||||
"identifier": "floor_sink_terminal",
|
"identifier": "floor_sink_terminal",
|
||||||
"showcase": {
|
"showcase": {
|
||||||
"title": "Sink Floor Terminal",
|
"title": "Sink Floor Terminal",
|
||||||
|
"category": "Floors",
|
||||||
"icon": "SinkFloorTerminal",
|
"icon": "SinkFloorTerminal",
|
||||||
"type": "floor",
|
"type": "floor",
|
||||||
"cfgs": [
|
"cfgs": [
|
||||||
|
@ -137,6 +137,7 @@
|
|||||||
"identifier": "wood_trafo",
|
"identifier": "wood_trafo",
|
||||||
"showcase": {
|
"showcase": {
|
||||||
"title": "Wood Trafo",
|
"title": "Wood Trafo",
|
||||||
|
"category": "Trafo",
|
||||||
"icon": "WoodTrafo",
|
"icon": "WoodTrafo",
|
||||||
"type": "floor",
|
"type": "floor",
|
||||||
"cfgs": [
|
"cfgs": [
|
||||||
@ -187,6 +188,7 @@
|
|||||||
"identifier": "stone_trafo",
|
"identifier": "stone_trafo",
|
||||||
"showcase": {
|
"showcase": {
|
||||||
"title": "Stone Trafo",
|
"title": "Stone Trafo",
|
||||||
|
"category": "Trafo",
|
||||||
"icon": "StoneTrafo",
|
"icon": "StoneTrafo",
|
||||||
"type": "floor",
|
"type": "floor",
|
||||||
"cfgs": [
|
"cfgs": [
|
||||||
@ -237,6 +239,7 @@
|
|||||||
"identifier": "paper_trafo",
|
"identifier": "paper_trafo",
|
||||||
"showcase": {
|
"showcase": {
|
||||||
"title": "Paper Trafo",
|
"title": "Paper Trafo",
|
||||||
|
"category": "Trafo",
|
||||||
"icon": "PaperTrafo",
|
"icon": "PaperTrafo",
|
||||||
"type": "floor",
|
"type": "floor",
|
||||||
"cfgs": [
|
"cfgs": [
|
||||||
|
@ -111,6 +111,7 @@
|
|||||||
"identifier": "floor_transition",
|
"identifier": "floor_transition",
|
||||||
"showcase": {
|
"showcase": {
|
||||||
"title": "Transition",
|
"title": "Transition",
|
||||||
|
"category": "Miscellaneous",
|
||||||
"icon": "Transition",
|
"icon": "Transition",
|
||||||
"type": "floor",
|
"type": "floor",
|
||||||
"cfgs": [
|
"cfgs": [
|
||||||
@ -191,6 +192,7 @@
|
|||||||
"identifier": "floor_narrow_transition",
|
"identifier": "floor_narrow_transition",
|
||||||
"showcase": {
|
"showcase": {
|
||||||
"title": "Narrow Transition",
|
"title": "Narrow Transition",
|
||||||
|
"category": "Miscellaneous",
|
||||||
"icon": "NarrowTransition",
|
"icon": "NarrowTransition",
|
||||||
"type": "floor",
|
"type": "floor",
|
||||||
"cfgs": [
|
"cfgs": [
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
"identifier": "floor_wide_straight",
|
"identifier": "floor_wide_straight",
|
||||||
"showcase": {
|
"showcase": {
|
||||||
"title": "Wide Floor",
|
"title": "Wide Floor",
|
||||||
|
"category": "Wide Floors",
|
||||||
"icon": "WideFloor",
|
"icon": "WideFloor",
|
||||||
"type": "floor",
|
"type": "floor",
|
||||||
"cfgs": [
|
"cfgs": [
|
||||||
@ -106,6 +107,7 @@
|
|||||||
"identifier": "floor_wide_terminal",
|
"identifier": "floor_wide_terminal",
|
||||||
"showcase": {
|
"showcase": {
|
||||||
"title": "Wide Floor Terminal",
|
"title": "Wide Floor Terminal",
|
||||||
|
"category": "Wide Floors",
|
||||||
"icon": "WideFloorTerminal",
|
"icon": "WideFloorTerminal",
|
||||||
"type": "floor",
|
"type": "floor",
|
||||||
"cfgs": [
|
"cfgs": [
|
||||||
@ -220,6 +222,7 @@
|
|||||||
"identifier": "floor_wide_l_crossing",
|
"identifier": "floor_wide_l_crossing",
|
||||||
"showcase": {
|
"showcase": {
|
||||||
"title": "Wide Floor L Crossing",
|
"title": "Wide Floor L Crossing",
|
||||||
|
"category": "Wide Floors",
|
||||||
"icon": "WideLCrossing",
|
"icon": "WideLCrossing",
|
||||||
"type": "floor",
|
"type": "floor",
|
||||||
"cfgs": [
|
"cfgs": [
|
||||||
@ -352,6 +355,7 @@
|
|||||||
"identifier": "floor_wide_t_crossing",
|
"identifier": "floor_wide_t_crossing",
|
||||||
"showcase": {
|
"showcase": {
|
||||||
"title": "Wide Floor T Crossing",
|
"title": "Wide Floor T Crossing",
|
||||||
|
"category": "Wide Floors",
|
||||||
"icon": "WideTCrossing",
|
"icon": "WideTCrossing",
|
||||||
"type": "floor",
|
"type": "floor",
|
||||||
"cfgs": [
|
"cfgs": [
|
||||||
@ -475,6 +479,7 @@
|
|||||||
"identifier": "floor_wide_x_crossing",
|
"identifier": "floor_wide_x_crossing",
|
||||||
"showcase": {
|
"showcase": {
|
||||||
"title": "Wide Floor X Crossing",
|
"title": "Wide Floor X Crossing",
|
||||||
|
"category": "Wide Floors",
|
||||||
"icon": "WideXCrossing",
|
"icon": "WideXCrossing",
|
||||||
"type": "floor",
|
"type": "floor",
|
||||||
"cfgs": [
|
"cfgs": [
|
||||||
|
@ -27,6 +27,7 @@ class ShowcaseCfg(BaseModel):
|
|||||||
|
|
||||||
class Showcase(BaseModel):
|
class Showcase(BaseModel):
|
||||||
title: str = Field(frozen=True, strict=True)
|
title: str = Field(frozen=True, strict=True)
|
||||||
|
category: str = Field(frozen=True, strict=True)
|
||||||
icon: str = Field(frozen=True, strict=True)
|
icon: str = Field(frozen=True, strict=True)
|
||||||
type: ShowcaseType = Field(frozen=True)
|
type: ShowcaseType = Field(frozen=True)
|
||||||
cfgs: list[ShowcaseCfg] = Field(frozen=True, strict=True)
|
cfgs: list[ShowcaseCfg] = Field(frozen=True, strict=True)
|
||||||
|
@ -9,80 +9,96 @@ import pydantic, polib, json5
|
|||||||
# If the context string of translation changed, please synchronize it.
|
# If the context string of translation changed, please synchronize it.
|
||||||
|
|
||||||
CTX_TRANSLATION: str = 'BBP/BME'
|
CTX_TRANSLATION: str = 'BBP/BME'
|
||||||
|
CTX_PROTOTYPE: str = f'{CTX_TRANSLATION}/Proto'
|
||||||
|
CTX_CATEGORY: str = f'{CTX_TRANSLATION}/Category'
|
||||||
|
|
||||||
|
|
||||||
def _extract_prototype(prototype: bme.Prototype) -> typing.Iterator[polib.POEntry]:
|
class JsonsExtractor:
|
||||||
identifier = prototype.identifier
|
|
||||||
showcase = prototype.showcase
|
|
||||||
|
|
||||||
# Show message
|
po: polib.POFile
|
||||||
logging.info(f'Extracting prototype {identifier}')
|
"""Extracted PO file"""
|
||||||
|
categories: set[str]
|
||||||
|
"""Set for removing duplicated category names"""
|
||||||
|
|
||||||
# Extract showcase
|
def __init__(self) -> None:
|
||||||
if showcase is None:
|
# create po file
|
||||||
return
|
self.po = polib.POFile()
|
||||||
|
self.po.metadata = {
|
||||||
|
'Project-Id-Version': '1.0',
|
||||||
|
'Report-Msgid-Bugs-To': 'you@example.com',
|
||||||
|
'POT-Creation-Date': 'YEAR-MO-DA HO:MI+ZONE',
|
||||||
|
'PO-Revision-Date': 'YEAR-MO-DA HO:MI+ZONE',
|
||||||
|
'Last-Translator': 'FULL NAME <EMAIL@ADDRESS>',
|
||||||
|
'Language-Team': 'LANGUAGE <LL@li.org>',
|
||||||
|
'MIME-Version': '1.0',
|
||||||
|
'Content-Type': 'text/plain; charset=utf-8',
|
||||||
|
'Content-Transfer-Encoding': '8bit',
|
||||||
|
'X-Generator': 'polib',
|
||||||
|
}
|
||||||
|
# create category set
|
||||||
|
self.categories = set()
|
||||||
|
|
||||||
# Extract showcase title
|
def __extract_prototype(self, prototype: bme.Prototype) -> None:
|
||||||
yield polib.POEntry(msgid=showcase.title, msgstr='', msgctxt=f'{CTX_TRANSLATION}/{identifier}')
|
identifier = prototype.identifier
|
||||||
# Extract showcase entries
|
showcase = prototype.showcase
|
||||||
for i, cfg in enumerate(showcase.cfgs):
|
|
||||||
# extract title and description
|
|
||||||
yield polib.POEntry(msgid=cfg.title, msgstr='', msgctxt=f'{CTX_TRANSLATION}/{identifier}/[{i}]')
|
|
||||||
yield polib.POEntry(msgid=cfg.desc, msgstr='', msgctxt=f'{CTX_TRANSLATION}/{identifier}/[{i}]')
|
|
||||||
|
|
||||||
|
# Show message
|
||||||
|
logging.info(f'Extracting prototype {identifier}')
|
||||||
|
|
||||||
def _extract_json(json_file: Path) -> typing.Iterator[polib.POEntry]:
|
# Extract showcase
|
||||||
# Show message
|
if showcase is None:
|
||||||
logging.info(f'Extracting file {json_file}')
|
return
|
||||||
|
|
||||||
try:
|
# Extract showcase title
|
||||||
# Read file and convert it into BME struct.
|
self.po.append(polib.POEntry(msgid=showcase.title, msgstr='', msgctxt=f'{CTX_PROTOTYPE}/{identifier}'))
|
||||||
with open(json_file, 'r', encoding='utf-8') as f:
|
# extract showcase category
|
||||||
document = json5.load(f)
|
if showcase.category not in self.categories:
|
||||||
prototypes = bme.Prototypes.model_validate(document)
|
self.po.append(polib.POEntry(msgid=showcase.category, msgstr='', msgctxt=CTX_CATEGORY))
|
||||||
# Extract translation
|
self.categories.add(showcase.category)
|
||||||
return itertools.chain.from_iterable(_extract_prototype(prototype) for prototype in prototypes.root)
|
# Extract showcase entries
|
||||||
except pydantic.ValidationError:
|
for i, cfg in enumerate(showcase.cfgs):
|
||||||
logging.error(f'Can not extract translation from {json_file} due to struct error. Please validate it first.')
|
# extract title and description
|
||||||
except (ValueError, UnicodeDecodeError):
|
self.po.append(polib.POEntry(msgid=cfg.title, msgstr='', msgctxt=f'{CTX_PROTOTYPE}/{identifier}/[{i}]'))
|
||||||
logging.error(f'Can not extract translation from {json_file} due to JSON5 error. Please validate it first.')
|
self.po.append(polib.POEntry(msgid=cfg.desc, msgstr='', msgctxt=f'{CTX_PROTOTYPE}/{identifier}/[{i}]'))
|
||||||
|
|
||||||
# Output nothing
|
def __extract_json(self, json_file: Path) -> None:
|
||||||
return itertools.chain.from_iterable(())
|
# Show message
|
||||||
|
logging.info(f'Extracting file {json_file}')
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Read file and convert it into BME struct.
|
||||||
|
with open(json_file, 'r', encoding='utf-8') as f:
|
||||||
|
document = json5.load(f)
|
||||||
|
prototypes = bme.Prototypes.model_validate(document)
|
||||||
|
# Extract translation
|
||||||
|
for prototype in prototypes.root:
|
||||||
|
self.__extract_prototype(prototype)
|
||||||
|
except pydantic.ValidationError:
|
||||||
|
logging.error(
|
||||||
|
f'Can not extract translation from {json_file} due to struct error. Please validate it first.')
|
||||||
|
except (ValueError, UnicodeDecodeError):
|
||||||
|
logging.error(f'Can not extract translation from {json_file} due to JSON5 error. Please validate it first.')
|
||||||
|
|
||||||
def extract_jsons() -> None:
|
def extract_jsons(self) -> None:
|
||||||
raw_jsons_dir = common.get_raw_assets_folder(AssetKind.Jsons)
|
raw_jsons_dir = common.get_raw_assets_folder(AssetKind.Jsons)
|
||||||
|
|
||||||
# Create POT content
|
# Iterate all prototypes and add into POT
|
||||||
po = polib.POFile()
|
for raw_json_file in raw_jsons_dir.glob('*.json5'):
|
||||||
po.metadata = {
|
# Skip non-file.
|
||||||
'Project-Id-Version': '1.0',
|
if not raw_json_file.is_file():
|
||||||
'Report-Msgid-Bugs-To': 'you@example.com',
|
continue
|
||||||
'POT-Creation-Date': 'YEAR-MO-DA HO:MI+ZONE',
|
# Extract json
|
||||||
'PO-Revision-Date': 'YEAR-MO-DA HO:MI+ZONE',
|
self.__extract_json(raw_json_file)
|
||||||
'Last-Translator': 'FULL NAME <EMAIL@ADDRESS>',
|
|
||||||
'Language-Team': 'LANGUAGE <LL@li.org>',
|
|
||||||
'MIME-Version': '1.0',
|
|
||||||
'Content-Type': 'text/plain; charset=utf-8',
|
|
||||||
'Content-Transfer-Encoding': '8bit',
|
|
||||||
'X-Generator': 'polib',
|
|
||||||
}
|
|
||||||
|
|
||||||
# Iterate all prototypes and add into POT
|
def save(self) -> None:
|
||||||
for raw_json_file in raw_jsons_dir.glob('*.json5'):
|
"""Save extracted POT file into correct path"""
|
||||||
# Skip non-file.
|
pot_file = common.get_root_folder() / 'i18n' / 'bme.pot'
|
||||||
if not raw_json_file.is_file():
|
logging.info(f'Saving POT into {pot_file}')
|
||||||
continue
|
self.po.save(str(pot_file))
|
||||||
# Extract json and append it.
|
|
||||||
po.extend(_extract_json(raw_json_file))
|
|
||||||
|
|
||||||
# Write into POT file
|
|
||||||
pot_file = common.get_root_folder() / 'i18n' / 'bme.pot'
|
|
||||||
logging.info(f'Saving POT into {pot_file}')
|
|
||||||
po.save(str(pot_file))
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
common.setup_logging()
|
common.setup_logging()
|
||||||
extract_jsons()
|
extractor = JsonsExtractor()
|
||||||
|
extractor.extract_jsons()
|
||||||
|
extractor.save()
|
||||||
|
@ -48,6 +48,9 @@ def _validate_showcase(showcase: bme.Showcase, variables: set[str]) -> None:
|
|||||||
# The title of showcase should not be empty
|
# The title of showcase should not be empty
|
||||||
if len(showcase.title) == 0:
|
if len(showcase.title) == 0:
|
||||||
logging.error('The title of showcase should not be empty.')
|
logging.error('The title of showcase should not be empty.')
|
||||||
|
# Category words should not be empty.
|
||||||
|
if len(showcase.category) == 0:
|
||||||
|
logging.error('The category of showcase should not be empty.')
|
||||||
|
|
||||||
# Check icon name
|
# Check icon name
|
||||||
_check_showcase_icon(showcase.icon)
|
_check_showcase_icon(showcase.icon)
|
||||||
|
Reference in New Issue
Block a user