From 0cfe6834fa08fe3c6d3cf0152c581fb61e644b98 Mon Sep 17 00:00:00 2001 From: Nightsky <050644zf@outlook.com> Date: Thu, 13 Feb 2025 18:19:07 +0800 Subject: [PATCH 1/4] have bug in 'decision' and main_14 processing --- codespace.sh | 13 +++- epub_convert.py | 172 ++++++++++++++++++++++++++++++++++++++++++++++++ func.py | 2 +- 3 files changed, 184 insertions(+), 3 deletions(-) create mode 100644 epub_convert.py diff --git a/codespace.sh b/codespace.sh index 237c55b..e484502 100644 --- a/codespace.sh +++ b/codespace.sh @@ -1,15 +1,24 @@ # using light yellow color echo -e "\033[1;33m Initializing... \033[0m" pip install openpyxl > /dev/null 2>&1 -echo -e "\033[1;33m Downloading latest data... \033[0m" -git clone https://github.com/Kengxxiao/ArknightsGameData.git # using light green color echo -e "\033[1;32m Initialization complete. \033[0m" echo -e "\033[1;33m Available servers:\033[0m zh_CN, en_US, ko_KR, ja_JP, zh_TW" echo -e "Enter the server you want to use, press Enter to continue, Blank for zh_CN: " read server +echo -e "\033[1;33m Downloading latest data... \033[0m" if [ -z "$server" ]; then server="zh_CN" + git clone https://github.com/Kengxxiao/ArknightsGameData.git +else + server=$server + # only pull the $server folder from Kengxxiao/ArknightsGameData_YoStar + git clone --depth 1 --filter=blob:none --sparse https://github.com/Kengxxiao/ArknightsGameData_YoStar.git + cd ArknightsGameData_YoStar + git sparse-checkout init --cone + git sparse-checkout set $server + cd .. + mv ArknightsGameData_YoStar/$server ArknightsGameData fi echo -e "Current Server: \033[1;33m $server\033[0m" diff --git a/epub_convert.py b/epub_convert.py new file mode 100644 index 0000000..ad2e41a --- /dev/null +++ b/epub_convert.py @@ -0,0 +1,172 @@ +from ebooklib import epub +from pathlib import Path +from jsonconvert import reader +from typing import Iterable + +import json +import re + +import func + +EPUB_CHAPTER_TEMPLATE = """ + + + {story.storyCode} {story.storyName} {story.avgTag} + + + {lines} + +""" + +DOCTOR = "Doctor" + +EPUB_NAME_TEMPLATE = "

{name} {content}

" + +EPUB_BRANCH_TEMPLATE = "
  • {option}
  • " + + +def parseContent(content: str, doctor=DOCTOR) -> str: + color_re = re.compile(r"(.+?)<\/color>", re.MULTILINE) + nbsp_sub_before = re.compile(r"(\s+)(<\/?\w+>)", re.MULTILINE) + nbsp_sub_after = re.compile(r"(<\/?\w+>)(\s+)", re.MULTILINE) + content = content.replace("{@nickname}", doctor) + content = re.sub(r"(?:\r\n|\r|\n|\\n|\\r)", "
    ", content) + content = color_re.sub(r'\2', content) + content = nbsp_sub_before.sub(r" \2", content) + content = nbsp_sub_after.sub(r"\1 ", content) + return content + + +def parseHTML(story_json): + lines = [] + rawlist = story_json["storyList"] + for lidx, line in enumerate(rawlist): + index = line["id"] + prop: str = line["prop"].lower() + attrs = line["attributes"] + + if prop == "name": + lines.append( + EPUB_NAME_TEMPLATE.format( + index=index, + name=attrs.get('name',''), content=parseContent(attrs.get("content", "")) + ) + ) + + if prop == 'multiline': + lines.append( + EPUB_NAME_TEMPLATE.format( + index=index, + name=attrs.get('name',''), content=parseContent(attrs.get("content", "")) + ) + ) + + if prop == 'decision': + options = attrs['options'].split(';') + values = attrs['values'].split(';') + targetLines = line['targetLine'] + options = '' + for i, option in enumerate(options): + options += EPUB_BRANCH_TEMPLATE.format(index=targetLines[f'option{values}'], option=option) + lines.append( + '
      {options}
    '.format(index=index, options=options) + ) + + if prop == 'predicate': + if line.get('endOfOpt'): + lines.append('

    ---End of Options---

    '.format(index=index)) + else: + lines.append('

    ---{option}---

    '.format(index=index,option=attrs['references'].replace(';', '&'))) + + if prop == 'subtitle': + lines.append('

    {content}


    '.format(index=index, content=parseContent(attrs.get('text', '')))) + + if prop == 'sticker': + lines.append('

    {content}

    '.format(index=index, content=parseContent(attrs.get('text', '')))) + + if prop == 'stickerclear': + lines.append('
    ') + + if prop == 'image': + lines.append('

    {content}

    '.format(index=index, content=attrs.get('image', ''))) + + + return lines + + + + +DATA_PATH = Path(r"ArknightsStoryJson") + +lang = "zh_CN" +epub_lang = lang.replace("_", "-") +event_id = "main_0" +event: Iterable[func.Story] = func.Event(DATA_PATH, lang, event_id) + +file_name = f"{event.eventid}_{event.name}.epub" + +book = epub.EpubBook() +book.set_identifier(f"{event.eventid} {lang}") +book.set_title(event.name) +book.set_language(epub_lang) +book.add_author("HyperGryph") + +chapters = [] +for idx, story in enumerate(event): + chapter = epub.EpubHtml( + title=f"{story.storyCode} {story.storyName} {story.avgTag}", + file_name=f"{story.storyCode}_{story.storyName}_{story.avgTag}.xhtml", + lang=epub_lang, + ) + with open(story.storyTxt.with_suffix(".json"), encoding="utf-8") as f: + story_json = json.load(f) + + lines = parseHTML(story_json) + chapter.content = EPUB_CHAPTER_TEMPLATE.format(story=story, lines="".join(lines)) + book.add_item(chapter) + chapters.append(chapter) + +book.toc = chapters +book.add_item(epub.EpubNcx()) +book.add_item(epub.EpubNav()) + +style = ''' +@namespace epub "http://www.idpf.org/2007/ops"; + +body { + font-family: Cambria, Liberation Serif, Bitstream Vera Serif, Georgia, Times, Times New Roman, serif; +} + +h2 { + text-align: left; + text-transform: uppercase; + font-weight: 200; +} + +ol { + list-style-type: none; +} + +ol > li:first-child { + margin-top: 0.3em; +} + + +nav[epub|type~='toc'] > ol > li > ol { + list-style-type:square; +} + + +nav[epub|type~='toc'] > ol > li > ol > li { + margin-top: 0.3em; +} + +''' + +# add css file +nav_css = epub.EpubItem(uid="style_nav", file_name="style/nav.css", media_type="text/css", content=style) +book.add_item(nav_css) + +book.spine = ["nav"] + chapters + +epub.write_epub(file_name, book, {}) diff --git a/func.py b/func.py index 5a6d029..c0177a2 100644 --- a/func.py +++ b/func.py @@ -26,7 +26,7 @@ def __init__(self, data_dir:Path, lang:str, eventid:str): self.storyList = self.review['infoUnlockDatas'] - def __getitem__(self, idx): + def __getitem__(self, idx)->'Story': return Story(self, self.storyList[idx]) def __len__(self): From 89f41a6bf58634c93776dca1de3359d313bca619 Mon Sep 17 00:00:00 2001 From: Nightsky <050644zf@outlook.com> Date: Sat, 15 Feb 2025 17:15:11 +0800 Subject: [PATCH 2/4] have bugs in main_14 --- .gitignore | 2 ++ epub_convert.py | 28 +++++++++++++++------------- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/.gitignore b/.gitignore index 33b2087..47bee10 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,5 @@ reader/dist/* *.ipynb ArknightsGameData_YoStar/ /ArknightsResource +/htmls +*.epub diff --git a/epub_convert.py b/epub_convert.py index ad2e41a..24dc44f 100644 --- a/epub_convert.py +++ b/epub_convert.py @@ -48,7 +48,7 @@ def parseHTML(story_json): if prop == "name": lines.append( EPUB_NAME_TEMPLATE.format( - index=index, + index=f'line{index}', name=attrs.get('name',''), content=parseContent(attrs.get("content", "")) ) ) @@ -56,7 +56,7 @@ def parseHTML(story_json): if prop == 'multiline': lines.append( EPUB_NAME_TEMPLATE.format( - index=index, + index=f'line{index}', name=attrs.get('name',''), content=parseContent(attrs.get("content", "")) ) ) @@ -65,30 +65,30 @@ def parseHTML(story_json): options = attrs['options'].split(';') values = attrs['values'].split(';') targetLines = line['targetLine'] - options = '' - for i, option in enumerate(options): - options += EPUB_BRANCH_TEMPLATE.format(index=targetLines[f'option{values}'], option=option) + options_html = [] + for i in range(min(len(values),len(options))): + options_html.append(EPUB_BRANCH_TEMPLATE.format(index=targetLines.get(f'option{values[i]}',f'{index+1}'), option=options[i])) lines.append( - '
      {options}
    '.format(index=index, options=options) + '

    \n

      \n{options}\n
    \n

    '.format(index=index, options='\n'.join(options_html)) ) if prop == 'predicate': if line.get('endOfOpt'): - lines.append('

    ---End of Options---

    '.format(index=index)) + lines.append('

    ---End of Options---

    '.format(index=index)) else: - lines.append('

    ---{option}---

    '.format(index=index,option=attrs['references'].replace(';', '&'))) + lines.append('

    ---{option}---

    '.format(index=index,option=attrs['references'].replace(';', '&'))) if prop == 'subtitle': - lines.append('

    {content}


    '.format(index=index, content=parseContent(attrs.get('text', '')))) + lines.append('

    {content}


    '.format(index=index, content=parseContent(attrs.get('text', '')))) if prop == 'sticker': - lines.append('

    {content}

    '.format(index=index, content=parseContent(attrs.get('text', '')))) + lines.append('

    {content}

    '.format(index=index, content=parseContent(attrs.get('text', '')))) if prop == 'stickerclear': lines.append('
    ') if prop == 'image': - lines.append('

    {content}

    '.format(index=index, content=attrs.get('image', ''))) + lines.append('

    {content}

    '.format(index=index, content=attrs.get('image', ''))) return lines @@ -100,7 +100,7 @@ def parseHTML(story_json): lang = "zh_CN" epub_lang = lang.replace("_", "-") -event_id = "main_0" +event_id = "act40side" event: Iterable[func.Story] = func.Event(DATA_PATH, lang, event_id) file_name = f"{event.eventid}_{event.name}.epub" @@ -122,7 +122,9 @@ def parseHTML(story_json): story_json = json.load(f) lines = parseHTML(story_json) - chapter.content = EPUB_CHAPTER_TEMPLATE.format(story=story, lines="".join(lines)) + chapter.content = EPUB_CHAPTER_TEMPLATE.format(story=story, lines="\n".join(lines)) + with open(f'htmls/{chapter.file_name}', 'w', encoding='utf-8') as f: + f.write(chapter.content) book.add_item(chapter) chapters.append(chapter) From dedb2203267fedb185bf95e6fb5f40d6959b9a2f Mon Sep 17 00:00:00 2001 From: Nightsky <050644zf@outlook.com> Date: Tue, 18 Feb 2025 09:26:40 +0800 Subject: [PATCH 3/4] Fix html tag, add storyname strip --- epub_convert.py | 6 +++--- func.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/epub_convert.py b/epub_convert.py index 24dc44f..9c0efe9 100644 --- a/epub_convert.py +++ b/epub_convert.py @@ -20,9 +20,9 @@ DOCTOR = "Doctor" -EPUB_NAME_TEMPLATE = "

    {name} {content}

    " +EPUB_NAME_TEMPLATE = '

    {name} {content}

    ' -EPUB_BRANCH_TEMPLATE = "
  • {option}
  • " +EPUB_BRANCH_TEMPLATE = '
  • {option}
  • ' def parseContent(content: str, doctor=DOCTOR) -> str: @@ -96,7 +96,7 @@ def parseHTML(story_json): -DATA_PATH = Path(r"ArknightsStoryJson") +DATA_PATH = Path(r"D:\zf-py\ArknightsStoryJson") lang = "zh_CN" epub_lang = lang.replace("_", "-") diff --git a/func.py b/func.py index c0177a2..844dcb4 100644 --- a/func.py +++ b/func.py @@ -45,7 +45,7 @@ def __init__(self, event:Event, storyData:dict): self.storyData = storyData self.storyCode = storyData['storyCode'] self.avgTag = storyData['avgTag'] if storyData['avgTag'] else '' - self.storyName = storyData['storyName'] + self.storyName = storyData['storyName'].strip() self.storyInfo = self.root_dir/'gamedata/story/[uc]{}.txt'.format(storyData['storyInfo']) if storyData['storyInfo'] else None self.storyTxt = self.root_dir/'gamedata/story/{}.txt'.format(storyData['storyTxt']) self.f = storyData['storyTxt'] From f6fd9f4cd2b46254a2db5bde555b358f93b0cbb9 Mon Sep 17 00:00:00 2001 From: Nightsky <050644zf@outlook.com> Date: Tue, 18 Feb 2025 11:13:39 +0800 Subject: [PATCH 4/4] Fix main_14 issue, add parser --- epub_convert.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/epub_convert.py b/epub_convert.py index 9c0efe9..a132bba 100644 --- a/epub_convert.py +++ b/epub_convert.py @@ -8,6 +8,8 @@ import func +import argparse + EPUB_CHAPTER_TEMPLATE = """ @@ -92,15 +94,19 @@ def parseHTML(story_json): return lines - + +parser = argparse.ArgumentParser() +parser.add_argument("event_id", help="Event ID") +parser.add_argument("-l", "--lang", help="Language", default="zh_CN") +args = parser.parse_args() -DATA_PATH = Path(r"D:\zf-py\ArknightsStoryJson") +DATA_PATH = Path(r"ArknightsStoryJson") -lang = "zh_CN" +lang = args.lang epub_lang = lang.replace("_", "-") -event_id = "act40side" +event_id = args.event_id event: Iterable[func.Story] = func.Event(DATA_PATH, lang, event_id) file_name = f"{event.eventid}_{event.name}.epub" @@ -113,6 +119,7 @@ def parseHTML(story_json): chapters = [] for idx, story in enumerate(event): + print(f"Processing {story.storyCode} {story.storyName} {story.avgTag}") chapter = epub.EpubHtml( title=f"{story.storyCode} {story.storyName} {story.avgTag}", file_name=f"{story.storyCode}_{story.storyName}_{story.avgTag}.xhtml", @@ -122,6 +129,8 @@ def parseHTML(story_json): story_json = json.load(f) lines = parseHTML(story_json) + if len(lines) == 0: + lines = ["

    Empty Chapter.

    "] chapter.content = EPUB_CHAPTER_TEMPLATE.format(story=story, lines="\n".join(lines)) with open(f'htmls/{chapter.file_name}', 'w', encoding='utf-8') as f: f.write(chapter.content)