avwx.current.base
Current report shared resources
1""" 2Current report shared resources 3""" 4 5# pylint: disable=abstract-method,arguments-renamed 6 7# stdlib 8import asyncio as aio 9from datetime import date 10from typing import List, Optional, Tuple, Union 11 12# module 13from avwx.base import ManagedReport 14from avwx.service import get_service 15from avwx.static.core import WX_TRANSLATIONS 16from avwx.structs import Code, Coord, ReportData, ReportTrans, Sanitization, Units 17 18 19def wx_code(code: str) -> Union[Code, str]: 20 """ 21 Translates weather codes into readable strings 22 23 Returns translated string of variable length 24 """ 25 if not code: 26 return "" 27 ret, code_copy = "", code 28 if code[0] == "+": 29 ret = "Heavy " 30 code = code[1:] 31 elif code[0] == "-": 32 ret = "Light " 33 code = code[1:] 34 # Return code if code is not a code, ex R03/03002V03 35 if len(code) not in [2, 4, 6] or code.isdigit(): 36 return code 37 is_code = False 38 while code: 39 try: 40 ret += f"{WX_TRANSLATIONS[code[:2]]} " 41 is_code = True 42 except KeyError: 43 ret += code[:2] 44 code = code[2:] 45 # Return Code if any part was able to be translated 46 return Code(code_copy, ret.strip()) if is_code else code_copy 47 48 49def get_wx_codes(codes: List[str]) -> Tuple[List[str], List[Code]]: 50 """ 51 Separates parsed WX codes 52 """ 53 other: List[str] = [] 54 ret: List[Code] = [] 55 for item in codes: 56 code = wx_code(item) 57 if isinstance(code, Code): 58 ret.append(code) 59 else: 60 other.append(code) 61 return other, ret 62 63 64class Report(ManagedReport): 65 """ 66 Base report to take care of service assignment and station info 67 """ 68 69 #: ReportTrans dataclass of translation strings from data. Parsed on update() 70 translations: Optional[ReportTrans] = None 71 72 sanitization: Optional[Sanitization] = None 73 74 def __init__(self, code: str): 75 """Add doc string to show constructor""" 76 super().__init__(code) 77 if self.station is not None: 78 service = get_service(code, self.station.country) 79 self.service = service(self.__class__.__name__.lower()) # type: ignore 80 81 82class Reports(ManagedReport): 83 """ 84 Base class containing multiple reports 85 """ 86 87 coord: Optional[Coord] = None 88 raw: Optional[List[str]] = None # type: ignore 89 data: Optional[List[ReportData]] = None # type: ignore 90 units: Units = Units.north_american() 91 sanitization: Optional[List[Sanitization]] = None 92 93 def __init__(self, code: Optional[str] = None, coord: Optional[Coord] = None): 94 if code: 95 super().__init__(code) 96 if self.station is not None: 97 coord = self.station.coord 98 elif coord is None: 99 raise ValueError("No station or coordinate given") 100 self.coord = coord 101 102 def __repr__(self) -> str: 103 if self.code: 104 return f"<avwx.{self.__class__.__name__} code={self.code}>" 105 return f"<avwx.{self.__class__.__name__} coord={self.coord}>" 106 107 @staticmethod 108 def _report_filter(reports: List[str]) -> List[str]: 109 """Applies any report filtering before updating raw_reports""" 110 return reports 111 112 async def _update( # type: ignore 113 self, reports: List[str], issued: Optional[date], disable_post: bool 114 ) -> bool: 115 if not reports: 116 return False 117 reports = self._report_filter(reports) 118 return await super()._update(reports, issued, disable_post) 119 120 def parse( 121 self, reports: Union[str, List[str]], issued: Optional[date] = None 122 ) -> bool: 123 """Updates report data by parsing a given report 124 125 Can accept a report issue date if not a recent report string 126 """ 127 return aio.run(self.async_parse(reports, issued)) 128 129 async def async_parse( 130 self, reports: Union[str, List[str]], issued: Optional[date] = None 131 ) -> bool: 132 """Async updates report data by parsing a given report 133 134 Can accept a report issue date if not a recent report string 135 """ 136 self.source = None 137 if isinstance(reports, str): 138 reports = [reports] 139 return await self._update(reports, issued, False) 140 141 def update(self, timeout: int = 10, disable_post: bool = False) -> bool: 142 """Updates report data by fetching and parsing the report 143 144 Returns True if new reports are available, else False 145 """ 146 return aio.run(self.async_update(timeout, disable_post)) 147 148 async def async_update(self, timeout: int = 10, disable_post: bool = False) -> bool: 149 """Async updates report data by fetching and parsing the report""" 150 reports = await self.service.async_fetch(coord=self.coord, timeout=timeout) # type: ignore 151 self.source = self.service.root 152 return await self._update(reports, None, disable_post)
20def wx_code(code: str) -> Union[Code, str]: 21 """ 22 Translates weather codes into readable strings 23 24 Returns translated string of variable length 25 """ 26 if not code: 27 return "" 28 ret, code_copy = "", code 29 if code[0] == "+": 30 ret = "Heavy " 31 code = code[1:] 32 elif code[0] == "-": 33 ret = "Light " 34 code = code[1:] 35 # Return code if code is not a code, ex R03/03002V03 36 if len(code) not in [2, 4, 6] or code.isdigit(): 37 return code 38 is_code = False 39 while code: 40 try: 41 ret += f"{WX_TRANSLATIONS[code[:2]]} " 42 is_code = True 43 except KeyError: 44 ret += code[:2] 45 code = code[2:] 46 # Return Code if any part was able to be translated 47 return Code(code_copy, ret.strip()) if is_code else code_copy
Translates weather codes into readable strings
Returns translated string of variable length
50def get_wx_codes(codes: List[str]) -> Tuple[List[str], List[Code]]: 51 """ 52 Separates parsed WX codes 53 """ 54 other: List[str] = [] 55 ret: List[Code] = [] 56 for item in codes: 57 code = wx_code(item) 58 if isinstance(code, Code): 59 ret.append(code) 60 else: 61 other.append(code) 62 return other, ret
Separates parsed WX codes
65class Report(ManagedReport): 66 """ 67 Base report to take care of service assignment and station info 68 """ 69 70 #: ReportTrans dataclass of translation strings from data. Parsed on update() 71 translations: Optional[ReportTrans] = None 72 73 sanitization: Optional[Sanitization] = None 74 75 def __init__(self, code: str): 76 """Add doc string to show constructor""" 77 super().__init__(code) 78 if self.station is not None: 79 service = get_service(code, self.station.country) 80 self.service = service(self.__class__.__name__.lower()) # type: ignore
Base report to take care of service assignment and station info
Report(code: str)
75 def __init__(self, code: str): 76 """Add doc string to show constructor""" 77 super().__init__(code) 78 if self.station is not None: 79 service = get_service(code, self.station.country) 80 self.service = service(self.__class__.__name__.lower()) # type: ignore
Add doc string to show constructor
83class Reports(ManagedReport): 84 """ 85 Base class containing multiple reports 86 """ 87 88 coord: Optional[Coord] = None 89 raw: Optional[List[str]] = None # type: ignore 90 data: Optional[List[ReportData]] = None # type: ignore 91 units: Units = Units.north_american() 92 sanitization: Optional[List[Sanitization]] = None 93 94 def __init__(self, code: Optional[str] = None, coord: Optional[Coord] = None): 95 if code: 96 super().__init__(code) 97 if self.station is not None: 98 coord = self.station.coord 99 elif coord is None: 100 raise ValueError("No station or coordinate given") 101 self.coord = coord 102 103 def __repr__(self) -> str: 104 if self.code: 105 return f"<avwx.{self.__class__.__name__} code={self.code}>" 106 return f"<avwx.{self.__class__.__name__} coord={self.coord}>" 107 108 @staticmethod 109 def _report_filter(reports: List[str]) -> List[str]: 110 """Applies any report filtering before updating raw_reports""" 111 return reports 112 113 async def _update( # type: ignore 114 self, reports: List[str], issued: Optional[date], disable_post: bool 115 ) -> bool: 116 if not reports: 117 return False 118 reports = self._report_filter(reports) 119 return await super()._update(reports, issued, disable_post) 120 121 def parse( 122 self, reports: Union[str, List[str]], issued: Optional[date] = None 123 ) -> bool: 124 """Updates report data by parsing a given report 125 126 Can accept a report issue date if not a recent report string 127 """ 128 return aio.run(self.async_parse(reports, issued)) 129 130 async def async_parse( 131 self, reports: Union[str, List[str]], issued: Optional[date] = None 132 ) -> bool: 133 """Async updates report data by parsing a given report 134 135 Can accept a report issue date if not a recent report string 136 """ 137 self.source = None 138 if isinstance(reports, str): 139 reports = [reports] 140 return await self._update(reports, issued, False) 141 142 def update(self, timeout: int = 10, disable_post: bool = False) -> bool: 143 """Updates report data by fetching and parsing the report 144 145 Returns True if new reports are available, else False 146 """ 147 return aio.run(self.async_update(timeout, disable_post)) 148 149 async def async_update(self, timeout: int = 10, disable_post: bool = False) -> bool: 150 """Async updates report data by fetching and parsing the report""" 151 reports = await self.service.async_fetch(coord=self.coord, timeout=timeout) # type: ignore 152 self.source = self.service.root 153 return await self._update(reports, None, disable_post)
Base class containing multiple reports
units: avwx.structs.Units =
Units(accumulation='in', altimeter='inHg', altitude='ft', temperature='C', visibility='sm', wind_speed='kt')
def
parse( self, reports: Union[str, List[str]], issued: Optional[datetime.date] = None) -> bool:
121 def parse( 122 self, reports: Union[str, List[str]], issued: Optional[date] = None 123 ) -> bool: 124 """Updates report data by parsing a given report 125 126 Can accept a report issue date if not a recent report string 127 """ 128 return aio.run(self.async_parse(reports, issued))
Updates report data by parsing a given report
Can accept a report issue date if not a recent report string
async def
async_parse( self, reports: Union[str, List[str]], issued: Optional[datetime.date] = None) -> bool:
130 async def async_parse( 131 self, reports: Union[str, List[str]], issued: Optional[date] = None 132 ) -> bool: 133 """Async updates report data by parsing a given report 134 135 Can accept a report issue date if not a recent report string 136 """ 137 self.source = None 138 if isinstance(reports, str): 139 reports = [reports] 140 return await self._update(reports, issued, False)
Async updates report data by parsing a given report
Can accept a report issue date if not a recent report string
def
update(self, timeout: int = 10, disable_post: bool = False) -> bool:
142 def update(self, timeout: int = 10, disable_post: bool = False) -> bool: 143 """Updates report data by fetching and parsing the report 144 145 Returns True if new reports are available, else False 146 """ 147 return aio.run(self.async_update(timeout, disable_post))
Updates report data by fetching and parsing the report
Returns True if new reports are available, else False
async def
async_update(self, timeout: int = 10, disable_post: bool = False) -> bool:
149 async def async_update(self, timeout: int = 10, disable_post: bool = False) -> bool: 150 """Async updates report data by fetching and parsing the report""" 151 reports = await self.service.async_fetch(coord=self.coord, timeout=timeout) # type: ignore 152 self.source = self.service.root 153 return await self._update(reports, None, disable_post)
Async updates report data by fetching and parsing the report