From 86615ede929c54d259c9c51e6f3b32740024bed6 Mon Sep 17 00:00:00 2001 From: LmeSzinc <37934724+LmeSzinc@users.noreply.github.com> Date: Sat, 2 Oct 2021 04:11:59 +0800 Subject: [PATCH] Add: Auto updates to the latest event - Opt: Non-ascii characters in json - Fix: Template.json override --- config/template.json | 4 +- module/config/argument/args.json | 84 ++++++++++++++++++--- module/config/argument/argument.yaml | 4 +- module/config/config_generated.py | 2 +- module/config/config_updater.py | 108 +++++++++++++++++++++++++-- module/config/i18n/en-US.json | 39 +++++++++- module/config/i18n/zh-CN.json | 39 +++++++++- module/config/i18n/zh-TW.json | 39 +++++++++- module/config/utils.py | 29 +++---- 9 files changed, 309 insertions(+), 39 deletions(-) diff --git a/config/template.json b/config/template.json index 15959f2f0..119977657 100644 --- a/config/template.json +++ b/config/template.json @@ -13,7 +13,7 @@ "ScreenshotLength": 1 }, "Optimization": { - "CombatScreenshotInterval": 2 + "CombatScreenshotInterval": 1.0 }, "DropRecord": { "SaveFolder": "./screenshots", @@ -717,7 +717,7 @@ "PR3": "champagne" }, "MedalShop": { - "Filter": "DR > PRY\n> BookRedT3 > BookYellowT3 > BookBlueT3 > BookRedT2 > BookYellowT2 > BookBlueT2\n> RetrofitT3 > PlateGeneralT3\n> FoodT6 > FoodT5" + "Filter": "DRBP > PRYBP\n> BookRedT3 > BookYellowT3 > BookBlueT3 > BookRedT2 > BookYellowT2 > BookBlueT2\n> RetrofitT3 > PlateGeneralT3\n> FoodT6 > FoodT5" }, "MeritShop": { "Refresh": false, diff --git a/module/config/argument/args.json b/module/config/argument/args.json index 2ac5bb002..9e7d86c32 100644 --- a/module/config/argument/args.json +++ b/module/config/argument/args.json @@ -204,7 +204,10 @@ }, "Event": { "type": "disable", - "value": "campaign_main" + "value": "campaign_main", + "option": [ + "campaign_main" + ] }, "Mode": { "type": "select", @@ -527,8 +530,51 @@ "value": "7-2" }, "Event": { - "type": "input", - "value": "campaign_main" + "type": "select", + "value": "campaign_main", + "option": [ + "campaign_main", + "event_20200917_cn", + "event_20210916_cn", + "event_20210722_cn", + "event_20210819_cn", + "event_20200806_cn", + "event_20200723_cn", + "event_20200903_en", + "event_20210624_cn", + "event_20210624_tw", + "event_20210610_tw", + "event_20210527_cn", + "event_20210527_tw", + "event_20210429_tw", + "event_20210422_cn", + "event_20210415_tw", + "event_20210325_cn", + "event_20210225_tw", + "event_20210225_cn", + "event_20210121_cn", + "event_20201229_cn", + "event_20201126_cn", + "event_20201012_cn", + "event_20200312_cn", + "event_20201029_cn", + "event_20201002_en", + "event_20200820_cn", + "event_20200716_en", + "event_20200611_en", + "event_20200603_en", + "event_20200603_cn", + "event_20200521_en", + "event_20200521_cn", + "event_20200507_cn", + "event_20200423_cn", + "event_20200326_cn", + "event_20200227_cn" + ], + "tw": "event_20200917_cn", + "cn": "event_20210916_cn", + "en": "event_20210916_cn", + "jp": "event_20210916_cn" }, "Mode": { "type": "disable", @@ -1006,7 +1052,10 @@ }, "Event": { "type": "disable", - "value": "campaign_main" + "value": "campaign_main", + "option": [ + "campaign_main" + ] }, "Mode": { "type": "disable", @@ -1336,7 +1385,10 @@ }, "Event": { "type": "disable", - "value": "campaign_main" + "value": "campaign_main", + "option": [ + "campaign_main" + ] }, "Mode": { "type": "disable", @@ -1672,7 +1724,10 @@ }, "Event": { "type": "disable", - "value": "campaign_main" + "value": "campaign_main", + "option": [ + "campaign_main" + ] }, "Mode": { "type": "disable", @@ -2026,7 +2081,10 @@ }, "Event": { "type": "disable", - "value": "campaign_main" + "value": "campaign_main", + "option": [ + "campaign_main" + ] }, "Mode": { "type": "disable", @@ -2382,8 +2440,11 @@ "value": "7-2" }, "Event": { - "type": "input", - "value": "campaign_main" + "type": "select", + "value": "campaign_main", + "option": [ + "campaign_main" + ] }, "Mode": { "type": "disable", @@ -3508,7 +3569,10 @@ }, "Event": { "type": "disable", - "value": "campaign_main" + "value": "campaign_main", + "option": [ + "campaign_main" + ] }, "Mode": { "type": "disable", diff --git a/module/config/argument/argument.yaml b/module/config/argument/argument.yaml index 030cab36c..a152f065e 100644 --- a/module/config/argument/argument.yaml +++ b/module/config/argument/argument.yaml @@ -57,7 +57,9 @@ Retirement: Campaign: Name: 7-2 - Event: campaign_main + Event: + value: campaign_main + option: [campaign_main] Mode: value: normal option: [normal, hard] diff --git a/module/config/config_generated.py b/module/config/config_generated.py index bbe6f5e2d..2ba92679a 100644 --- a/module/config/config_generated.py +++ b/module/config/config_generated.py @@ -55,7 +55,7 @@ class GeneratedConfig: # Group `Campaign` Campaign_Name = '7-2' - Campaign_Event = 'campaign_main' + Campaign_Event = 'campaign_main' # campaign_main Campaign_Mode = 'normal' # normal, hard Campaign_UseClearMode = True Campaign_UseFleetLock = True diff --git a/module/config/config_updater.py b/module/config/config_updater.py index 0428a497a..3a64fcc00 100644 --- a/module/config/config_updater.py +++ b/module/config/config_updater.py @@ -1,3 +1,4 @@ +import re from copy import deepcopy from cached_property import cached_property @@ -18,6 +19,38 @@ class GeneratedConfig: Auto generated configuration """ '''.strip().split('\n') +ARCHIVES_PREFIX = { + 'cn': '档案_', + 'en': 'archives_', + 'jp': 'archives_', + 'tw': '檔案_' +} + + +class Event: + def __init__(self, text): + self.date, self.directory, self.name, self.cn, self.en, self.jp, self.tw \ + = [x.strip() for x in text.strip('| \n').split('|')] + + self.directory = self.directory.replace(' ', '_') + self.cn = self.cn.replace('、', '') + self.en = self.en.replace(',', '').replace('\'', '').replace('\\', '') + self.jp = self.jp.replace('、', '') + self.tw = self.tw.replace('、', '') + self.is_war_archives = self.directory.startswith('war_archives') + self.is_raid = self.directory.startswith('raid_') + for server in ARCHIVES_PREFIX.keys(): + if self.__getattribute__(server) == '-': + self.__setattr__(server, None) + else: + if self.is_war_archives: + self.__setattr__(server, ARCHIVES_PREFIX[server] + self.__getattribute__(server)) + + def __str__(self): + return self.directory + + def __eq__(self, other): + return str(self) == str(other) class ConfigGenerator: @@ -114,7 +147,6 @@ class ConfigGenerator: deep_set(data, keys=f'{task}.Scheduler.Command.value', value=task) deep_set(data, keys=f'{task}.Scheduler.Command.type', value='disable') - write_file(filepath_args(), data) return data @timer @@ -164,14 +196,14 @@ class ConfigGenerator: d = ".".join(k) if default else str(word) value = deep_get(old, keys=k, default=d) deep_set(new, keys=k, value=value) - + # Menu for path, data in deep_iter(self.menu, depth=2): func, group = path deep_load(['Menu', func]) deep_load(['Menu', group]) for task in data: deep_load([func, task]) - + # Arguments visited_group = set() for path, data in deep_iter(self.argument, depth=2): if path[0] not in visited_group: @@ -180,13 +212,20 @@ class ConfigGenerator: deep_load(path) if 'option' in data: deep_load(path, words=data['option'], default=False) + # Event names + for event in deep_get(self.args, keys=f'Event.Campaign.Event.option'): + if isinstance(event, Event): + name = event.__getattribute__(LANG_TO_SERVER[lang]) + if not name: + name = '-' + deep_set(new, keys=f'Campaign.Event.{event}', value=name) write_file(filepath_i18n(lang), new) @cached_property def menu(self): """ - Generate menu definations + Generate menu definitions task.yaml --> menu.json @@ -210,14 +249,61 @@ class ConfigGenerator: if tasks: deep_set(data, keys=f'Task.{group}', value=tasks) - # Write - write_file(filepath_args('menu'), data) return data + @cached_property + @timer + def event(self): + """ + Returns: + list[Event]: From latest to oldest + """ + events = [] + with open('./campaign/Readme.md', encoding='utf-8') as f: + for text in f.readlines(): + if re.search('\d{8}', text): + event = Event(text) + events.append(event) + + return events[::-1] + + def insert_event(self): + """ + Insert event information into `self.args`. + + ./campaign/Readme.md -----+ + v + args.json -----+-----> args.json + """ + for event in self.event: + for server_ in ARCHIVES_PREFIX.keys(): + name = event.__getattribute__(server_) + + def insert(key): + options = deep_get(self.args, keys=f'{key}.Campaign.Event.option') + if event not in options: + options.append(event) + if name: + deep_default(self.args, keys=f'{key}.Campaign.Event.{server_}', value=event) + + if name: + if event.is_raid: + # insert('Raid') + pass + elif event.is_war_archives: + # insert('WarArchives') + pass + else: + insert('Event') + @timer def generate(self): _ = self.args _ = self.menu + _ = self.event + self.insert_event() + write_file(filepath_args(), self.args) + write_file(filepath_args('menu'), self.menu) self.generate_code() for lang in LANGUAGES: self.generate_i18n(lang) @@ -240,11 +326,12 @@ class ConfigUpdater: """ new = {} old = read_file(filepath_config(config_name)) + is_template = config_name == 'template' def deep_load(keys): data = deep_get(self.args, keys=keys, default={}) value = deep_get(old, keys=keys, default=data['value']) - if value is None or data['type'] == 'disable': + if value is None or data['type'] == 'disable' or is_template: value = data['value'] value = parse_value(value, data=data) deep_set(new, keys=keys, value=value) @@ -252,10 +339,15 @@ class ConfigUpdater: for path, _ in deep_iter(self.args, depth=3): deep_load(path) - if config_name == 'template': + # AzurStatsID + if is_template: deep_set(new, 'Alas.DropRecord.AzurStatsID', None) else: deep_default(new, 'Alas.DropRecord.AzurStatsID', random_id()) + # Update to latest event + if not is_template: + server_ = deep_get(new, 'Alas.Emulator.Server', 'cn') + deep_set(new, keys='Event.Campaign.Event', value=deep_get(self.args, f'Event.Campaign.Event.{server_}')) return new diff --git a/module/config/i18n/en-US.json b/module/config/i18n/en-US.json index f7de22732..5c2ba7aea 100644 --- a/module/config/i18n/en-US.json +++ b/module/config/i18n/en-US.json @@ -337,7 +337,44 @@ }, "Event": { "name": "Campaign.Event.name", - "help": "Campaign.Event.help" + "help": "Campaign.Event.help", + "campaign_main": "campaign_main", + "event_20200917_cn": "-", + "event_20210916_cn": "Upon the Shimmering Blue", + "event_20210722_cn": "-", + "event_20210819_cn": "Microlayer Medley Rerun", + "event_20200806_cn": "-", + "event_20200723_cn": "-", + "event_20200903_en": "-", + "event_20210624_cn": "Swirling Cherry Blossoms Rerun", + "event_20210624_tw": "-", + "event_20210610_tw": "-", + "event_20210527_cn": "Mirror Involution", + "event_20210527_tw": "-", + "event_20210429_tw": "-", + "event_20210422_cn": "Daedalian Hymn", + "event_20210415_tw": "-", + "event_20210325_cn": "Ashen Simulacrum Rerun", + "event_20210225_tw": "-", + "event_20210225_cn": "Khorovod of Dawns Rime", + "event_20210121_cn": "Empyreal Tragicomedy Rerun", + "event_20201229_cn": "Inverted Orthant", + "event_20201126_cn": "Vacation Lane", + "event_20201012_cn": "Sundered Blue", + "event_20200312_cn": "-", + "event_20201029_cn": "Universe in Unison", + "event_20201002_en": "Counterattack Within the Fjord", + "event_20200820_cn": "Scherzo of Iron and Blood Rerun", + "event_20200716_en": "Ink Stained Steel Sakura Rerun", + "event_20200611_en": "Skybound Oratorio", + "event_20200603_en": "Prelude under the Moon Rerun", + "event_20200603_cn": "-", + "event_20200521_en": "Iris of Light and Dark Rerun", + "event_20200521_cn": "-", + "event_20200507_cn": "The Way Home in the Night", + "event_20200423_cn": "Crimson Echoes Rerun", + "event_20200326_cn": "Microlayer Medley", + "event_20200227_cn": "Northern Overture" }, "Mode": { "name": "Campaign.Mode.name", diff --git a/module/config/i18n/zh-CN.json b/module/config/i18n/zh-CN.json index f7de22732..28cdd680c 100644 --- a/module/config/i18n/zh-CN.json +++ b/module/config/i18n/zh-CN.json @@ -337,7 +337,44 @@ }, "Event": { "name": "Campaign.Event.name", - "help": "Campaign.Event.help" + "help": "Campaign.Event.help", + "campaign_main": "campaign_main", + "event_20200917_cn": "-", + "event_20210916_cn": "碧海光粼", + "event_20210722_cn": "-", + "event_20210819_cn": "复刻微层混合", + "event_20200806_cn": "-", + "event_20200723_cn": "-", + "event_20200903_en": "-", + "event_20210624_cn": "复刻浮樱影华", + "event_20210624_tw": "-", + "event_20210610_tw": "-", + "event_20210527_cn": "镜位螺旋", + "event_20210527_tw": "-", + "event_20210429_tw": "-", + "event_20210422_cn": "复兴的赞美诗", + "event_20210415_tw": "-", + "event_20210325_cn": "复刻箱庭疗法", + "event_20210225_tw": "-", + "event_20210225_cn": "破晓冰华", + "event_20210121_cn": "复刻神圣的悲喜剧", + "event_20201229_cn": "负象限作战", + "event_20201126_cn": "假日航线", + "event_20201012_cn": "-", + "event_20200312_cn": "-", + "event_20201029_cn": "激唱的UNIVERSE", + "event_20201002_en": "-", + "event_20200820_cn": "复刻铁血音符誓言", + "event_20200716_en": "-", + "event_20200611_en": "-", + "event_20200603_en": "-", + "event_20200603_cn": "峡湾间的反击", + "event_20200521_en": "-", + "event_20200521_cn": "穹顶下的圣咏曲", + "event_20200507_cn": "夜幕下的归途", + "event_20200423_cn": "复刻苍红的回响", + "event_20200326_cn": "微层混合", + "event_20200227_cn": "北境序曲" }, "Mode": { "name": "Campaign.Mode.name", diff --git a/module/config/i18n/zh-TW.json b/module/config/i18n/zh-TW.json index f7de22732..6e5ba2e11 100644 --- a/module/config/i18n/zh-TW.json +++ b/module/config/i18n/zh-TW.json @@ -337,7 +337,44 @@ }, "Event": { "name": "Campaign.Event.name", - "help": "Campaign.Event.help" + "help": "Campaign.Event.help", + "campaign_main": "campaign_main", + "event_20200917_cn": "蝶海夢花", + "event_20210916_cn": "-", + "event_20210722_cn": "響徹碧海的偶像歌", + "event_20210819_cn": "-", + "event_20200806_cn": "最重要的寶物", + "event_20200723_cn": "永夜幻光", + "event_20200903_en": "峽灣間的星辰", + "event_20210624_cn": "-", + "event_20210624_tw": "穹頂下的聖詠曲", + "event_20210610_tw": "夜幕下的歸途", + "event_20210527_cn": "-", + "event_20210527_tw": "微層混合", + "event_20210429_tw": "復刻墨染的鋼鐵之花", + "event_20210422_cn": "-", + "event_20210415_tw": "復刻圍剿施佩伯爵", + "event_20210325_cn": "-", + "event_20210225_tw": "北境序曲", + "event_20210225_cn": "-", + "event_20210121_cn": "-", + "event_20201229_cn": "-", + "event_20201126_cn": "-", + "event_20201012_cn": "-", + "event_20200312_cn": "斯圖爾特的硝煙", + "event_20201029_cn": "-", + "event_20201002_en": "-", + "event_20200820_cn": "-", + "event_20200716_en": "-", + "event_20200611_en": "-", + "event_20200603_en": "-", + "event_20200603_cn": "-", + "event_20200521_en": "-", + "event_20200521_cn": "-", + "event_20200507_cn": "-", + "event_20200423_cn": "-", + "event_20200326_cn": "-", + "event_20200227_cn": "-" }, "Mode": { "name": "Campaign.Mode.name", diff --git a/module/config/utils.py b/module/config/utils.py index 411a4ff1c..7125f9b2e 100644 --- a/module/config/utils.py +++ b/module/config/utils.py @@ -9,9 +9,19 @@ import yaml import module.config.server as server LANGUAGES = ['zh-CN', 'en-US', 'zh-TW'] - - -# LANGUAGES = ['zh-CN'] +SERVER_TO_LANG = { + 'cn': 'zh-CN', + 'en': 'en-US', + 'jp': 'ja-JP', + 'tw': 'zh-TW', +} +LANG_TO_SERVER = {v: k for k, v in SERVER_TO_LANG.items()} +SERVER_TO_TIMEZONE = { + 'cn': 8, + 'en': -7, + 'jp': 9, + 'tw': 8, +} # https://stackoverflow.com/questions/8640959/how-can-i-control-what-scalar-form-pyyaml-uses-for-my-data/15423007 @@ -105,7 +115,7 @@ def write_file(file, data): sort_keys=False) elif ext == '.json': with open(file, mode='w', encoding='utf-8') as f: - s = json.dumps(data, indent=2, ensure_ascii=True, sort_keys=False, default=str) + s = json.dumps(data, indent=2, ensure_ascii=False, sort_keys=False, default=str) f.write(s) else: print(f'Unsupported config file extension: {ext}') @@ -311,16 +321,7 @@ def dict_to_kv(dictionary, allow_none=True): def server_timezone(): - if server.server == 'en': - return -7 - elif server.server == 'cn': - return 8 - elif server.server == 'jp': - return 9 - elif server.server == 'tw': - return 8 - else: - return 8 + return SERVER_TO_TIMEZONE.get(server.server, 8) def get_server_next_update(daily_trigger):