├── .gitignore ├── README.md ├── pylanggetter ├── __init__.py ├── __main__.py ├── pylanggetter.py └── utils.py └── pyproject.toml /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode/ 2 | 3 | lang/ 4 | 5 | .mypy_cache 6 | 7 | __pycache__/ 8 | 9 | dist/ 10 | 11 | poetry.lock -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PyLangGetter 2 | Tiny utility to help you download Dofus Retro Lang files. 3 | 4 | # Installation 5 | `pip install pylanggetter` 6 | 7 | ## Usage 8 | `python -m pylanggetter` to get all lang files in **all language** and **all build** \ 9 | `python -m pylanggetter fr` to get lang files in **fr** language and **all build** \ 10 | `python -m pylanggetter it de` to get lang files in **it** and **de** langage and **all build** \ 11 | `python -m pylanggetter --prod` to get all lang files in **all language** and only **prod** build \ 12 | `python -m pylanggetter fr --temporis` to get lang files in **fr** language and **temporis** build \ 13 | `python -m pylanggetter it de --betaenv` to get lang files in **it** and **de** langage and **betaenv** build \ 14 | `python -m pylanggetter es pt --prod --temporis` to get lang files in **es** and **pt** langage and **prod** and **temporis** build 15 | 16 | Available language option : `fr, de, en, it, es, pt, nl` \ 17 | Available build option : `--prod, --betaenv, --temporis, --ephemeris2releasebucket, --t3mporis-release` 18 | 19 | #### Build description: 20 | - **prod**: official lang used on regular servers 21 | - **betaenv**: beta lang used on beta servers 22 | - **temporis**: temporis lang used on temporis servers 23 | - **ephemeris2releasebucket**: special temporis lang used on temporis servers 24 | - **t3mporis-release**: temporis lang used on temporis 3 servers 25 | -------------------------------------------------------------------------------- /pylanggetter/__init__.py: -------------------------------------------------------------------------------- 1 | from .pylanggetter import start 2 | -------------------------------------------------------------------------------- /pylanggetter/__main__.py: -------------------------------------------------------------------------------- 1 | from pylanggetter import start 2 | 3 | if __name__ == "__main__": 4 | start() 5 | -------------------------------------------------------------------------------- /pylanggetter/pylanggetter.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | 4 | from loguru import logger 5 | 6 | from pylanggetter.utils import Utils 7 | 8 | _BASE_URL: str = "http://dofusretro.cdn.ankama.com%s/lang/" 9 | _BASE_DIR: str = "data%s/lang/" 10 | 11 | 12 | def start(): 13 | lang_list = Utils.parse_args_langs(sys.argv) 14 | builds = Utils.parse_args_build(sys.argv) 15 | 16 | logger.info(f"Getting lang from this : {lang_list}") 17 | logger.info(f"Getting build from this : {builds}") 18 | 19 | for count_build, build in enumerate(builds, start=1): 20 | os.makedirs(_BASE_DIR % build + "swf/", exist_ok=True) 21 | versions_uri = _BASE_URL % build + "versions.swf" 22 | versions_dir = _BASE_DIR % build + "versions.swf" 23 | 24 | content = Utils.get_content_from_uri(versions_uri, False) 25 | Utils.write_content_to_file(versions_dir, content, True) 26 | 27 | for count_lang, lang in enumerate(lang_list, start=1): 28 | version_name = "versions_" + lang + ".txt" 29 | url_version = _BASE_URL % build + version_name 30 | dir_version = _BASE_DIR % build + version_name 31 | 32 | content = Utils.get_content_from_uri(url_version, True) 33 | Utils.write_content_to_file(dir_version, content, False) 34 | 35 | file_list = Utils.parse_version(dir_version) 36 | 37 | for count_file, file in enumerate(file_list, start=1): 38 | url_file = _BASE_URL % build + "swf/" + file 39 | dir_file = _BASE_DIR % build + "swf/" + file 40 | 41 | logger.info( 42 | f"[{count_build}/{len(builds)}][{count_lang}/{len(lang_list)}][{count_file:02d}/{len(file_list)}] \t === {file} - {build[1:] or 'default'}" 43 | ) 44 | content = Utils.get_content_from_uri(url_file, False) 45 | Utils.write_content_to_file(dir_file, content, True) 46 | 47 | logger.success("Done. All files are in the data folder.") 48 | -------------------------------------------------------------------------------- /pylanggetter/utils.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import urllib.request as urireq 4 | 5 | 6 | class Utils: 7 | DEFAULT_LANG: list = ["fr", "de", "en", "it", "es", "pt", "nl"] 8 | DEFAULT_BUILD: dict = { 9 | "prod": "", 10 | # "beta": "/beta", 11 | "betaenv": "/betaenv", 12 | "temporis": "/temporis", 13 | "ephemeris2releasebucket": "/ephemeris2releasebucket", 14 | "t3mporis-release": "/t3mporis-release", 15 | } 16 | 17 | @staticmethod 18 | def write_content_to_file(filename: str, content: str, isByte: bool) -> None: 19 | """Write content to the file filename 20 | 21 | Args: 22 | filename (str): the filename destination 23 | content (str): the content to write 24 | isByte (bool): true if the content is raw bytes, false otherwise 25 | """ 26 | mode = "wb" if isByte else "w" 27 | with open(filename, mode) as file: 28 | file.write(content) 29 | 30 | @staticmethod 31 | def get_content_from_uri(uri: str, decode: bool) -> str: 32 | """Get the content of a file from the uri 33 | 34 | Args: 35 | uri (str): the url of the file 36 | decode (bool): true if decode the content in utf-8, false otherwise 37 | 38 | Returns: 39 | str: the content of the file 40 | """ 41 | with urireq.urlopen(uri) as file: 42 | if decode: 43 | return file.read().decode("utf-8") 44 | return file.read() 45 | 46 | @staticmethod 47 | def parse_version(version_file: str) -> list: 48 | """Parse the given version file and return a list of the swf files 49 | 50 | Args: 51 | version_file (str): the version_*.txt to parse 52 | 53 | Returns: 54 | list: a list of swf file name 55 | """ 56 | with open(version_file, "r") as file: 57 | content = file.read() 58 | file_list = content.replace("&f=", "").replace(",", "_").split("|")[:-1] 59 | return [f"{name}.swf" for name in file_list] 60 | 61 | @staticmethod 62 | def parse_args_langs(args: list) -> list: 63 | """Parse the CLI args to determine the swf lang to get 64 | 65 | Args: 66 | args (list): the list of args to parse 67 | 68 | Raises: 69 | ValueError: When a lang arg is not available 70 | 71 | Returns: 72 | list: the list of the language lang to get 73 | """ 74 | args = args[1:] # ? remove the program name 75 | args = [arg for arg in args if not arg.startswith("--")] 76 | 77 | if len(args) < 1: 78 | return Utils.DEFAULT_LANG 79 | 80 | for arg in args: 81 | if arg not in Utils.DEFAULT_LANG: 82 | raise ValueError(f"Unknow lang {arg}, available lang : {Utils.DEFAULT_LANG}") 83 | return args 84 | 85 | @staticmethod 86 | def parse_args_build(args: list) -> list: 87 | """Parse the CLI args to determine swf the build to get 88 | 89 | Args: 90 | args (list): the list of args to parse 91 | 92 | Raises: 93 | ValueError: When a build arg is not available 94 | 95 | Returns: 96 | list: the build to get 97 | """ 98 | args = args[1:] # ? remove the program name 99 | args = [arg for arg in args if arg.startswith("--")] 100 | args = [arg.replace("--", "") for arg in args] 101 | 102 | if len(args) < 1: 103 | return list(Utils.DEFAULT_BUILD.values()) 104 | 105 | res: list = [] 106 | for arg in args: 107 | if arg not in Utils.DEFAULT_BUILD: 108 | raise ValueError(f"Unknow build {arg}, available build : {list(Utils.DEFAULT_BUILD.keys())}") 109 | res.append(Utils.DEFAULT_BUILD[arg]) 110 | 111 | return res 112 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "PylangGetter" 3 | version = "0.3.2" 4 | description = "Tiny utility to help you download Dofus Retro Lang files" 5 | authors = ["Dysta"] 6 | keywords = ["dofus retro", "dofus", "retro", "bot", "emulateur"] 7 | readme = "README.md" 8 | repository = "https://github.com/Dysta/PylangGetter" 9 | 10 | [tool.poetry.scripts] 11 | pylanggetter = "pylanggetter.pylanggetter:start" 12 | 13 | [tool.poetry.dependencies] 14 | python = ">=3.8" 15 | loguru = "^0.6.0" 16 | 17 | [tool.poetry.dev-dependencies] 18 | black = "^22.8.0" 19 | 20 | [tool.black] 21 | line-length = 120 22 | 23 | [build-system] 24 | requires = ["poetry-core>=1.0.0"] 25 | build-backend = "poetry.core.masonry.api" 26 | --------------------------------------------------------------------------------