Commits

Guillermo Szeliga committed 23680a6

- READMEs and CHANGELOG updated
- --disable-cover-art parameter added.

Comments (0)

Files changed (10)

+v1.2.0
+--------------------------
+
+- Download album cover art support added.
+
 v1.1.0
 --------------------------
 
 Because it will save you a __*HUGE*__ amount of time by:
 
 * Tagging all your _mp3_ files with their right ID3Tag information.
-* Decompressing and tagging any __*zip*__, __*rar*__ or __*7z*__ file that you have with music on it transparently __(New feature!!)__
+* Downloading album cover art __(New feature!!)__
+* Decompressing and tagging any __*zip*__, __*rar*__ or __*7z*__ file that you have with music on it transparently 
 * Creating a hierarchical media tree organized by artists and albums.
 * Naming all files in a simple and yet clear syntax.
-* Letting you know whenever a file has something that prevents it from being accurately classified.
+* Detecting tag issues that prevent files from being accurately classified.
 * Avoiding any stranded or unknown music files inside any portable music player (which usually happens in Creative Zen players, just to name an example) which take up storage space and are not easily detected.
 
 ## Installation guide:
 
-Before proceeding with the installation, please check whether your system already has the following dependencies:
+Before proceeding with the installation, please check if your system already has the following packages installed:
 
 
 * Python 2.7.x and headers (python-dev)
 * Chromaprint tools (libchromaprint-tools)
 * Libevent headers (libevent-dev)
+* Libxml (libxml2-dev and libxslt-dev)
 * unrar and 7z commands available within your system _PATH_ 
 
 
 
 The main binary is called _longtang_ (as you can imagine) and it accepts the following parameters:
 
-* __source__: Source path where all the to-be-processed files are located.
-* __target__: Target path where the hierarchical structure will be created.
-* __verbosity__: Level of debug information to be printed. Accepted values are: _DEBUG_, _INFO_, _WARN_ or _ERROR_. Default value is _NONE_
-* __override-tags__: _(Optional)_ Whether you want _Longtang_ to override any id3tag information on the source music files. _Bear in mind that if the amount of files is high it will turn the process to be real slow_.
-* __offline__: _(Optional)_ Since any missing id3tag information will be retrieved using [Acoustid](http://acoustid.org/chromaprint) service, maybe you might be interesed in not performing this action and just handle your media collection with the already existing id3 information and point out any failure during the process.
-* __help__: Prints out help information
+* __--source__: Source path where all the to-be-processed files are located.
+* __--target__: Target path where the hierarchical structure will be created.
+* __--verbosity__: Level of debug information to be printed. Accepted values are: _DEBUG_, _INFO_, _WARN_ or _ERROR_. Default value is _NONE_
+* __--override-tags__: _(Optional)_ Whether you want _Longtang_ to override any id3tag information on the source music files. _Bear in mind that if the amount of files is high it will turn the process to be real slow_.
+* __--offline__: _(Optional)_ Since any missing id3tag information will be retrieved using [Acoustid](http://acoustid.org/chromaprint) service, maybe you might be interesed in not performing this action and just handle your media collection with the already existing id3 information and point out any failure during the process.
+* __--disable-cover-art__: _(Optional)_ Disables resolution of all cover art from all matched artists and albums.
+* __--help__: Prints out help information
 
 
 ## What's coming next?
 Well, i currently have a lot of ideas but, in a short term, i'm thinking in:
 
 * Supporting more music formats: ogg, mpc, flac and so on.
-* Supporting cover-art automatic retrieval.
 * Porting source code into Python 3.
-* Replacing _gevent_ library with _multiprocessing_ library so that we gain execution _**parallelism**_.
+* Replacing _gevent_ with _multiprocessing_ library so that we gain execution _**parallelism**_ (take a look at branch __features/multiprocessing__ for further details).
 
 ## Bugs and Feedback
 
 Because it will save you a **HUGE** amount of time by:
 
 * Tagging all your *mp3* files with the right ID3Tag information.
-* Decompressing and tagging any **zip**, **rar** or **7z** file that you have with music on it transparently **(New feature!!)**
+* Downloading album cover art **(New feature!!)**
+* Decompressing and tagging any **zip**, **rar** or **7z** file that you have with music on it transparently.
 * Creating a hierarchical media tree organized by artists and albums.
 * Naming all files in a simple and yet clear syntax.
-* Letting you know whenever a file has something that prevents it from being accurately classified.
+* Detecting tag issues that prevent files from being accurately classified.
 * Avoiding any stranded or unknown music files inside any portable music player (which usually happens in Creative Zen players, just to name an example) which take up storage space and are not easily detected.
 
 Installation guide:
 -------------------
 
-Before proceeding with the installation, please check whether your system already has the following dependencies:
+Before proceeding with the installation, please check if your system already has the following packages installed:
 
 
 * Python 2.7.x and headers (python-dev)
 * Chromaprint tools (libchromaprint-tools)
 * Libevent headers (libevent-dev)
+* Libxml (libxml2-dev and libxslt-dev)
+* unrar and 7z commands available within your system _PATH_ 
 
 
 After that, you can proceed to install in either two manners: from the source code or from `Pypi <https://pypi.python.org/pypi>`_ by using `pip <http://www.pip-installer.org/en/latest/>`_ utility.
 * --verbosity  Level of debug information to be printed. Accepted values are: *DEBUG*, *INFO*, *WARN* or *ERROR*. Default value is *NONE*
 * --override-tags  (Optional) Whether you want *Longtang* to override any id3tag information on the source music files. *Bear in mind that if the amount of files is high it will turn the process to be real slow*.
 * --offline  (Optional) Since any missing id3tag information will be retrieved using `Acoustid <http://acoustid.org/chromaprint>`_ service, maybe you might be interesed in not performing this action and just handle your media collection with the already existing id3 information and point out any failure during the process.
+* --disable-cover-art: (Optional) Disables resolution of all cover art from all matched artists and albums.
 * --help  Prints out help information
 
 
 Well, i currently have a lot of ideas but, in a short term, i'm thinking in:
 
 * Supporting more music formats: ogg, mpc, flac and so on.
-* Supporting cover-art automatic retrieval.
 * Porting source code into Python 3.
-* Replacing *gevent* library with *multiprocessing* library so that we gain execution **parallelism**.
+* Replacing _gevent_ with _multiprocessing_ library so that we gain execution _**parallelism**_ (take a look at branch **features/multiprocessing** for further details).
 
 Bugs and Feedback
 -----------------
     parser.add_argument('--target', dest='target_path', required=True, action='store', help='Target path where all the media files will be classified')
     parser.add_argument('--verbosity', dest='verbosity', required=False, action='store', default=None, choices=['DEBUG', 'INFO', 'WARN', 'ERROR'], help='Verbosity level')
     parser.add_argument('--override-tags', dest='override', required=False, action='store', nargs='?', default=False, const=True, help='If present, all id3tags will be overriden using MusicBrainz information (this parameter is not compatible with --offline option)')
-    parser.add_argument('--offline', dest='offline', required=False, action='store', nargs='?', default=False, const=True, help='If present, no request to MusicBrainz service will be commited so that any incomplete metatag will cause the file to be ignored (this parameter is not compatible with --override option)')    
+    parser.add_argument('--offline', dest='offline', required=False, action='store', nargs='?', default=False, const=True, help='If present, no request to MusicBrainz service will be commited so that any incomplete metatag will cause the file to be ignored (this parameter is not compatible with --override option)')
+    parser.add_argument('--disable-cover-art', dest='disable_cover_art', required=False, action='store', nargs='?', default=False, const=True, help='If present, no album cover art will be retrieved for any matched album')
                        
     args = parser.parse_args()
 
                                .generate_at(target_path)\
                                .override_tags(args.override)\
                                .offline_mode(args.offline)\
+                               .download_cover_art(not(args.disable_cover_art))\
                                .build()
 
         props_builder = properties.SystemPropertiesBuilder()

longtang/actors/supervisors/filepackaging/configuration.py

 	
 	def __init__(self):
 		self.__offline_mode=None
+		self.__is_enable=None
+
+	@property
+	def cover_art_enabled(self):
+		return self.__is_enable
+
+	@cover_art_enabled.setter
+	def cover_art_enabled(self, value):
+		self.__is_enable = value
 
 	@property
 	def offline_mode(self):
 
 	def __init__(self):
 		self.__offline_mode=False
+		self.__enabled=True
 
 	def offline_mode(self, value):
 		self.__offline_mode=value
 		return self
 
+	def cover_art_enabled(self, value):
+		self.__enabled=value
+		return self
+
 	def build(self):
 		config = FilePackagingConfiguration()
 
 		config.offline_mode=self.__offline_mode
+		config.cover_art_enabled=self.__enabled
 
 		return config

longtang/actors/supervisors/filepackaging/filepackaging.py

 																									message.new_dir_path(),\
 																									message.tracking()), self)
 
-			if not self.__config.offline_mode:
+			if not self.__config.offline_mode and self.__config.cover_art_enabled:
 				self.context().get_by_id('cover-art-actor').tell(coverart_messages.LookupCoverArt(	message.metadata().artist, \
 																									message.metadata().album, \
 																									message.new_dir_path()), self)

longtang/actors/supervisors/filepackaging/test/test_filepackaging.py

 
 	def test_file_packaging(self):
 
-		config = configuration.FilePackagingConfigurationBuilder().offline_mode(False).build()
+		config = configuration.FilePackagingConfigurationBuilder().offline_mode(False).cover_art_enabled(False).build()
 
 		data_dir = os.path.join(actorstestutils.current_dirpath(__file__), 'data')
 		source_file = os.path.join(data_dir, 'with_id3taginfo.mp3')
 
 	def test_file_packaging_copy_failure(self):
 
-		config = configuration.FilePackagingConfigurationBuilder().offline_mode(False).build()
+		config = configuration.FilePackagingConfigurationBuilder().offline_mode(False).cover_art_enabled(False).build()
 
 		data_dir = os.path.join(actorstestutils.current_dirpath(__file__), 'data')
 		source_file = os.path.join(data_dir, 'nonexisting_id3taginfo.mp3')
 
 	def test_file_packaging_folder_creation_failure(self):
 
-		config = configuration.FilePackagingConfigurationBuilder().offline_mode(False).build()
+		config = configuration.FilePackagingConfigurationBuilder().offline_mode(False).cover_art_enabled(False).build()
 
 
 		data_dir = os.path.join(actorstestutils.current_dirpath(__file__), 'data')
 
 	def test_file_packaging_metadata_writting_failure(self):
 
-		config = configuration.FilePackagingConfigurationBuilder().offline_mode(False).build()
+		config = configuration.FilePackagingConfigurationBuilder().offline_mode(False).cover_art_enabled(False).build()
 
 		data_dir = os.path.join(actorstestutils.current_dirpath(__file__), 'data')
 		source_file = os.path.join(data_dir, 'with_id3taginfo.mp3')

longtang/actors/supervisors/flowconductor/flowconductor.py

 		self.logger().info('Initializing filepackaging-actor...')
 
 		packagingconfig = packaging_config.FilePackagingConfigurationBuilder().offline_mode(self.__config.offline_mode)\
+																				.cover_art_enabled(self.__config.download_cover_art)\
 																		  		.build()
 
 		self.__filepackaging_ref = self.context().with_factory(packaging_factory.FilePackagingSupervisorFactory(packagingconfig),'filepackaging-actor')

longtang/actors/supervisors/flowconductor/test/test_flowconductor.py

 		data_dir = os.path.join(actorstestutils.current_dirpath(__file__), 'data')
 
 		config_builder = configuration.LongTangConfigurationBuilder()
-		config = config_builder.read_from(base_from_test_dir).generate_at(base_to_test_dir).build()
+		config = config_builder.read_from(base_from_test_dir).generate_at(base_to_test_dir).download_cover_art(False).build()
 
 		actor_system = system.ActorSystem()
 		main_actor = actor_system.with_factory(factory.FlowConductorSupervisorFactory(config),'flowconductor-test-actor')
 		source_file_with_id3tag = actorstestutils.copy_to_tmp(source=os.path.join(data_dir, 'with_id3taginfo.mp3'),suffix='.tmp.mp3',dir=base_from_test_dir)
 
 		config_builder = configuration.LongTangConfigurationBuilder()
-		config = config_builder.read_from(base_from_test_dir).generate_at(base_to_test_dir).build()
+		config = config_builder.read_from(base_from_test_dir).generate_at(base_to_test_dir).download_cover_art(False).build()
 
 		flowconductor_actor = actorstestutils.TestActorBuilder().with_factory(factory.FlowConductorSupervisorFactory(config))\
 															.with_id('flowconductor-test-actor')\
 		source_file_with_id3tag = actorstestutils.copy_to_tmp(source=os.path.join(data_dir, 'invalid_metadata.mp3'),suffix='.tmp.mp3',dir=base_from_test_dir)		
 
 		config_builder = configuration.LongTangConfigurationBuilder()
-		config = config_builder.read_from(base_from_test_dir).generate_at(base_to_test_dir).build()
+		config = config_builder.read_from(base_from_test_dir).generate_at(base_to_test_dir).download_cover_art(False).build()
 
 		flowconductor_actor = actorstestutils.TestActorBuilder().with_factory(factory.FlowConductorSupervisorFactory(config))\
 															.with_id('flowconductor-test-actor')\
 	def test_single_file_processing_nonexisting_path(self):
 
 		config_builder = configuration.LongTangConfigurationBuilder()
-		config = config_builder.read_from(base_from_test_dir).generate_at(base_to_test_dir).build()
+		config = config_builder.read_from(base_from_test_dir).generate_at(base_to_test_dir).download_cover_art(False).build()
 
 		flowconductor_actor = actorstestutils.TestActorBuilder().with_factory(factory.FlowConductorSupervisorFactory(config))\
 															.with_id('flowconductor-test-actor')\
 		source_file_with_id3tag = actorstestutils.copy_to_tmp(source=os.path.join(data_dir, 'with_id3taginfo.mp3'),suffix='.tmp.mp3',dir=base_from_test_dir)
 
 		config_builder = configuration.LongTangConfigurationBuilder()
-		config = config_builder.read_from(base_from_test_dir).generate_at('/dummy').build()
+		config = config_builder.read_from(base_from_test_dir).generate_at('/dummy').download_cover_art(False).build()
 
 		flowconductor_actor = actorstestutils.TestActorBuilder().with_factory(factory.FlowConductorSupervisorFactory(config))\
 															.with_id('flowconductor-test-actor')\

longtang/config/configuration.py

 		self.__generate_at=None
 		self.__override_tags=None
 		self.__offline_mode=None
+		self.__download_cover_art=None
+
+	@property
+	def download_cover_art(self):
+		return self.__download_cover_art
+
+	@download_cover_art.setter
+	def download_cover_art(self,value):
+		self.__download_cover_art=value
 
 	@property
 	def read_from(self):
 		self.__generate_at=None
 		self.__override_tags=False
 		self.__offline_mode=False
+		self.__download_cover_art=True
+
+	def download_cover_art(self, enabled):
+		self.__download_cover_art=enabled
+		return self
 
 	def read_from(self, path):
 		self.__read_from=path
 		config.generate_at=self.__generate_at
 		config.override_tags=self.__override_tags
 		config.offline_mode=self.__offline_mode
+		config.download_cover_art=self.__download_cover_art
 
 		return config