mirror of
				https://github.com/devine-dl/devine.git
				synced 2025-11-04 11:54:50 +00:00 
			
		
		
		
	refactor(Track): Add type checks, improve typing
This commit is contained in:
		
							parent
							
								
									944cfb0273
								
							
						
					
					
						commit
						470e051100
					
				@ -38,6 +38,31 @@ class Track:
 | 
				
			|||||||
        edition: Optional[str] = None,
 | 
					        edition: Optional[str] = None,
 | 
				
			||||||
        extra: Optional[Any] = None
 | 
					        extra: Optional[Any] = None
 | 
				
			||||||
    ) -> None:
 | 
					    ) -> None:
 | 
				
			||||||
 | 
					        if not isinstance(id_, str):
 | 
				
			||||||
 | 
					            raise TypeError(f"Expected id to be a {str}, not {type(id_)}")
 | 
				
			||||||
 | 
					        if not isinstance(url, (str, list)):
 | 
				
			||||||
 | 
					            raise TypeError(f"Expected url to be a {str}, or list of {str}, not {type(url)}")
 | 
				
			||||||
 | 
					        if not isinstance(language, (Language, str)):
 | 
				
			||||||
 | 
					            raise TypeError(f"Expected language to be a {Language} or {str}, not {type(language)}")
 | 
				
			||||||
 | 
					        if not isinstance(is_original_lang, bool):
 | 
				
			||||||
 | 
					            raise TypeError(f"Expected is_original_lang to be a {bool}, not {type(is_original_lang)}")
 | 
				
			||||||
 | 
					        if not isinstance(descriptor, Track.Descriptor):
 | 
				
			||||||
 | 
					            raise TypeError(f"Expected descriptor to be a {Track.Descriptor}, not {type(descriptor)}")
 | 
				
			||||||
 | 
					        if not isinstance(needs_repack, bool):
 | 
				
			||||||
 | 
					            raise TypeError(f"Expected needs_repack to be a {bool}, not {type(needs_repack)}")
 | 
				
			||||||
 | 
					        if not isinstance(edition, (str, type(None))):
 | 
				
			||||||
 | 
					            raise TypeError(f"Expected edition to be a {str}, not {type(edition)}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        invalid_urls = ", ".join(set(type(x) for x in url if not isinstance(x, str)))
 | 
				
			||||||
 | 
					        if invalid_urls:
 | 
				
			||||||
 | 
					            raise TypeError(f"Expected all items in url to be a {str}, but found {invalid_urls}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if drm is not None:
 | 
				
			||||||
 | 
					            try:
 | 
				
			||||||
 | 
					                iter(drm)
 | 
				
			||||||
 | 
					            except TypeError:
 | 
				
			||||||
 | 
					                raise TypeError(f"Expected drm to be an iterable, not {type(drm)}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.id = id_
 | 
					        self.id = id_
 | 
				
			||||||
        self.url = url
 | 
					        self.url = url
 | 
				
			||||||
        # required basic metadata
 | 
					        # required basic metadata
 | 
				
			||||||
@ -75,7 +100,7 @@ class Track:
 | 
				
			|||||||
            items=", ".join([f"{k}={repr(v)}" for k, v in self.__dict__.items()])
 | 
					            items=", ".join([f"{k}={repr(v)}" for k, v in self.__dict__.items()])
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __eq__(self, other: object) -> bool:
 | 
					    def __eq__(self, other: Any) -> bool:
 | 
				
			||||||
        return isinstance(other, Track) and self.id == other.id
 | 
					        return isinstance(other, Track) and self.id == other.id
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_track_name(self) -> Optional[str]:
 | 
					    def get_track_name(self) -> Optional[str]:
 | 
				
			||||||
@ -166,21 +191,28 @@ class Track:
 | 
				
			|||||||
            byte_range: Range of bytes to download from the explicit or implicit URL.
 | 
					            byte_range: Range of bytes to download from the explicit or implicit URL.
 | 
				
			||||||
            session: Session context, e.g., authorization and headers.
 | 
					            session: Session context, e.g., authorization and headers.
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
 | 
					        if not isinstance(maximum_size, int):
 | 
				
			||||||
 | 
					            raise TypeError(f"Expected maximum_size to be an {int}, not {type(maximum_size)}")
 | 
				
			||||||
 | 
					        if not isinstance(url, (str, type(None))):
 | 
				
			||||||
 | 
					            raise TypeError(f"Expected url to be a {str}, not {type(url)}")
 | 
				
			||||||
 | 
					        if not isinstance(byte_range, (str, type(None))):
 | 
				
			||||||
 | 
					            raise TypeError(f"Expected byte_range to be a {str}, not {type(byte_range)}")
 | 
				
			||||||
 | 
					        if not isinstance(session, (requests.Session, type(None))):
 | 
				
			||||||
 | 
					            raise TypeError(f"Expected session to be a {requests.Session}, not {type(session)}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if not url:
 | 
				
			||||||
 | 
					            if self.descriptor != self.Descriptor.URL:
 | 
				
			||||||
 | 
					                # We cannot know which init map from the HLS or DASH playlist is actually used.
 | 
				
			||||||
 | 
					                # For DASH this could be from any adaptation set, any period, e.t.c.
 | 
				
			||||||
 | 
					                # For HLS we could make some assumptions, but it's best that it is explicitly provided.
 | 
				
			||||||
 | 
					                raise ValueError(f"An explicit URL must be provided for {self.descriptor.name} tracks")
 | 
				
			||||||
 | 
					            if not self.url:
 | 
				
			||||||
 | 
					                raise ValueError("An explicit URL must be provided as the track has no URL")
 | 
				
			||||||
 | 
					            url = self.url
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if not session:
 | 
					        if not session:
 | 
				
			||||||
            session = requests.Session()
 | 
					            session = requests.Session()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if self.descriptor != self.Descriptor.URL and not url:
 | 
					 | 
				
			||||||
            # We cannot know which init map from the HLS or DASH playlist is actually used.
 | 
					 | 
				
			||||||
            # For DASH this could be from any adaptation set, any period, e.t.c.
 | 
					 | 
				
			||||||
            # For HLS we could make some assumptions, but it's best that it is explicitly provided.
 | 
					 | 
				
			||||||
            raise ValueError(
 | 
					 | 
				
			||||||
                f"An explicit URL to an init map or file must be provided for {self.descriptor.name} tracks."
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        url = url or self.url
 | 
					 | 
				
			||||||
        if not url:
 | 
					 | 
				
			||||||
            raise ValueError("The track must have an URL to point towards it's data.")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        content_length = maximum_size
 | 
					        content_length = maximum_size
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if byte_range:
 | 
					        if byte_range:
 | 
				
			||||||
@ -270,32 +302,61 @@ class Track:
 | 
				
			|||||||
        self.swap(output_path)
 | 
					        self.swap(output_path)
 | 
				
			||||||
        self.move(original_path)
 | 
					        self.move(original_path)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def move(self, target: Union[str, Path]) -> bool:
 | 
					    def move(self, target: Union[Path, str]) -> bool:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Move the Track's file from current location, to target location.
 | 
					        Move the Track's file from current location, to target location.
 | 
				
			||||||
        This will overwrite anything at the target path.
 | 
					        This will overwrite anything at the target path.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Raises:
 | 
				
			||||||
 | 
					            TypeError: If the target argument is not the expected type.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Returns True if the move succeeded, or False if there was no file to move, or
 | 
				
			||||||
 | 
					        the file failed to move.
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
 | 
					        if not isinstance(target, (str, Path)):
 | 
				
			||||||
 | 
					            raise TypeError(f"Expected {target} to be a {Path} or {str}, not {type(target)}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if not self.path:
 | 
					        if not self.path:
 | 
				
			||||||
            return False
 | 
					            return False
 | 
				
			||||||
        target = Path(target)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ok = Path(shutil.move(self.path, target)).resolve() == target.resolve()
 | 
					        if not isinstance(target, Path):
 | 
				
			||||||
        if ok:
 | 
					            target = Path(target)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        moved_to = Path(shutil.move(self.path, target))
 | 
				
			||||||
 | 
					        success = moved_to.resolve() == target.resolve()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if success:
 | 
				
			||||||
            self.path = target
 | 
					            self.path = target
 | 
				
			||||||
        return ok
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def swap(self, target: Union[str, Path]) -> bool:
 | 
					        return success
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def swap(self, target: Union[Path, str]) -> bool:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Swaps the Track's file with the Target file. The current Track's file is deleted.
 | 
					        Delete the Track's file and swap to the Target file.
 | 
				
			||||||
        Returns False if the Track is not yet downloaded, or the target path does not exist.
 | 
					
 | 
				
			||||||
 | 
					        Raises:
 | 
				
			||||||
 | 
					            TypeError: If the target argument is not the expected type.
 | 
				
			||||||
 | 
					            OSError: If the file somehow failed to move.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Returns True if the swap succeeded, or False if the track is not yet downloaded,
 | 
				
			||||||
 | 
					        or the target path does not exist.
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
 | 
					        if not isinstance(target, (str, Path)):
 | 
				
			||||||
 | 
					            raise TypeError(f"Expected {target} to be a {Path} or {str}, not {type(target)}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        target = Path(target)
 | 
					        target = Path(target)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if not target.exists() or not self.path:
 | 
					        if not target.exists() or not self.path:
 | 
				
			||||||
            return False
 | 
					            return False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.path.unlink()
 | 
					        self.path.unlink()
 | 
				
			||||||
        ok = Path(shutil.move(target, self.path)).resolve() == self.path.resolve()
 | 
					
 | 
				
			||||||
        if not ok:
 | 
					        moved_to = Path(shutil.move(target, self.path))
 | 
				
			||||||
 | 
					        success = moved_to.resolve() == self.path.resolve()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if not success:
 | 
				
			||||||
            return False
 | 
					            return False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return self.move(target)
 | 
					        return self.move(target)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user