diff --git a/data/interfaces/default/album.html b/data/interfaces/default/album.html index 2308f32b..da287746 100644 --- a/data/interfaces/default/album.html +++ b/data/interfaces/default/album.html @@ -10,7 +10,8 @@ %if album['Status'] == 'Skipped':
  • Mark Album as Wanted
  • %elif album['Status'] == 'Wanted': -
  • Mark Album as Skipped
  • +
  • Force Check
  • +
  • Mark Album as Skipped
  • %else:
  • Retry Download
  • Try New Version
  • diff --git a/data/interfaces/remix/album.html b/data/interfaces/remix/album.html index 2308f32b..da287746 100644 --- a/data/interfaces/remix/album.html +++ b/data/interfaces/remix/album.html @@ -10,7 +10,8 @@ %if album['Status'] == 'Skipped':
  • Mark Album as Wanted
  • %elif album['Status'] == 'Wanted': -
  • Mark Album as Skipped
  • +
  • Force Check
  • +
  • Mark Album as Skipped
  • %else:
  • Retry Download
  • Try New Version
  • diff --git a/headphones/importer.py b/headphones/importer.py index d0841bfc..11dc15d2 100644 --- a/headphones/importer.py +++ b/headphones/importer.py @@ -37,20 +37,23 @@ def scanMusic(dir=None): for song in results: try: f = MediaFile(song) - albumartist = f.albumartist - artist = f.artist except: logger.warn('Could not read file: %s' % song) continue else: - if albumartist and albumartist != 'Various Artists': - artist = albumartist - elif artist: - pass + if f.albumartist: + artist = f.albumartist + elif f.artist: + artist = f.artist else: continue - myDB.action('INSERT INTO have VALUES( ?, ?, ?, ?, ?, ?, ?, ?, ?)', [artist, f.album, f.track, f.title, f.length, f.bitrate, f.genre, f.date, f.mb_trackid]) + if not f.album: + album = None + else: + album = f.album + + myDB.action('INSERT INTO have VALUES( ?, ?, ?, ?, ?, ?, ?, ?, ?)', [artist, album, f.track, f.title, f.length, f.bitrate, f.genre, f.date, f.mb_trackid]) # Get the average bitrate if the option is selected if headphones.DETECT_BITRATE: diff --git a/headphones/logger.py b/headphones/logger.py index 93c77c57..9df46990 100644 --- a/headphones/logger.py +++ b/headphones/logger.py @@ -60,7 +60,7 @@ class RotatingLogger(object): logger.debug(message) elif level == 'INFO': logger.info(message) - elif level == 'WARN': + elif level == 'WARNING': logger.warn(message) else: logger.error(message) @@ -74,7 +74,7 @@ def info(message): headphones_log.log(message, level='INFO') def warn(message): - headphones_log.log(message, level='WARN') + headphones_log.log(message, level='WARNING') def error(message): headphones_log.log(message, level='ERROR') diff --git a/headphones/mb.py b/headphones/mb.py index 1bf35308..2646403b 100644 --- a/headphones/mb.py +++ b/headphones/mb.py @@ -51,7 +51,14 @@ def findArtist(name, limit=1): artistdict = findArtistbyAlbum(name) if not artistdict: - return False + logger.debug('Cannot determine the best match from an artist/album search. Using top match instead') + artistlist.append({ + 'name': result.artist.name, + 'uniquename': result.artist.getUniqueName(), + 'id': u.extractUuid(result.artist.id), + 'url': result.artist.id, + 'score': result.score + }) else: artistlist.append(artistdict) @@ -393,7 +400,14 @@ def findArtistbyAlbum(name): myDB = db.DBConnection() - artist = myDB.action('SELECT AlbumTitle from have WHERE ArtistName=?', [name]).fetchone() + artist = myDB.action('SELECT AlbumTitle from have WHERE ArtistName=? AND AlbumTitle IS NOT NULL ORDER BY RANDOM()', [name]).fetchone() + + if not artist: + return False + + # Probably not neccessary but just want to double check + if not artist['AlbumTitle']: + return False term = '"'+artist['AlbumTitle']+'" AND artist:"'+name+'"' diff --git a/headphones/postprocessor.py b/headphones/postprocessor.py index 2b1f87c9..75cb124c 100644 --- a/headphones/postprocessor.py +++ b/headphones/postprocessor.py @@ -22,6 +22,7 @@ def checkFolder(): album_path = os.path.join(headphones.DOWNLOAD_DIR, album['FolderName']) if os.path.exists(album_path): + logger.debug('Found %s. Verifying....' % album['FolderName']) verify(album['AlbumID'], album_path) def verify(albumid, albumpath): @@ -118,28 +119,48 @@ def verify(albumid, albumpath): downloaded_track_list.append(os.path.join(r, files)) # test #1: metadata - usually works + logger.debug('Verifying metadata...') + for downloaded_track in downloaded_track_list: try: f = MediaFile(downloaded_track) except: continue - if helpers.latinToAscii(f.artist.lower()).encode('UTF-8') == helpers.latinToAscii(release['ArtistName'].lower()).encode('UTF-8') and helpers.latinToAscii(f.album.lower()).encode('UTF-8') == helpers.latinToAscii(release['AlbumTitle'].lower()).encode('UTF-8'): + + metaartist = helpers.latinToAscii(f.artist.lower()).encode('UTF-8') + dbartist = helpers.latinToAscii(release['ArtistName'].lower()).encode('UTF-8') + metaalbum = helpers.latinToAscii(f.album.lower()).encode('UTF-8') + dbalbum = helpers.latinToAscii(release['AlbumTitle'].lower()).encode('UTF-8') + + logger.debug('Matching metadata artist: %s with artist name: %s' % (metaartist, dbartist)) + logger.debug('Matching metadata album: %s with album name: %s' % (metaalbum, dbalbum)) + + if metaartist == dbartist and metaalbum == dbalbum: doPostProcessing(albumid, albumpath, release, tracks, downloaded_track_list) return # test #2: filenames + logger.debug('Metadata check failed. Verifying filenames...') for downloaded_track in downloaded_track_list: track_name = os.path.splitext(downloaded_track)[0] split_track_name = re.sub('[\.\-\_]', ' ', track_name).lower() for track in tracks: - if helpers.latinToAscii(track['TrackTitle'].lower()).encode('UTF-8') in helpers.latinToAscii(split_track_name).encode('UTF-8'): + + dbtrack = helpers.latinToAscii(track['TrackTitle'].lower()).encode('UTF-8') + filetrack = helpers.latinToAscii(split_track_name).encode('UTF-8') + logger.debug('Checking if track title: %s is in file name: %s' % (dbtrack, filetrack)) + + if dbtrack in filetrack: doPostProcessing(albumid, albumpath, release, tracks, downloaded_track_list) return # test #3: number of songs and duration + logger.debug('Filename check failed. Verifying album length...') db_track_duration = 0 downloaded_track_duration = 0 + logger.debug('Total music files in %s: %i' % (albumpath, len(downloaded_track_list))) + logger.debug('Total tracks for this album in the database: %i' % len(tracks)) if len(tracks) == len(downloaded_track_list): for track in tracks: @@ -156,8 +177,10 @@ def verify(albumid, albumpath): except: downloaded_track_duration = False break - + if downloaded_track_duration and db_track_duration: + logger.debug('Downloaded album duration: %i' % downloaded_track_duration) + logger.debug('Database track duration: %i' % db_track_duration) delta = abs(downloaded_track_duration - db_track_duration) if delta < 240: doPostProcessing(albumid, albumpath, release, tracks, downloaded_track_list) diff --git a/headphones/searcher.py b/headphones/searcher.py index c83f975d..42807109 100644 --- a/headphones/searcher.py +++ b/headphones/searcher.py @@ -437,17 +437,17 @@ def verifyresult(title, artistterm, term): title = re.sub('[\.\-\/\_]', ' ', title) - if artistterm != 'Various Artists': - - if not re.search('^' + re.escape(artistterm), title, re.IGNORECASE): - logger.info("Removed from results: " + title + " (artist not at string start).") - return False - elif re.search(re.escape(artistterm) + '\w', title, re.IGNORECASE | re.UNICODE): - logger.info("Removed from results: " + title + " (post substring result).") - return False - elif re.search('\w' + re.escape(artistterm), title, re.IGNORECASE | re.UNICODE): - logger.info("Removed from results: " + title + " (pre substring result).") - return False + #if artistterm != 'Various Artists': + # + # if not re.search('^' + re.escape(artistterm), title, re.IGNORECASE): + # #logger.info("Removed from results: " + title + " (artist not at string start).") + # #return False + # elif re.search(re.escape(artistterm) + '\w', title, re.IGNORECASE | re.UNICODE): + # logger.info("Removed from results: " + title + " (post substring result).") + # return False + # elif re.search('\w' + re.escape(artistterm), title, re.IGNORECASE | re.UNICODE): + # logger.info("Removed from results: " + title + " (pre substring result).") + # return False #another attempt to weed out substrings. We don't want "Vol III" when we were looking for "Vol II" tokens = re.split('\W', term, re.IGNORECASE | re.UNICODE) diff --git a/lib/beets/autotag/__init__.py b/lib/beets/autotag/__init__.py index fb3c6de4..43d72d1f 100644 --- a/lib/beets/autotag/__init__.py +++ b/lib/beets/autotag/__init__.py @@ -378,8 +378,8 @@ def apply_metadata(items, info): # Compilation flag. item.comp = info['va'] - item.comments = 'tagged by headphones/beets' - + item.comments = 'tagged by headphones/beets' + def match_by_id(items): """If the items are tagged with a MusicBrainz album ID, returns an info dict for the corresponding album. Otherwise, returns None. diff --git a/lib/beets/library.py b/lib/beets/library.py index 213d42dd..3ebc0c1d 100644 --- a/lib/beets/library.py +++ b/lib/beets/library.py @@ -204,7 +204,8 @@ class Item(object): """ f = MediaFile(syspath(self.path)) for key in ITEM_KEYS_WRITABLE: - setattr(f, key, getattr(self, key)) + if getattr(self, key): #make sure it has a value before we set it and create blank tags with wrong types + setattr(f, key, getattr(self, key)) f.save()