modm_data.dl.stmicro.document
1# Copyright 2022, Niklas Hauser 2# SPDX-License-Identifier: MPL-2.0 3 4import json 5import logging 6from pathlib import Path 7from functools import cached_property 8from ..store import download_file, download_data 9from ...utils import ext_path 10 11LOGGER = logging.getLogger(__name__) 12 13 14class Document: 15 """ 16 Smaller helper class to store all relevant information about a remote 17 STMicro PDF document and how to download it. 18 """ 19 20 def __init__(self, data): 21 # Primary information from JSON data 22 self._title = data["title"] 23 self._description = data["localizedDescriptions"]["en"] 24 self._url = data["localizedLinks"]["en"] 25 self._version = data["version"] 26 self._update = data["latestUpdate"] 27 self._type = data.get("resourceType", "Unknown") 28 29 # Derived information 30 self._short_type = self._title[:2] 31 clean_version = self._version.replace(".0", "").replace(".", "_") 32 self.name = self._title + "-v" + clean_version 33 """The full name of the document including version.""" 34 self.filename = self.name + ".pdf" 35 """The leaf filename of the document.""" 36 self.url = "https://www.st.com" + self._url 37 """The full URL that the file was downloaded from.""" 38 39 @property 40 def data(self) -> dict: 41 """ 42 A dictionary uniquely identifying this document version in a similar 43 format to the one used by the STMicro homepage. This can be used to 44 keep track of which documents have already been downloaded and which 45 have been updated upstream. 46 """ 47 return { 48 "title": self._title, 49 "localizedDescriptions": {"en": self._description}, 50 "localizedLinks": {"en": self._url}, 51 "version": self._version, 52 "latestUpdate": self._update, 53 "resourceType": self._type, 54 } 55 56 def store_pdf(self, path: str, overwrite: bool = False) -> bool: 57 """Download the PDF file to the path, optionally overwriting it.""" 58 return download_file(self.url, path, overwrite=overwrite) 59 60 def __repr__(self) -> str: 61 return f"Doc({self._title} v{self._version.replace('.0', '')})" 62 63 def __eq__(self, other) -> bool: 64 if not isinstance(other, type(self)): 65 return False 66 return self.filename == other.filename 67 68 def __hash__(self) -> int: 69 return hash(self.filename) 70 71 72_json_short_urls = { 73 # Technical docs for STM32 microcontrollers 74 "stm32": [ 75 "CL1734", 76 "SC2154", 77 "SC2155", 78 "SC2157", 79 "SC2156", 80 ], 81 # Technical docs for STM32 development boards 82 "boards": [ 83 "LN1847", 84 "LN1848", 85 "LN1199", 86 ], 87 # Technical docs for STMicro sensors 88 "sensors": [ 89 "SC444", 90 #SC1946", 91 "SC1449", 92 "SC1288", 93 #SC1718", 94 "SC1448", 95 "SC1922", 96 "SC1316", 97 "SC294", 98 ], 99 # Technical docs for STMicro data converters 100 "converters": [ 101 "SC47", 102 "SC2514", 103 "SC397", 104 ], 105 # Technical docs for STMicro hardware debug tools 106 "debug": [ 107 "SC2330" 108 ] 109} 110_json_url_prefix = "https://www.st.com/bin/st/selectors/cxst/en.cxst-rs-grid.html/" 111_json_url_suffix = ".technical_literature.json" 112 113_json_urls = {key: [_json_url_prefix + url + _json_url_suffix for url in urls] 114 for key, urls in _json_short_urls.items()} 115_remote_info = "remote.json" 116_local_info = "local.json" 117 118 119def load_remote_info(base_dir: Path, use_cached: bool = False) -> list[dict]: 120 info = base_dir / _remote_info 121 if use_cached and info.exists(): 122 LOGGER.debug(f"Loading remote info from cache") 123 docs = json.loads(info.read_text()) 124 else: 125 LOGGER.info(f"Downloading remote info") 126 docs = [] 127 for urls in _json_urls.values(): 128 for url in urls: 129 docs.extend(json.loads(download_data(url))["rows"]) 130 return docs 131 132 133def store_remote_info(base_dir: Path, docs: list[dict]): 134 info = base_dir / _remote_info 135 info.parent.mkdir(parents=True, exist_ok=True) 136 info.write_text(json.dumps(sorted(docs, 137 key=lambda d: (d["title"], d["version"])), indent=4, sort_keys=True)) 138 139 140def load_local_info(base_dir: Path) -> list[dict]: 141 info = base_dir / _local_info 142 if info.exists(): 143 LOGGER.debug(f"Loading local info from cache") 144 return json.loads(info.read_text()) 145 return [] 146 147 148def store_local_info(base_dir: Path, docs: list[dict]): 149 info = base_dir / _local_info 150 info.parent.mkdir(parents=True, exist_ok=True) 151 info.write_text(json.dumps(sorted(docs, 152 key=lambda d: (d["title"], d["version"])), indent=4, sort_keys=True)) 153 154 155def sync_info(base_dir: Path, use_cached: bool = False) -> set[Document]: 156 remote_docs = set(map(Document, load_remote_info(base_dir, use_cached))) 157 local_docs = set(map(Document, load_local_info(base_dir))) 158 return remote_docs - local_docs
LOGGER =
<Logger modm_data.dl.stmicro.document (WARNING)>
class
Document:
15class Document: 16 """ 17 Smaller helper class to store all relevant information about a remote 18 STMicro PDF document and how to download it. 19 """ 20 21 def __init__(self, data): 22 # Primary information from JSON data 23 self._title = data["title"] 24 self._description = data["localizedDescriptions"]["en"] 25 self._url = data["localizedLinks"]["en"] 26 self._version = data["version"] 27 self._update = data["latestUpdate"] 28 self._type = data.get("resourceType", "Unknown") 29 30 # Derived information 31 self._short_type = self._title[:2] 32 clean_version = self._version.replace(".0", "").replace(".", "_") 33 self.name = self._title + "-v" + clean_version 34 """The full name of the document including version.""" 35 self.filename = self.name + ".pdf" 36 """The leaf filename of the document.""" 37 self.url = "https://www.st.com" + self._url 38 """The full URL that the file was downloaded from.""" 39 40 @property 41 def data(self) -> dict: 42 """ 43 A dictionary uniquely identifying this document version in a similar 44 format to the one used by the STMicro homepage. This can be used to 45 keep track of which documents have already been downloaded and which 46 have been updated upstream. 47 """ 48 return { 49 "title": self._title, 50 "localizedDescriptions": {"en": self._description}, 51 "localizedLinks": {"en": self._url}, 52 "version": self._version, 53 "latestUpdate": self._update, 54 "resourceType": self._type, 55 } 56 57 def store_pdf(self, path: str, overwrite: bool = False) -> bool: 58 """Download the PDF file to the path, optionally overwriting it.""" 59 return download_file(self.url, path, overwrite=overwrite) 60 61 def __repr__(self) -> str: 62 return f"Doc({self._title} v{self._version.replace('.0', '')})" 63 64 def __eq__(self, other) -> bool: 65 if not isinstance(other, type(self)): 66 return False 67 return self.filename == other.filename 68 69 def __hash__(self) -> int: 70 return hash(self.filename)
Smaller helper class to store all relevant information about a remote STMicro PDF document and how to download it.
Document(data)
21 def __init__(self, data): 22 # Primary information from JSON data 23 self._title = data["title"] 24 self._description = data["localizedDescriptions"]["en"] 25 self._url = data["localizedLinks"]["en"] 26 self._version = data["version"] 27 self._update = data["latestUpdate"] 28 self._type = data.get("resourceType", "Unknown") 29 30 # Derived information 31 self._short_type = self._title[:2] 32 clean_version = self._version.replace(".0", "").replace(".", "_") 33 self.name = self._title + "-v" + clean_version 34 """The full name of the document including version.""" 35 self.filename = self.name + ".pdf" 36 """The leaf filename of the document.""" 37 self.url = "https://www.st.com" + self._url 38 """The full URL that the file was downloaded from."""
data: dict
40 @property 41 def data(self) -> dict: 42 """ 43 A dictionary uniquely identifying this document version in a similar 44 format to the one used by the STMicro homepage. This can be used to 45 keep track of which documents have already been downloaded and which 46 have been updated upstream. 47 """ 48 return { 49 "title": self._title, 50 "localizedDescriptions": {"en": self._description}, 51 "localizedLinks": {"en": self._url}, 52 "version": self._version, 53 "latestUpdate": self._update, 54 "resourceType": self._type, 55 }
A dictionary uniquely identifying this document version in a similar format to the one used by the STMicro homepage. This can be used to keep track of which documents have already been downloaded and which have been updated upstream.
def
store_pdf(self, path: str, overwrite: bool = False) -> bool:
57 def store_pdf(self, path: str, overwrite: bool = False) -> bool: 58 """Download the PDF file to the path, optionally overwriting it.""" 59 return download_file(self.url, path, overwrite=overwrite)
Download the PDF file to the path, optionally overwriting it.
def
load_remote_info(base_dir: pathlib.Path, use_cached: bool = False) -> list[dict]:
120def load_remote_info(base_dir: Path, use_cached: bool = False) -> list[dict]: 121 info = base_dir / _remote_info 122 if use_cached and info.exists(): 123 LOGGER.debug(f"Loading remote info from cache") 124 docs = json.loads(info.read_text()) 125 else: 126 LOGGER.info(f"Downloading remote info") 127 docs = [] 128 for urls in _json_urls.values(): 129 for url in urls: 130 docs.extend(json.loads(download_data(url))["rows"]) 131 return docs
def
store_remote_info(base_dir: pathlib.Path, docs: list[dict]):
def
load_local_info(base_dir: pathlib.Path) -> list[dict]:
def
store_local_info(base_dir: pathlib.Path, docs: list[dict]):