Source code for wow_sdm.exp03_wotlk.mapping

# -*- coding: utf-8 -*-

"""
这个模块的可以让你对 Account / Character 和宏命令 Yaml 文件进行排列组合, 然后一键将你的
配置文件应用到你的客户端中的 WTF 目录下.
"""

import typing as T
import dataclasses
from pathlib_mate import Path

from wow_acc.api import Account, Character

from ..logger import logger

from .model import SdmMacro, SdmLua


[docs]@dataclasses.dataclass class Client: r""" 代表着一个具体魔兽世界客户端. 你必须要指定这个客户端的目录. 然后就可以用各种 method 来 获取对应的 SDM 插件 lua 文件的绝对路径了. :param dir: 客户端目录, 根据此目录可以定位其他的目录. 例如 "C:\Program Files\World of Warcraft" :param locale: 客户端语种, 例如 enUS, zhCN, zhTW 等. """ dir: Path = dataclasses.field() locale: str = dataclasses.field() @property def dir_wtf(self) -> Path: return self.dir / "WTF"
[docs] def get_account_sdm_lua( self, wtf_account_name: str, ) -> Path: r""" This file stores account level SDM AddOn configuration. Example: ``C:\...\WTF\Account\MYACCOUNT\SavedVariables\SuperDuperMacro.lua`` """ return self.dir_wtf.joinpath( "Account", wtf_account_name, "SavedVariables", "SuperDuperMacro.lua", )
[docs]@dataclasses.dataclass class BaseMapping: """ Mapping 是一个 Account / Character 和一个 Macro 文件的组合. """ file: Path = dataclasses.field()
[docs]@dataclasses.dataclass class AccLvlMapping(BaseMapping): """ ``Account`` 和一个 Macro 文件的组合. :param acc: `wow_acc.api.Account <https://wow-acc.readthedocs.io/en/latest/wow_acc/model.html#wow_acc.model.Account>`_ 对象. :param file: Macro 文件的绝对路径. """ acc: Account = dataclasses.field() file: Path = dataclasses.field()
[docs] @classmethod def make_many( cls, account: T.Union[Account, T.Iterable[Account]], file: T.Union[Path, T.Iterable[Path]], ): """ 生成多个 ``Account`` 和 Macro 文件的组合. 让你写更少的代码. :param account: 单个 Account 或是多个 Account 的集合. :param file: 单个 Path 或是多个 Path 的集合. """ if isinstance(account, Account): # pragma: no cover accounts = [account] else: # pragma: no cover accounts = account if isinstance(file, Path): # pragma: no cover files = [file] else: files = file lst = list() for account in accounts: for file in files: lst.append(cls(acc=account, file=file)) return lst
[docs]@dataclasses.dataclass class CharLvlMapping(BaseMapping): """ ``Character`` 和一个 Macro 文件的组合. :param char: `wow_acc.api.Character <https://wow-acc.readthedocs.io/en/latest/wow_acc/model.html#wow_acc.model.Character>`_ 对象. :param file: Macro 文件的绝对路径. """ char: Character = dataclasses.field() file: Path = dataclasses.field()
[docs] @classmethod def make_many( cls, character: T.Union[Character, T.Iterable[Character]], file: T.Union[Path, T.List[Path]], ): """ 生成多个 ``Character`` 和 Macro 文件的组合. 让你写更少的代码. :param character: 单个 Character 或是多个 Character 的集合. :param file: 单个 Path 或是多个 Path 的集合. """ if isinstance(character, Character): # pragma: no cover characters = [character] else: # pragma: no cover characters = character if isinstance(file, Path): # pragma: no cover files = [file] else: files = file lst = list() for character in characters: for file in files: lst.append(cls(char=character, file=file)) return lst
[docs]@dataclasses.dataclass class SdmMapping: """ 定义了一个魔兽世界客户端中被管理的所有 Sdm 宏命令的设定. :param client: :class:`Client` 对象. 有了这个才知道我们要将配置文件写到哪里去. :param all_accounts: 所有的 `wow_acc.api.Account <https://wow-acc.readthedocs.io/en/latest/wow_acc/model.html#wow_acc.model.Account>`_ 对象. 在 render Jinja 模板时会用到. :param all_characters: 所有的 `wow_acc.api.Character <https://wow-acc.readthedocs.io/en/latest/wow_acc/model.html#wow_acc.model.Character>`_ 对象. 在 render Jinja 模板时会用到. """ # fmt: off client: Client all_accounts: T.Iterable[Account] all_characters: T.Iterable[Character] acc_macros: T.List[AccLvlMapping] = dataclasses.field(default_factory=list) char_macros: T.List[CharLvlMapping] = dataclasses.field(default_factory=list) # fmt: on
[docs] @logger.emoji_block(msg="{func_name}", emoji="🎮") def apply(self, real_run: bool = False): """ 将 SDM 的 Lua 文件写入 ``SavedVariables`` 文件夹中. """ # mapper 是一个以 account 为 key 的分组器 mapper: T.Dict[str, T.List[SdmMacro]] = dict() for acc_map in self.acc_macros: macro = SdmMacro.from_yaml(acc_map.file) try: mapper[acc_map.acc.wtf_account_name].append(macro) except KeyError: mapper[acc_map.acc.wtf_account_name] = [macro] for char_map in self.char_macros: macro = SdmMacro.from_yaml(char_map.file) # 将其设定为 character macro macro.set_char(name=char_map.char.titled_character_name, realm=char_map.char.realm_name) try: mapper[char_map.char.account.wtf_account_name].append(macro) except KeyError: # pragma: no cover mapper[char_map.char.account.wtf_account_name] = [macro] for wtf_account_name, macros in mapper.items(): path_lua = self.client.get_account_sdm_lua(wtf_account_name) sdm_lua = SdmLua( path_lua=path_lua, macros=macros, ) sdm_lua.write(real_run=real_run, verbose=True)