mirror of
				https://github.com/KevinMidboe/spotify-downloader.git
				synced 2025-10-29 18:00:15 +00:00 
			
		
		
		
	Refactor exceptions
* Suffix names for custom exceptions with "Error" * Introduce exceptions for when the coressponding encoder isn't found
This commit is contained in:
		
							
								
								
									
										3
									
								
								setup.py
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								setup.py
									
									
									
									
									
								
							| @@ -14,7 +14,8 @@ setup( | |||||||
|         "spotdl", |         "spotdl", | ||||||
|         "spotdl.lyrics", |         "spotdl.lyrics", | ||||||
|         "spotdl.lyrics.providers", |         "spotdl.lyrics.providers", | ||||||
|         "spotdl.encoders", |         "spotdl.encode", | ||||||
|  |         "spotdl.encode.encoders", | ||||||
|         "spotdl.downloaders", |         "spotdl.downloaders", | ||||||
|         "spotdl.patch", |         "spotdl.patch", | ||||||
|     ], |     ], | ||||||
|   | |||||||
| @@ -1,8 +1,11 @@ | |||||||
|  | import shutil | ||||||
| import os | import os | ||||||
|  |  | ||||||
| from abc import ABC | from abc import ABC | ||||||
| from abc import abstractmethod | from abc import abstractmethod | ||||||
|  |  | ||||||
|  | from spotdl.encode.exceptions import EncoderNotFoundError | ||||||
|  |  | ||||||
| """ | """ | ||||||
|   NOTE ON ENCODERS |   NOTE ON ENCODERS | ||||||
|   ================ |   ================ | ||||||
| @@ -25,6 +28,12 @@ from abc import abstractmethod | |||||||
| class EncoderBase(ABC): | class EncoderBase(ABC): | ||||||
|     @abstractmethod |     @abstractmethod | ||||||
|     def __init__(self, encoder_path, loglevel, additional_arguments): |     def __init__(self, encoder_path, loglevel, additional_arguments): | ||||||
|  |         if shutil.which(encoder_path) is None: | ||||||
|  |             raise EncoderNotFoundError( | ||||||
|  |                 "{} executable does not exist or was not found in PATH.".format( | ||||||
|  |                     encoder_path | ||||||
|  |                 ) | ||||||
|  |             ) | ||||||
|         self.encoder_path = encoder_path |         self.encoder_path = encoder_path | ||||||
|         self._loglevel = loglevel |         self._loglevel = loglevel | ||||||
|         self._additional_arguments = additional_arguments |         self._additional_arguments = additional_arguments | ||||||
|   | |||||||
| @@ -2,16 +2,21 @@ import subprocess | |||||||
| import os | import os | ||||||
| from logzero import logger as log | from logzero import logger as log | ||||||
| from spotdl.encode import EncoderBase | from spotdl.encode import EncoderBase | ||||||
|  | from spotdl.encode.exceptions import EncoderNotFoundError | ||||||
|  | from spotdl.encode.exceptions import AvconvNotFoundError | ||||||
|  |  | ||||||
| class EncoderAvconv(EncoderBase): | class EncoderAvconv(EncoderBase): | ||||||
|     def __init__(self, encoder_path="avconv"): |     def __init__(self, encoder_path="avconv"): | ||||||
|         print("Using avconv is deprecated and this will be removed in", |         print("Using EncoderAvconv is deprecated and will be removed" | ||||||
|               "future versions. Use ffmpeg instead.") |               "in future versions. Use EncoderFFmpeg instead.") | ||||||
|         encoder_path = encoder_path |         encoder_path = encoder_path | ||||||
|         _loglevel = "-loglevel 0" |         _loglevel = "-loglevel 0" | ||||||
|         _additional_arguments = ["-ab", "192k"] |         _additional_arguments = ["-ab", "192k"] | ||||||
|  |  | ||||||
|         super().__init__(encoder_path, _loglevel, _additional_arguments) |         try: | ||||||
|  |             super().__init__(encoder_path, _loglevel, _additional_arguments) | ||||||
|  |         except EncoderNotFoundError as e: | ||||||
|  |             raise AvconvNotFoundError(e.args[0]) | ||||||
|  |  | ||||||
|     def set_argument(self, argument): |     def set_argument(self, argument): | ||||||
|         super().set_argument(argument) |         super().set_argument(argument) | ||||||
|   | |||||||
| @@ -1,7 +1,10 @@ | |||||||
| import subprocess | import subprocess | ||||||
| import os | import os | ||||||
| from logzero import logger as log | from logzero import logger as log | ||||||
|  |  | ||||||
| from spotdl.encode import EncoderBase | from spotdl.encode import EncoderBase | ||||||
|  | from spotdl.encode.exceptions import EncoderNotFoundError | ||||||
|  | from spotdl.encode.exceptions import FFmpegNotFoundError | ||||||
|  |  | ||||||
| RULES = { | RULES = { | ||||||
|     "m4a": { |     "m4a": { | ||||||
| @@ -17,14 +20,15 @@ RULES = { | |||||||
|     }, |     }, | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| class EncoderFFmpeg(EncoderBase): | class EncoderFFmpeg(EncoderBase): | ||||||
|     def __init__(self, encoder_path="ffmpeg"): |     def __init__(self, encoder_path="ffmpeg"): | ||||||
|         encoder_path = encoder_path |  | ||||||
|         _loglevel = "-hide_banner -nostats -v panic" |         _loglevel = "-hide_banner -nostats -v panic" | ||||||
|         _additional_arguments = ["-b:a", "192k", "-vn"] |         _additional_arguments = ["-b:a", "192k", "-vn"] | ||||||
|  |         try: | ||||||
|         super().__init__(encoder_path, _loglevel, _additional_arguments) |             super().__init__(encoder_path, _loglevel, _additional_arguments) | ||||||
|  |         except EncoderNotFoundError as e: | ||||||
|  |             raise FFmpegNotFoundError(e.args[0]) | ||||||
|         self._rules = RULES |         self._rules = RULES | ||||||
|  |  | ||||||
|     def set_argument(self, argument): |     def set_argument(self, argument): | ||||||
| @@ -41,18 +45,16 @@ class EncoderFFmpeg(EncoderBase): | |||||||
|         if initial_arguments is None: |         if initial_arguments is None: | ||||||
|             raise TypeError( |             raise TypeError( | ||||||
|                 'The input format ("{}") is not supported.'.format( |                 'The input format ("{}") is not supported.'.format( | ||||||
|                 input_extension, |                 input_encoding, | ||||||
|             ) |             ) | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|         arguments = initial_arguments.get(output_encoding) |         arguments = initial_arguments.get(output_encoding) | ||||||
|         if arguments is None: |         if arguments is None: | ||||||
|             raise TypeError( |             raise TypeError( | ||||||
|                 'The output format ("{}") is not supported.'.format( |                 'The output format ("{}") is not supported.'.format( | ||||||
|                 output_extension, |                 output_encoding, | ||||||
|             ) |             ) | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|         return arguments |         return arguments | ||||||
|  |  | ||||||
|     def set_debuglog(self): |     def set_debuglog(self): | ||||||
| @@ -61,12 +63,10 @@ class EncoderFFmpeg(EncoderBase): | |||||||
|     def _generate_encode_command(self, input_file, output_file): |     def _generate_encode_command(self, input_file, output_file): | ||||||
|         input_encoding = self.get_encoding(input_file) |         input_encoding = self.get_encoding(input_file) | ||||||
|         output_encoding = self.get_encoding(output_file) |         output_encoding = self.get_encoding(output_file) | ||||||
|  |  | ||||||
|         arguments = self._generate_encoding_arguments( |         arguments = self._generate_encoding_arguments( | ||||||
|             input_encoding, |             input_encoding, | ||||||
|             output_encoding |             output_encoding | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|         command = [self.encoder_path] \ |         command = [self.encoder_path] \ | ||||||
|             + ["-y", "-nostdin"] \ |             + ["-y", "-nostdin"] \ | ||||||
|             + self._loglevel.split() \ |             + self._loglevel.split() \ | ||||||
| @@ -82,10 +82,8 @@ class EncoderFFmpeg(EncoderBase): | |||||||
|             input_file, |             input_file, | ||||||
|             output_file |             output_file | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|         returncode = subprocess.call(encode_command) |         returncode = subprocess.call(encode_command) | ||||||
|         encode_successful = returncode == 0 |         encode_successful = returncode == 0 | ||||||
|  |  | ||||||
|         if encode_successful and delete_original: |         if encode_successful and delete_original: | ||||||
|             os.remove(input_file) |             os.remove(input_file) | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										0
									
								
								spotdl/encode/encoders/tests/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								spotdl/encode/encoders/tests/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										188
									
								
								spotdl/encode/encoders/tests/test_ffmpeg.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										188
									
								
								spotdl/encode/encoders/tests/test_ffmpeg.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,188 @@ | |||||||
|  | from spotdl.encode import EncoderBase | ||||||
|  | # from spotdl.encode import exceptions | ||||||
|  | from spotdl.encode.encoders import EncoderFFmpeg | ||||||
|  |  | ||||||
|  | import pytest | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class TestEncoderFFmpeg: | ||||||
|  |     def test_subclass(self): | ||||||
|  |         assert issubclass(EncoderFFmpeg, EncoderBase) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class TestEncodingDefaults: | ||||||
|  |     def m4a_to_mp3_encoder(input_file, output_file): | ||||||
|  |         command = [ | ||||||
|  |             'ffmpeg', '-y', '-nostdin', '-hide_banner', '-nostats', '-v', 'panic', | ||||||
|  |             '-i', input_file, | ||||||
|  |             '-codec:v', 'copy', | ||||||
|  |             '-codec:a', 'libmp3lame', | ||||||
|  |             '-ar', '48000', | ||||||
|  |             '-b:a', '192k', | ||||||
|  |             '-vn', output_file | ||||||
|  |         ] | ||||||
|  |         return command | ||||||
|  |  | ||||||
|  |     def m4a_to_webm_encoder(input_file, output_file): | ||||||
|  |         command = [ | ||||||
|  |             'ffmpeg', '-y', '-nostdin', '-hide_banner', '-nostats', '-v', 'panic', | ||||||
|  |             '-i', input_file, | ||||||
|  |             '-codec:a', 'libopus', | ||||||
|  |             '-vbr', 'on', | ||||||
|  |             '-b:a', '192k', | ||||||
|  |             '-vn', output_file | ||||||
|  |         ] | ||||||
|  |         return command | ||||||
|  |  | ||||||
|  |     def m4a_to_m4a_encoder(input_file, output_file): | ||||||
|  |         command = [ | ||||||
|  |             'ffmpeg', '-y', '-nostdin', '-hide_banner', '-nostats', '-v', 'panic', | ||||||
|  |             '-i', input_file, | ||||||
|  |             '-acodec', 'copy', | ||||||
|  |             '-b:a', '192k', | ||||||
|  |             '-vn', output_file | ||||||
|  |         ] | ||||||
|  |         return command | ||||||
|  |  | ||||||
|  |     def m4a_to_flac_encoder(input_file, output_file): | ||||||
|  |         command = [ | ||||||
|  |             'ffmpeg', '-y', '-nostdin', '-hide_banner', '-nostats', '-v', 'panic', | ||||||
|  |             '-i', input_file, | ||||||
|  |             '-codec:a', 'flac', | ||||||
|  |             '-ar', '48000', | ||||||
|  |             '-b:a', '192k', | ||||||
|  |             '-vn', output_file | ||||||
|  |         ] | ||||||
|  |         return command | ||||||
|  |  | ||||||
|  |     @pytest.mark.parametrize("files, expected_command", [ | ||||||
|  |         (("test.m4a", "test.mp3"), m4a_to_mp3_encoder("test.m4a", "test.mp3")), | ||||||
|  |         (("abc.m4a", "cba.webm"), m4a_to_webm_encoder("abc.m4a", "cba.webm")), | ||||||
|  |         (("bla bla.m4a", "ble ble.m4a"), m4a_to_m4a_encoder("bla bla.m4a", "ble ble.m4a")), | ||||||
|  |         (("😛.m4a", "• tongue.flac"), m4a_to_flac_encoder("😛.m4a", "• tongue.flac")), | ||||||
|  |     ]) | ||||||
|  |     def test_generate_encode_command(self, files, expected_command): | ||||||
|  |         encoder = EncoderFFmpeg() | ||||||
|  |         assert encoder._generate_encode_command(*files) == expected_command | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class TestEncodingInDebugMode: | ||||||
|  |     def m4a_to_mp3_encoder_with_debug(input_file, output_file): | ||||||
|  |         command = [ | ||||||
|  |             'ffmpeg', '-y', '-nostdin', '-loglevel', 'debug', | ||||||
|  |             '-i', input_file, | ||||||
|  |             '-codec:v', 'copy', | ||||||
|  |             '-codec:a', 'libmp3lame', | ||||||
|  |             '-ar', '48000', | ||||||
|  |             '-b:a', '192k', | ||||||
|  |             '-vn', output_file | ||||||
|  |         ] | ||||||
|  |         return command | ||||||
|  |  | ||||||
|  |     def m4a_to_webm_encoder_with_debug(input_file, output_file): | ||||||
|  |         command = [ | ||||||
|  |             'ffmpeg', '-y', '-nostdin', '-loglevel', 'debug', | ||||||
|  |             '-i', input_file, | ||||||
|  |             '-codec:a', 'libopus', | ||||||
|  |             '-vbr', 'on', | ||||||
|  |             '-b:a', '192k', | ||||||
|  |             '-vn', output_file | ||||||
|  |         ] | ||||||
|  |         return command | ||||||
|  |  | ||||||
|  |     def m4a_to_m4a_encoder_with_debug(input_file, output_file): | ||||||
|  |         command = [ | ||||||
|  |             'ffmpeg', '-y', '-nostdin', '-loglevel', 'debug', | ||||||
|  |             '-i', input_file, | ||||||
|  |             '-acodec', 'copy', | ||||||
|  |             '-b:a', '192k', | ||||||
|  |             '-vn', output_file | ||||||
|  |         ] | ||||||
|  |         return command | ||||||
|  |  | ||||||
|  |     def m4a_to_flac_encoder_with_debug(input_file, output_file): | ||||||
|  |         command = [ | ||||||
|  |             'ffmpeg', '-y', '-nostdin', '-loglevel', 'debug', | ||||||
|  |             '-i', input_file, | ||||||
|  |             '-codec:a', 'flac', | ||||||
|  |             '-ar', '48000', | ||||||
|  |             '-b:a', '192k', | ||||||
|  |             '-vn', output_file | ||||||
|  |         ] | ||||||
|  |         return command | ||||||
|  |  | ||||||
|  |     @pytest.mark.parametrize("files, expected_command", [ | ||||||
|  |         (("test.m4a", "test.mp3"), m4a_to_mp3_encoder_with_debug("test.m4a", "test.mp3")), | ||||||
|  |         (("abc.m4a", "cba.webm"), m4a_to_webm_encoder_with_debug("abc.m4a", "cba.webm")), | ||||||
|  |         (("bla bla.m4a", "ble ble.m4a"), m4a_to_m4a_encoder_with_debug("bla bla.m4a", "ble ble.m4a")), | ||||||
|  |         (("😛.m4a", "• tongue.flac"), m4a_to_flac_encoder_with_debug("😛.m4a", "• tongue.flac")), | ||||||
|  |     ]) | ||||||
|  |     def test_generate_encode_command_with_debug(self, files, expected_command): | ||||||
|  |         encoder = EncoderFFmpeg() | ||||||
|  |         encoder.set_debuglog() | ||||||
|  |         assert encoder._generate_encode_command(*files) == expected_command | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class TestEncodingAndTrimSilence: | ||||||
|  |     def m4a_to_mp3_encoder_and_trim_silence(input_file, output_file): | ||||||
|  |         command = [ | ||||||
|  |             'ffmpeg', '-y', '-nostdin', '-hide_banner', '-nostats', '-v', 'panic', | ||||||
|  |             '-i', input_file, | ||||||
|  |             '-codec:v', 'copy', | ||||||
|  |             '-codec:a', 'libmp3lame', | ||||||
|  |             '-ar', '48000', | ||||||
|  |             '-b:a', '192k', | ||||||
|  |             '-vn', | ||||||
|  |             '-af', 'silenceremove=start_periods=1', | ||||||
|  |             output_file | ||||||
|  |         ] | ||||||
|  |         return command | ||||||
|  |  | ||||||
|  |     def m4a_to_webm_encoder_and_trim_silence(input_file, output_file): | ||||||
|  |         command = [ | ||||||
|  |             'ffmpeg', '-y', '-nostdin', '-hide_banner', '-nostats', '-v', 'panic', | ||||||
|  |             '-i', input_file, | ||||||
|  |             '-codec:a', 'libopus', | ||||||
|  |             '-vbr', 'on', | ||||||
|  |             '-b:a', '192k', | ||||||
|  |             '-vn', | ||||||
|  |             '-af', 'silenceremove=start_periods=1', | ||||||
|  |             output_file | ||||||
|  |         ] | ||||||
|  |         return command | ||||||
|  |  | ||||||
|  |     def m4a_to_m4a_encoder_and_trim_silence(input_file, output_file): | ||||||
|  |         command = [ | ||||||
|  |             'ffmpeg', '-y', '-nostdin', '-hide_banner', '-nostats', '-v', 'panic', | ||||||
|  |             '-i', input_file, | ||||||
|  |             '-acodec', 'copy', | ||||||
|  |             '-b:a', '192k', | ||||||
|  |             '-vn', | ||||||
|  |             '-af', 'silenceremove=start_periods=1', | ||||||
|  |             output_file | ||||||
|  |         ] | ||||||
|  |         return command | ||||||
|  |  | ||||||
|  |     def m4a_to_flac_encoder_and_trim_silence(input_file, output_file): | ||||||
|  |         command = [ | ||||||
|  |             'ffmpeg', '-y', '-nostdin', '-hide_banner', '-nostats', '-v', 'panic', | ||||||
|  |             '-i', input_file, | ||||||
|  |             '-codec:a', 'flac', | ||||||
|  |             '-ar', '48000', | ||||||
|  |             '-b:a', '192k', | ||||||
|  |             '-vn', | ||||||
|  |             '-af', 'silenceremove=start_periods=1', | ||||||
|  |             output_file | ||||||
|  |         ] | ||||||
|  |         return command | ||||||
|  |  | ||||||
|  |     @pytest.mark.parametrize("files, expected_command", [ | ||||||
|  |         (("test.m4a", "test.mp3"), m4a_to_mp3_encoder_and_trim_silence("test.m4a", "test.mp3")), | ||||||
|  |         (("abc.m4a", "cba.webm"), m4a_to_webm_encoder_and_trim_silence("abc.m4a", "cba.webm")), | ||||||
|  |         (("bla bla.m4a", "ble ble.m4a"), m4a_to_m4a_encoder_and_trim_silence("bla bla.m4a", "ble ble.m4a")), | ||||||
|  |         (("😛.m4a", "• tongue.flac"), m4a_to_flac_encoder_and_trim_silence("😛.m4a", "• tongue.flac")), | ||||||
|  |     ]) | ||||||
|  |     def test_generate_encode_command_and_trim_silence(self, files, expected_command): | ||||||
|  |         encoder = EncoderFFmpeg() | ||||||
|  |         encoder.set_trim_silence() | ||||||
|  |         assert encoder._generate_encode_command(*files) == expected_command | ||||||
							
								
								
									
										20
									
								
								spotdl/encode/exceptions.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								spotdl/encode/exceptions.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | |||||||
|  | class EncoderNotFoundError(Exception): | ||||||
|  |     __module__ = Exception.__module__ | ||||||
|  |  | ||||||
|  |     def __init__(self, message=None): | ||||||
|  |         super(EncoderNotFoundError, self).__init__(message) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class FFmpegNotFoundError(EncoderNotFoundError): | ||||||
|  |     __module__ = Exception.__module__ | ||||||
|  |  | ||||||
|  |     def __init__(self, message=None): | ||||||
|  |         super(FFmpegNotFoundError, self).__init__(message) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class AvconvNotFoundError(EncoderNotFoundError): | ||||||
|  |     __module__ = Exception.__module__ | ||||||
|  |  | ||||||
|  |     def __init__(self, message=None): | ||||||
|  |         super(AvconvNotFoundError, self).__init__(message) | ||||||
|  |  | ||||||
							
								
								
									
										0
									
								
								spotdl/encode/tests/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								spotdl/encode/tests/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										13
									
								
								spotdl/encode/tests/test_encode_base.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								spotdl/encode/tests/test_encode_base.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | |||||||
|  | from spotdl.encode import EncoderBase | ||||||
|  |  | ||||||
|  | import pytest | ||||||
|  |  | ||||||
|  | def test_abstract_base_class_encoderbase(): | ||||||
|  |     encoder_path = "ffmpeg" | ||||||
|  |     _loglevel = "-hide_banner -nostats -v panic" | ||||||
|  |     _additional_arguments = ["-b:a", "192k", "-vn"] | ||||||
|  |  | ||||||
|  |     with pytest.raises(TypeError): | ||||||
|  |         # This abstract base class must be inherited from | ||||||
|  |         # for instantiation | ||||||
|  |         EncoderBase(encoder_path, _loglevel, _additional_arguments) | ||||||
							
								
								
									
										14
									
								
								spotdl/encode/tests/test_exceptions.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								spotdl/encode/tests/test_exceptions.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | |||||||
|  | from spotdl.encode.exceptions import EncoderNotFoundError | ||||||
|  | from spotdl.encode.exceptions import FFmpegNotFoundError | ||||||
|  | from spotdl.encode.exceptions import AvconvNotFoundError | ||||||
|  |  | ||||||
|  | import pytest | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class TestEncoderNotFoundSubclass: | ||||||
|  |     def test_ffmpeg_not_found_subclass(self): | ||||||
|  |         assert issubclass(FFmpegNotFoundError, EncoderNotFoundError) | ||||||
|  |  | ||||||
|  |     def test_avconv_not_found_subclass(self): | ||||||
|  |         assert issubclass(AvconvNotFoundError, EncoderNotFoundError) | ||||||
|  |  | ||||||
| @@ -1,5 +1,5 @@ | |||||||
| class LyricsNotFound(Exception): | class LyricsNotFoundError(Exception): | ||||||
|     __module__ = Exception.__module__ |     __module__ = Exception.__module__ | ||||||
|  |  | ||||||
|     def __init__(self, message=None): |     def __init__(self, message=None): | ||||||
|         super(LyricsNotFound, self).__init__(message) |         super(LyricsNotFoundError, self).__init__(message) | ||||||
|   | |||||||
| @@ -2,7 +2,7 @@ from bs4 import BeautifulSoup | |||||||
| import urllib.request | import urllib.request | ||||||
|  |  | ||||||
| from spotdl.lyrics.lyric_base import LyricBase | from spotdl.lyrics.lyric_base import LyricBase | ||||||
| from spotdl.lyrics.exceptions import LyricsNotFound | from spotdl.lyrics.exceptions import LyricsNotFoundError | ||||||
|  |  | ||||||
| BASE_URL = "https://genius.com" | BASE_URL = "https://genius.com" | ||||||
|  |  | ||||||
| @@ -26,7 +26,7 @@ class Genius(LyricBase): | |||||||
|         try: |         try: | ||||||
|             response = urllib.request.urlopen(request, timeout=timeout) |             response = urllib.request.urlopen(request, timeout=timeout) | ||||||
|         except urllib.request.HTTPError: |         except urllib.request.HTTPError: | ||||||
|             raise LyricsNotFound( |             raise LyricsNotFoundError( | ||||||
|                 "Could not find lyrics for {} - {} at URL: {}".format( |                 "Could not find lyrics for {} - {} at URL: {}".format( | ||||||
|                     self.artist, self.song, url |                     self.artist, self.song, url | ||||||
|                 ) |                 ) | ||||||
| @@ -40,7 +40,7 @@ class Genius(LyricBase): | |||||||
|         if lyrics_paragraph: |         if lyrics_paragraph: | ||||||
|             return lyrics_paragraph.get_text() |             return lyrics_paragraph.get_text() | ||||||
|         else: |         else: | ||||||
|             raise LyricsNotFound("The lyrics for this track are yet to be released.") |             raise LyricsNotFoundError("The lyrics for this track are yet to be released.") | ||||||
|  |  | ||||||
|     def get_lyrics(self, linesep="\n", timeout=None): |     def get_lyrics(self, linesep="\n", timeout=None): | ||||||
|         url = self._guess_lyric_url() |         url = self._guess_lyric_url() | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| import lyricwikia | import lyricwikia | ||||||
|  |  | ||||||
| from spotdl.lyrics.lyric_base import LyricBase | from spotdl.lyrics.lyric_base import LyricBase | ||||||
| from spotdl.lyrics.exceptions import LyricsNotFound | from spotdl.lyrics.exceptions import LyricsNotFoundError | ||||||
|  |  | ||||||
|  |  | ||||||
| class LyricWikia(LyricBase): | class LyricWikia(LyricBase): | ||||||
| @@ -13,6 +13,6 @@ class LyricWikia(LyricBase): | |||||||
|         try: |         try: | ||||||
|             lyrics = lyricwikia.get_lyrics(self.artist, self.song, linesep, timeout) |             lyrics = lyricwikia.get_lyrics(self.artist, self.song, linesep, timeout) | ||||||
|         except lyricwikia.LyricsNotFound as e: |         except lyricwikia.LyricsNotFound as e: | ||||||
|             raise LyricsNotFound(e.args[0]) |             raise LyricsNotFoundError(e.args[0]) | ||||||
|         else: |         else: | ||||||
|             return lyrics |             return lyrics | ||||||
|   | |||||||
| @@ -33,5 +33,5 @@ class TestGenius: | |||||||
|             raise urllib.request.HTTPError("", "", "", "", "") |             raise urllib.request.HTTPError("", "", "", "", "") | ||||||
|  |  | ||||||
|         monkeypatch.setattr("urllib.request.urlopen", mocked_urlopen) |         monkeypatch.setattr("urllib.request.urlopen", mocked_urlopen) | ||||||
|         with pytest.raises(exceptions.LyricsNotFound): |         with pytest.raises(exceptions.LyricsNotFoundError): | ||||||
|             track.get_lyrics() |             track.get_lyrics() | ||||||
|   | |||||||
| @@ -25,11 +25,11 @@ class TestLyricWikia: | |||||||
|         def lyricwikia_lyrics_not_found(msg): |         def lyricwikia_lyrics_not_found(msg): | ||||||
|             raise lyricwikia.LyricsNotFound(msg) |             raise lyricwikia.LyricsNotFound(msg) | ||||||
|  |  | ||||||
|         # Wrap `lyricwikia.LyricsNotFound` with `exceptions.LyricsNotFound` error. |         # Wrap `lyricwikia.LyricsNotFoundError` with `exceptions.LyricsNotFoundError` error. | ||||||
|         monkeypatch.setattr( |         monkeypatch.setattr( | ||||||
|             "lyricwikia.get_lyrics", |             "lyricwikia.get_lyrics", | ||||||
|             lambda a, b, c, d: lyricwikia_lyrics_not_found("Nope, no lyrics."), |             lambda a, b, c, d: lyricwikia_lyrics_not_found("Nope, no lyrics."), | ||||||
|         ) |         ) | ||||||
|         track = LyricWikia("Lyricwikia", "Lyricwikia") |         track = LyricWikia("Lyricwikia", "Lyricwikia") | ||||||
|         with pytest.raises(exceptions.LyricsNotFound): |         with pytest.raises(exceptions.LyricsNotFoundError): | ||||||
|             track.get_lyrics() |             track.get_lyrics() | ||||||
|   | |||||||
| @@ -12,7 +12,7 @@ import functools | |||||||
| from spotdl import const | from spotdl import const | ||||||
| from spotdl import internals | from spotdl import internals | ||||||
| from spotdl.lyrics.providers import LyricClasses | from spotdl.lyrics.providers import LyricClasses | ||||||
| from spotdl.lyrics.exceptions import LyricsNotFound | from spotdl.lyrics.exceptions import LyricsNotFoundError | ||||||
|  |  | ||||||
| spotify = None | spotify = None | ||||||
|  |  | ||||||
| @@ -82,7 +82,7 @@ def generate_metadata(raw_song): | |||||||
|         track = LyricClass(meta_tags["artists"][0]["name"], meta_tags["name"]) |         track = LyricClass(meta_tags["artists"][0]["name"], meta_tags["name"]) | ||||||
|         try: |         try: | ||||||
|             meta_tags["lyrics"] = track.get_lyrics() |             meta_tags["lyrics"] = track.get_lyrics() | ||||||
|         except LyricsNotFound: |         except LyricsNotFoundError: | ||||||
|             continue |             continue | ||||||
|         else: |         else: | ||||||
|             break |             break | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user