| 
						
						
							
								
							
						
						
					 | 
					 | 
					@ -9,12 +9,14 @@ from urllib3.util import Timeout | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					from openpilot.common.file_helpers import atomic_write_in_dir | 
					 | 
					 | 
					 | 
					from openpilot.common.file_helpers import atomic_write_in_dir | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					from openpilot.system.hardware.hw import Paths | 
					 | 
					 | 
					 | 
					from openpilot.system.hardware.hw import Paths | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					#  Cache chunk size | 
					 | 
					 | 
					 | 
					#  Cache chunk size | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					K = 1000 | 
					 | 
					 | 
					 | 
					K = 1000 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					CHUNK_SIZE = 1000 * K | 
					 | 
					 | 
					 | 
					CHUNK_SIZE = 1000 * K | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					logging.getLogger("urllib3").setLevel(logging.WARNING) | 
					 | 
					 | 
					 | 
					logging.getLogger("urllib3").setLevel(logging.WARNING) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					def hash_256(link: str) -> str: | 
					 | 
					 | 
					 | 
					def hash_256(link: str) -> str: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  return sha256((link.split("?")[0]).encode('utf-8')).hexdigest() | 
					 | 
					 | 
					 | 
					  return sha256((link.split("?")[0]).encode('utf-8')).hexdigest() | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -24,7 +26,7 @@ class URLFileException(Exception): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					class URLFile: | 
					 | 
					 | 
					 | 
					class URLFile: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  _pool_manager: PoolManager|None = None | 
					 | 
					 | 
					 | 
					  _pool_manager: PoolManager | None = None | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  @staticmethod | 
					 | 
					 | 
					 | 
					  @staticmethod | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  def reset() -> None: | 
					 | 
					 | 
					 | 
					  def reset() -> None: | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -33,16 +35,16 @@ class URLFile: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  @staticmethod | 
					 | 
					 | 
					 | 
					  @staticmethod | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  def pool_manager() -> PoolManager: | 
					 | 
					 | 
					 | 
					  def pool_manager() -> PoolManager: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if URLFile._pool_manager is None: | 
					 | 
					 | 
					 | 
					    if URLFile._pool_manager is None: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      socket_options = [(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1),] | 
					 | 
					 | 
					 | 
					      socket_options = [(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)] | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      retries = Retry(total=5, backoff_factor=0.5, status_forcelist=[409, 429, 503, 504]) | 
					 | 
					 | 
					 | 
					      retries = Retry(total=5, backoff_factor=0.5, status_forcelist=[409, 429, 503, 504]) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      URLFile._pool_manager = PoolManager(num_pools=10, maxsize=100, socket_options=socket_options, retries=retries) | 
					 | 
					 | 
					 | 
					      URLFile._pool_manager = PoolManager(num_pools=10, maxsize=100, socket_options=socket_options, retries=retries) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return URLFile._pool_manager | 
					 | 
					 | 
					 | 
					    return URLFile._pool_manager | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  def __init__(self, url: str, timeout: int=10, debug: bool=False, cache: bool|None=None): | 
					 | 
					 | 
					 | 
					  def __init__(self, url: str, timeout: int = 10, debug: bool = False, cache: bool | None = None): | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self._url = url | 
					 | 
					 | 
					 | 
					    self._url = url | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self._timeout = Timeout(connect=timeout, read=timeout) | 
					 | 
					 | 
					 | 
					    self._timeout = Timeout(connect=timeout, read=timeout) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self._pos = 0 | 
					 | 
					 | 
					 | 
					    self._pos = 0 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self._length: int|None = None | 
					 | 
					 | 
					 | 
					    self._length: int | None = None | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self._debug = debug | 
					 | 
					 | 
					 | 
					    self._debug = debug | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    #  True by default, false if FILEREADER_CACHE is defined, but can be overwritten by the cache input | 
					 | 
					 | 
					 | 
					    #  True by default, false if FILEREADER_CACHE is defined, but can be overwritten by the cache input | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self._force_download = not int(os.environ.get("FILEREADER_CACHE", "0")) | 
					 | 
					 | 
					 | 
					    self._force_download = not int(os.environ.get("FILEREADER_CACHE", "0")) | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -58,7 +60,7 @@ class URLFile: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  def __exit__(self, exc_type, exc_value, traceback) -> None: | 
					 | 
					 | 
					 | 
					  def __exit__(self, exc_type, exc_value, traceback) -> None: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    pass | 
					 | 
					 | 
					 | 
					    pass | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  def _request(self, method: str, url: str, headers: dict[str, str]|None=None) -> BaseHTTPResponse: | 
					 | 
					 | 
					 | 
					  def _request(self, method: str, url: str, headers: dict[str, str] | None = None) -> BaseHTTPResponse: | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return URLFile.pool_manager().request(method, url, timeout=self._timeout, headers=headers) | 
					 | 
					 | 
					 | 
					    return URLFile.pool_manager().request(method, url, timeout=self._timeout, headers=headers) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  def get_length_online(self) -> int: | 
					 | 
					 | 
					 | 
					  def get_length_online(self) -> int: | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -85,7 +87,7 @@ class URLFile: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        file_length.write(str(self._length)) | 
					 | 
					 | 
					 | 
					        file_length.write(str(self._length)) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return self._length | 
					 | 
					 | 
					 | 
					    return self._length | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  def read(self, ll: int|None=None) -> bytes: | 
					 | 
					 | 
					 | 
					  def read(self, ll: int | None = None) -> bytes: | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if self._force_download: | 
					 | 
					 | 
					 | 
					    if self._force_download: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      return self.read_aux(ll=ll) | 
					 | 
					 | 
					 | 
					      return self.read_aux(ll=ll) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -117,7 +119,7 @@ class URLFile: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        self._pos = file_end | 
					 | 
					 | 
					 | 
					        self._pos = file_end | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        return response | 
					 | 
					 | 
					 | 
					        return response | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  def read_aux(self, ll: int|None=None) -> bytes: | 
					 | 
					 | 
					 | 
					  def read_aux(self, ll: int | None = None) -> bytes: | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    download_range = False | 
					 | 
					 | 
					 | 
					    download_range = False | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    headers = {} | 
					 | 
					 | 
					 | 
					    headers = {} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if self._pos != 0 or ll is not None: | 
					 | 
					 | 
					 | 
					    if self._pos != 0 or ll is not None: | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -152,7 +154,7 @@ class URLFile: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self._pos += len(ret) | 
					 | 
					 | 
					 | 
					    self._pos += len(ret) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return ret | 
					 | 
					 | 
					 | 
					    return ret | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  def seek(self, pos:int) -> None: | 
					 | 
					 | 
					 | 
					  def seek(self, pos: int) -> None: | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self._pos = pos | 
					 | 
					 | 
					 | 
					    self._pos = pos | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  @property | 
					 | 
					 | 
					 | 
					  @property | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
					 | 
					
  |