From 4983852b076ebcf6f8e54c205f8a289a2cbbb293 Mon Sep 17 00:00:00 2001 From: Remy Date: Mon, 15 Aug 2011 19:54:11 -0700 Subject: [PATCH] Moved everything over to the new library scan - needs cleanup --- data/css/style.css | 12 ++- data/interfaces/default/album.html | 27 +++++ data/interfaces/default/artist.html | 19 +++- data/interfaces/default/history.html | 2 +- headphones/__init__.py | 29 +++++- headphones/helpers.py | 7 ++ headphones/importer.py | 142 +++++++++------------------ headphones/librarysync.py | 116 ++++++++++++---------- 8 files changed, 188 insertions(+), 166 deletions(-) diff --git a/data/css/style.css b/data/css/style.css index b7023a7f..2d3fb458 100755 --- a/data/css/style.css +++ b/data/css/style.css @@ -157,19 +157,21 @@ div#paddingheader { padding-top: 48px; font-size: 24px; font-weight: bold; text- div#nopaddingheader { font-size: 24px; font-weight: bold; text-align: center; } table#album_table { background-color: white; } -table#album_table th#select { vertical-align: middle; text-align: left; min-width: 25px; } +table#album_table th#select { vertical-align: middle; text-align: left; min-width: 10px; } table#album_table th#albumart { text-align: left; min-width: 50px; } table#album_table th#albumname { text-align: center; min-width: 150px; } -table#album_table th#reldate { width: 175px; text-align: center; min-width: 100px; } -table#album_table th#status { width: 175px; text-align: center; min-width: 100px; } +table#album_table th#reldate { width: 175px; text-align: center; min-width: 70px; } +table#album_table th#status { width: 175px; text-align: center; min-width: 80px; } table#album_table th#type { width: 175px; text-align: center; min-width: 100px; } +table#album_table th#bitrate { text-align: center; min-width: 60px; } table#album_table td#select { vertical-align: middle; text-align: left; } table#album_table td#albumart { vertical-align: middle; text-align: left; } table#album_table td#albumname { vertical-align: middle; text-align: center; } table#album_table td#reldate { vertical-align: middle; text-align: center; } -table#album_table td#status { vertical-align: middle; text-align: center; } +table#album_table td#status { vertical-align: middle; text-align: center; font-size: 13px; } table#album_table td#type { vertical-align: middle; text-align: center; } table#album_table td#have { vertical-align: middle; } +table#album_table td#bitrate { vertical-align: middle; text-align: center; font-size: 13px; } img.albumArt { float: left; padding-right: 5px; } div#albumheader { padding-top: 48px; height: 200px; } @@ -185,7 +187,7 @@ table#track_table td#number { vertical-align: middle; text-align: right; } table#track_table td#name { vertical-align: middle; text-align: center; } table#track_table td#duration { vertical-align: middle; text-align: center; } table#track_table td#location { vertical-align: middle; text-align: center; font-size: 11px; } -table#track_table td#location { vertical-align: middle; text-align: center; } +table#track_table td#bitrate { vertical-align: middle; text-align: center; font-size: 12px; } table#history_table { background-color: white; width: 100%; } diff --git a/data/interfaces/default/album.html b/data/interfaces/default/album.html index 355dd9b3..073a77e7 100644 --- a/data/interfaces/default/album.html +++ b/data/interfaces/default/album.html @@ -85,6 +85,33 @@ %endfor + <% + unmatched = myDB.select('SELECT * from have WHERE ArtistName LIKE ? AND AlbumTitle LIKE ?', [album['ArtistName'], album['AlbumTitle']]) + %> + %if unmatched: + + + + + + + + + + + + %for track in unmatched: + + + + + + + + %endfor + +
#Track TitleDurationLocal FileBit Rate
${track['TrackNumber']}${track['TrackTitle']}${track['TrackLength']}${track['Location']}${track['BitRate']}
+ %endif diff --git a/data/interfaces/default/artist.html b/data/interfaces/default/artist.html index 4b296eda..0438ac4c 100644 --- a/data/interfaces/default/artist.html +++ b/data/interfaces/default/artist.html @@ -41,11 +41,12 @@ - Album Name - Release Date - Release Type + Name + Date + Type Status Have + Bitrate @@ -62,7 +63,7 @@ myDB = db.DBConnection() totaltracks = len(myDB.select('SELECT TrackTitle from tracks WHERE AlbumID=?', [album['AlbumID']])) - havetracks = len(myDB.select('SELECT TrackTitle from have WHERE ArtistName like ? AND AlbumTitle like ?', [album['ArtistName'], album['AlbumTitle']])) + havetracks = len(myDB.select('SELECT TrackTitle from tracks WHERE AlbumID=? AND Location IS NOT NULL', [album['AlbumID']])) try: percent = (havetracks*100.0)/totaltracks @@ -71,6 +72,12 @@ except (ZeroDivisionError, TypeError): percent = 0 totaltracks = '?' + + avgbitrate = myDB.action("SELECT AVG(BitRate) FROM tracks WHERE AlbumID=?", [album['AlbumID']]).fetchone()[0] + if avgbitrate: + bitrate = str(int(avgbitrate)/1000) + ' kbps' + else: + bitrate = '' %> @@ -89,6 +96,7 @@ %endif
${havetracks}/${totaltracks}
+ ${bitrate} %endfor @@ -114,7 +122,8 @@ null, null, null, - { "sType": "title-numeric"} + { "sType": "title-numeric"}, + null ], "oLanguage": { "sLengthMenu":"Show _MENU_ albums per page", diff --git a/data/interfaces/default/history.html b/data/interfaces/default/history.html index b79a43af..8c98db9d 100644 --- a/data/interfaces/default/history.html +++ b/data/interfaces/default/history.html @@ -42,7 +42,7 @@ %> ${item['DateAdded']} - ${item['Title']} + ${item['Title']} [album page] ${helpers.bytes_to_mb(item['Size'])} ${item['Status']} [retry][new] diff --git a/headphones/__init__.py b/headphones/__init__.py index 1454fb79..335768d1 100644 --- a/headphones/__init__.py +++ b/headphones/__init__.py @@ -62,6 +62,8 @@ PATH_TO_XML = None PREFERRED_QUALITY = None PREFERRED_BITRATE = None DETECT_BITRATE = False +ADD_ARTISTS = False +NEW_ARTISTS = None CORRECT_METADATA = False MOVE_FILES = False RENAME_FILES = False @@ -160,7 +162,7 @@ def initialize(): global __INITIALIZED__, FULL_PATH, PROG_DIR, QUIET, DAEMON, DATA_DIR, CONFIG_FILE, CFG, LOG_DIR, CACHE_DIR, \ HTTP_PORT, HTTP_HOST, HTTP_USERNAME, HTTP_PASSWORD, HTTP_ROOT, LAUNCH_BROWSER, GIT_PATH, \ CURRENT_VERSION, LATEST_VERSION, MUSIC_DIR, DESTINATION_DIR, PREFERRED_QUALITY, PREFERRED_BITRATE, DETECT_BITRATE, \ - CORRECT_METADATA, MOVE_FILES, RENAME_FILES, FOLDER_FORMAT, FILE_FORMAT, CLEANUP_FILES, INCLUDE_EXTRAS, \ + ADD_ARTISTS, CORRECT_METADATA, MOVE_FILES, RENAME_FILES, FOLDER_FORMAT, FILE_FORMAT, CLEANUP_FILES, INCLUDE_EXTRAS, \ ADD_ALBUM_ART, EMBED_ALBUM_ART, DOWNLOAD_DIR, BLACKHOLE, BLACKHOLE_DIR, USENET_RETENTION, NZB_SEARCH_INTERVAL, \ LIBRARYSCAN_INTERVAL, DOWNLOAD_SCAN_INTERVAL, SAB_HOST, SAB_USERNAME, SAB_PASSWORD, SAB_APIKEY, SAB_CATEGORY, \ NZBMATRIX, NZBMATRIX_USERNAME, NZBMATRIX_APIKEY, NEWZNAB, NEWZNAB_HOST, NEWZNAB_APIKEY, \ @@ -199,6 +201,7 @@ def initialize(): PREFERRED_QUALITY = check_setting_int(CFG, 'General', 'preferred_quality', 0) PREFERRED_BITRATE = check_setting_int(CFG, 'General', 'preferred_bitrate', '') DETECT_BITRATE = bool(check_setting_int(CFG, 'General', 'detect_bitrate', 0)) + ADD_ARTISTS = bool(check_setting_int(CFG, 'General', 'add_artists', 1)) CORRECT_METADATA = bool(check_setting_int(CFG, 'General', 'correct_metadata', 0)) MOVE_FILES = bool(check_setting_int(CFG, 'General', 'move_files', 0)) RENAME_FILES = bool(check_setting_int(CFG, 'General', 'rename_files', 0)) @@ -363,6 +366,7 @@ def config_write(): new_config['General']['preferred_quality'] = PREFERRED_QUALITY new_config['General']['preferred_bitrate'] = PREFERRED_BITRATE new_config['General']['detect_bitrate'] = int(DETECT_BITRATE) + new_config['General']['add_artists'] = int(ADD_ARTISTS) new_config['General']['correct_metadata'] = int(CORRECT_METADATA) new_config['General']['move_files'] = int(MOVE_FILES) new_config['General']['rename_files'] = int(RENAME_FILES) @@ -425,10 +429,10 @@ def start(): SCHED.add_cron_job(updater.dbUpdate, hour=4, minute=0, second=0) SCHED.add_interval_job(searcher.searchNZB, minutes=NZB_SEARCH_INTERVAL) - SCHED.add_interval_job(importer.scanMusic, minutes=LIBRARYSCAN_INTERVAL) + SCHED.add_interval_job(librarysync.libraryScan(), minutes=LIBRARYSCAN_INTERVAL) SCHED.add_interval_job(versioncheck.checkGithub, minutes=300) SCHED.add_interval_job(postprocessor.checkFolder, minutes=DOWNLOAD_SCAN_INTERVAL) - + librarysync.libraryScan() SCHED.start() started = True @@ -439,9 +443,9 @@ def dbcheck(): c=conn.cursor() c.execute('CREATE TABLE IF NOT EXISTS artists (ArtistID TEXT UNIQUE, ArtistName TEXT, ArtistSortName TEXT, DateAdded TEXT, Status TEXT, IncludeExtras INTEGER, LatestAlbum TEXT, ReleaseDate TEXT, AlbumID TEXT, HaveTracks INTEGER, TotalTracks INTEGER)') c.execute('CREATE TABLE IF NOT EXISTS albums (ArtistID TEXT, ArtistName TEXT, AlbumTitle TEXT, AlbumASIN TEXT, ReleaseDate TEXT, DateAdded TEXT, AlbumID TEXT UNIQUE, Status TEXT, Type TEXT)') - c.execute('CREATE TABLE IF NOT EXISTS tracks (ArtistID TEXT, ArtistName TEXT, AlbumTitle TEXT, AlbumASIN TEXT, AlbumID TEXT, TrackTitle TEXT, TrackDuration, TrackID TEXT, TrackNumber INTEGER, Location TEXT, BitRate INTEGER)') + c.execute('CREATE TABLE IF NOT EXISTS tracks (ArtistID TEXT, ArtistName TEXT, AlbumTitle TEXT, AlbumASIN TEXT, AlbumID TEXT, TrackTitle TEXT, TrackDuration, TrackID TEXT, TrackNumber INTEGER, Location TEXT, BitRate INTEGER, CleanName TEXT)') c.execute('CREATE TABLE IF NOT EXISTS snatched (AlbumID TEXT, Title TEXT, Size INTEGER, URL TEXT, DateAdded TEXT, Status TEXT, FolderName TEXT)') - c.execute('CREATE TABLE IF NOT EXISTS have (ArtistName TEXT, AlbumTitle TEXT, TrackNumber TEXT, TrackTitle TEXT, TrackLength TEXT, BitRate TEXT, Genre TEXT, Date TEXT, TrackID TEXT)') + c.execute('CREATE TABLE IF NOT EXISTS have (ArtistName TEXT, AlbumTitle TEXT, TrackNumber TEXT, TrackTitle TEXT, TrackLength TEXT, BitRate TEXT, Genre TEXT, Date TEXT, TrackID TEXT, Location TEXT, CleanName TEXT)') c.execute('CREATE TABLE IF NOT EXISTS lastfmcloud (ArtistName TEXT, ArtistID TEXT, Count INTEGER)') c.execute('CREATE TABLE IF NOT EXISTS descriptions (ReleaseGroupID TEXT, ReleaseID TEXT, Summary TEXT, Content TEXT)') c.execute('CREATE TABLE IF NOT EXISTS releases (ReleaseID TEXT, ReleaseGroupID TEXT, UNIQUE(ReleaseID, ReleaseGroupID))') @@ -495,11 +499,26 @@ def dbcheck(): c.execute('SELECT Location from tracks') except sqlite3.OperationalError: c.execute('ALTER TABLE tracks ADD COLUMN Location TEXT') + + try: + c.execute('SELECT Location from have') + except sqlite3.OperationalError: + c.execute('ALTER TABLE have ADD COLUMN Location TEXT') try: c.execute('SELECT BitRate from tracks') except sqlite3.OperationalError: c.execute('ALTER TABLE tracks ADD COLUMN BitRate INTEGER') + + try: + c.execute('SELECT CleanName from tracks') + except sqlite3.OperationalError: + c.execute('ALTER TABLE tracks ADD COLUMN CleanName TEXT') + + try: + c.execute('SELECT CleanName from have') + except sqlite3.OperationalError: + c.execute('ALTER TABLE have ADD COLUMN CleanName TEXT') conn.commit() c.close() diff --git a/headphones/helpers.py b/headphones/helpers.py index c3246542..568bb0f7 100644 --- a/headphones/helpers.py +++ b/headphones/helpers.py @@ -104,6 +104,13 @@ def replace_all(text, dic): text = text.replace(i, j) return text +def cleanName(string): + + pass1 = latinToAscii(string).lower() + out_string = re.sub('[\.\-\/\!\@\#\$\%\^\&\*\(\)\+\-\"\'\,\;\:\[\]\{\}\<\>\=\_]', '', pass1).encode('utf-8') + + return out_string + def extract_data(s): from headphones import logger diff --git a/headphones/importer.py b/headphones/importer.py index 11dc15d2..70f5701c 100644 --- a/headphones/importer.py +++ b/headphones/importer.py @@ -7,89 +7,6 @@ import headphones from headphones import logger, helpers, db, mb, albumart, lastfm various_artists_mbid = '89ad4ac3-39f7-470e-963a-56509c546377' - -def scanMusic(dir=None): - - if not dir: - dir = headphones.MUSIC_DIR - - try: - dir = str(dir) - except UnicodeEncodeError: - dir = unicode(dir).encode('unicode_escape') - - logger.info('Starting Music Scan with directory: %s' % dir) - - results = [] - - for r,d,f in os.walk(dir): - for files in f: - if any(files.endswith('.' + x) for x in headphones.MEDIA_FORMATS): - results.append(os.path.join(r, files)) - - logger.info(u'%i music files found. Reading metadata....' % len(results)) - - if results: - - myDB = db.DBConnection() - myDB.action('''DELETE from have''') - - for song in results: - try: - f = MediaFile(song) - except: - logger.warn('Could not read file: %s' % song) - continue - else: - if f.albumartist: - artist = f.albumartist - elif f.artist: - artist = f.artist - else: - continue - - 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: - try: - avgbitrate = myDB.action("SELECT AVG(BitRate) FROM have").fetchone()[0] - headphones.PREFERRED_BITRATE = int(avgbitrate)/1000 - - except Exception, e: - logger.error('Error detecting preferred bitrate:' + str(e)) - - artistlist = myDB.action('SELECT DISTINCT ArtistName FROM have').fetchall() - logger.info(u"Preparing to import %i artists" % len(artistlist)) - - artistlist_to_mbids(artistlist) - -def itunesImport(pathtoxml): - - if os.path.splitext(pathtoxml)[1] == '.xml': - logger.info(u"Loading xml file from"+ pathtoxml) - pl = XMLLibraryParser(pathtoxml) - l = Library(pl.dictionary) - lst = [] - for song in l.songs: - lst.append(song.artist) - rawlist = {}.fromkeys(lst).keys() - artistlist = [f for f in rawlist if f != None] - - else: - rawlist = os.listdir(pathtoxml) - logger.info(u"Loading artists from directory:" +pathtoxml) - exclude = ['.ds_store', 'various artists', 'untitled folder', 'va'] - artistlist = [f for f in rawlist if f.lower() not in exclude] - - logger.info('Starting directory/xml import...') - artistlist_to_mbids(artistlist) - def is_exists(artistid): @@ -109,7 +26,7 @@ def artistlist_to_mbids(artistlist): for artist in artistlist: - results = mb.findArtist(artist['ArtistName'], limit=1) + results = mb.findArtist(artist, limit=1) if not results: continue @@ -124,16 +41,12 @@ def artistlist_to_mbids(artistlist): # Add to database if it doesn't exist if artistid != various_artists_mbid and not is_exists(artistid): addArtisttoDB(artistid) - - # Update track count regardless of whether it already exists - if artistid != various_artists_mbid: - + + # Just update the tracks if it does + else: myDB = db.DBConnection() - havetracks = len(myDB.select('SELECT TrackTitle from have WHERE ArtistName like ?', [artist['ArtistName']])) - - controlValueDict = {"ArtistID": artistid} - newValueDict = {"HaveTracks": havetracks} - myDB.upsert("artists", newValueDict, controlValueDict) + havetracks = len(myDB.select('SELECT TrackTitle from tracks WHERE ArtistID=?', [artistid])) + len(myDB.select('SELECT TrackTitle from have WHERE ArtistName like ?', [artist['ArtistName']])) + myDB.action('UPDATE artists SET HaveTracks=? WHERE ArtistID=?', [havetracks, artistid]) # Update the similar artist tag cloud: logger.info('Updating artist information from Last.fm') @@ -231,6 +144,8 @@ def addArtisttoDB(artistid, extrasonly=False): myDB.action('DELETE from tracks WHERE AlbumID=?', [rg['id']]) for track in release_dict['tracks']: + cleanname = helpers.cleanName(artist['artist_name'] + ' ' + rg['title'] + ' ' + track['title']) + controlValueDict = {"TrackID": track['id'], "AlbumID": rg['id']} newValueDict = {"ArtistID": artistid, @@ -239,14 +154,29 @@ def addArtisttoDB(artistid, extrasonly=False): "AlbumASIN": release_dict['asin'], "TrackTitle": track['title'], "TrackDuration": track['duration'], - "TrackNumber": track['number'] + "TrackNumber": track['number'], + "CleanName": cleanname } - + + location = myDB.action('SELECT Location, BitRate from have WHERE TrackID=?', [track['id']]).fetchone() + + if not location: + location = myDB.action('SELECT Location, BitRate from have WHERE CleanName=?', [cleanname]).fetchone() + + if not location: + location = myDB.action('SELECT Location, BitRate from have WHERE ArtistName LIKE ? AND AlbumTitle LIKE ? AND TrackTitle LIKE ?', [artist['artist_name'], rg['title'], track['title']]).fetchone() + + if location: + newValueDict['Location'] = location['Location'] + newValueDict['BitRate'] = location['BitRate'] + myDB.action('DELETE from have WHERE Location=?', [location['location']]) + myDB.upsert("tracks", newValueDict, controlValueDict) latestalbum = myDB.action('SELECT AlbumTitle, ReleaseDate, AlbumID from albums WHERE ArtistID=? order by ReleaseDate DESC', [artistid]).fetchone() totaltracks = len(myDB.select('SELECT TrackTitle from tracks WHERE ArtistID=?', [artistid])) - + havetracks = len(myDB.select('SELECT TrackTitle from tracks WHERE ArtistID=? AND Location IS NOT NULL', [artistid])) + len(myDB.select('SELECT TrackTitle from have WHERE ArtistName like ?', [artist['artist_name']])) + controlValueDict = {"ArtistID": artistid} if latestalbum: @@ -254,7 +184,8 @@ def addArtisttoDB(artistid, extrasonly=False): "LatestAlbum": latestalbum['AlbumTitle'], "ReleaseDate": latestalbum['ReleaseDate'], "AlbumID": latestalbum['AlbumID'], - "TotalTracks": totaltracks} + "TotalTracks": totaltracks, + "HaveTracks": havetracks} else: newValueDict = {"Status": "Active"} @@ -339,6 +270,8 @@ def addReleaseById(rid): for track in release_dict['tracks']: + cleanname = helpers.cleanName(release_dict['artist_name'] + ' ' + release_dict['rg_title'] + ' ' + track['title']) + controlValueDict = {"TrackID": track['id'], "AlbumID": rgid} newValueDict = {"ArtistID": release_dict['artist_id'], @@ -347,8 +280,21 @@ def addReleaseById(rid): "AlbumASIN": release_dict['asin'], "TrackTitle": track['title'], "TrackDuration": track['duration'], - "TrackNumber": track['number'] + "TrackNumber": track['number'], + "CleanName": cleanname } + + location = myDB.action('SELECT Location, BitRate from have WHERE TrackID=?', [track['id']]).fetchone() + + if not location: + location = myDB.action('SELECT Location, BitRate from have WHERE CleanName=?', [cleanname]).fetchone() + + if not location: + location = myDB.action('SELECT Location, BitRate from have WHERE ArtistName LIKE ? AND AlbumTitle LIKE ? AND TrackTitle LIKE ?', [release_dict['artist_name'], release_dict['rg_title'], track['title']]).fetchone() + + if location: + newValueDict['Location'] = location['Location'] + newValueDict['BitRate'] = location['BitRate'] myDB.upsert("tracks", newValueDict, controlValueDict) diff --git a/headphones/librarysync.py b/headphones/librarysync.py index 8a093b04..d5d7f742 100644 --- a/headphones/librarysync.py +++ b/headphones/librarysync.py @@ -4,17 +4,18 @@ import glob from lib.beets.mediafile import MediaFile import headphones -from headphones import db, logger +from headphones import db, logger, helpers, importer -def LibraryScan(): +def libraryScan(): if not headphones.MUSIC_DIR: return - unmatched_files = [] new_artists = [] + bitrates = [] myDB = db.DBConnection() + myDB.action('''DELETE from have''') for r,d,f in os.walk(headphones.MUSIC_DIR): for files in f: @@ -22,63 +23,58 @@ def LibraryScan(): if any(files.endswith('.' + x) for x in headphones.MEDIA_FORMATS): file = unicode(os.path.join(r, files), "utf-8") - print repr(file) + # Try to read the metadata try: f = MediaFile(file) except: logger.error('Cannot read file: ' + file) - continue + continue + + # Grab the bitrates for the auto detect bit rate option + if f.bitrate: + bitrates.append(f.bitrate) - # Try to match on metadata first, + # Try to match on metadata first, starting with the track id if f.mb_trackid: - print 'has track id:' + repr(f.mb_trackid) + # Wondering if theres a better way to do this -> do one thing if the row exists, # do something else if it doesn't track = myDB.action('SELECT TrackID from tracks WHERE TrackID=?', [f.mb_trackid]).fetchone() - if not track: - if f.albumartist: - new_artists.append(f.albumartist) - elif f.artist: - new_artists.append(f.artist) - else: - unmatched_files.append(file) - - else: + if track: myDB.action('UPDATE tracks SET Location=?, BitRate=? WHERE TrackID=?', [file, f.bitrate, track['TrackID']]) continue - elif f.albumartist and f.album and f.title: - - track = myDB.action('SELECT TrackID from tracks WHERE ArtistName LIKE ? AND AlbumTitle LIKE ? AND TrackTitle LIKE ?', [f.albumartist, f.album, f.title]).fetchone() - - if not track: - new_artists.append(f.albumartist) - - else: - myDB.action('UPDATE tracks SET Location=?, BitRate=? WHERE TrackID=?', [file, f.bitrate, track['TrackID']]) - - elif f.artist and f.album and f.title: - - track = myDB.action('SELECT TrackID from tracks WHERE ArtistName LIKE ? AND AlbumTitle LIKE ? AND TrackTitle LIKE ?', [f.artist, f.album, f.title]).fetchone() - - if not track: - new_artists.append(file) - else: - myDB.action('UPDATE tracks SET Location=?, BitRate=? WHERE TrackID=?', [file, f.bitrate, track['TrackID']]) - + # Try to find a match based on artist/album/tracktitle + if f.albumartist: + f_artist = f.albumartist + elif f.artist: + f_artist = f.artist else: continue + + if f_artist and f.album and f.title: + + track = myDB.action('SELECT TrackID from tracks WHERE CleanName LIKE ?', [helpers.cleanName(f_artist +' '+f.album+' '+f.title)]).fetchone() + + if not track: + track = myDB.action('SELECT TrackID from tracks WHERE ArtistName LIKE ? AND AlbumTitle LIKE ? AND TrackTitle LIKE ?', [f_artist, f.album, f.title]).fetchone() - # Try to parse the unmatched files based on the folder & file formats in the config - for file in unmatched_files: - # Will do later - pass + if track: + myDB.action('UPDATE tracks SET Location=?, BitRate=? WHERE TrackID=?', [file, f.bitrate, track['TrackID']]) + continue + + # if we can't find a match in the database on a track level, it might be a new artist or it might be on a non-mb release + new_artists.append(f_artist) + + # The have table will become the new database for unmatched tracks (i.e. tracks with no associated links in the database + myDB.action('INSERT INTO have VALUES( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', [f_artist, f.album, f.track, f.title, f.length, f.bitrate, f.genre, f.date, f.mb_trackid, file, helpers.cleanName(f_artist+' '+f.album+' '+f.title)]) # Now check empty file paths to see if we can find a match based on their folder format - tracks = myDB.select('SELECT * from tracks WHERE Location=NULL') + tracks = myDB.select('SELECT * from tracks WHERE Location IS NULL') for track in tracks: + release = myDB.action('SELECT * from albums WHERE AlbumID=?', [track['AlbumID']]).fetchone() try: @@ -129,32 +125,48 @@ def LibraryScan(): new_file_name = new_file_name.replace('?','_').replace(':', '_') - full_path_to_file = os.path.join(headphones.MUSIC_DIR, folder, new_file_name) + full_path_to_file = os.path.normpath(os.path.join(headphones.MUSIC_DIR, folder, new_file_name)) + + match = glob.glob(full_path_to_file) - print 'Full path to file is: ' + repr(full_path_to_file) - - if glob.glob(full_path_to_file): - myDB.action('UPDATE tracks SET Location=? WHERE TrackID=?', [full_path_to_file, track['TrackID']]) + if match: + + myDB.action('UPDATE tracks SET Location=? WHERE TrackID=?', [match[0], track['TrackID']]) # Try to insert the appropriate track id so we don't have to keep doing this try: - f = MediaFile(full_path_to_file) + f = MediaFile(match[0]) f.mb_trackid = track['TrackID'] myDB.action('UPDATE tracks SET BitRate=? WHERE TrackID=?', [f.bitrate, track['TrackID']]) f.save() + logger.info('Wrote mbid to track: %s' % match[0]) except: - logger.error('Error embedding track id into: %s' % full_path_to_file) + logger.error('Error embedding track id into: %s' % match[0]) - # Lastly, clean up any old paths that don't exist + # Clean up bad filepaths tracks = myDB.select('SELECT Location, TrackID from tracks WHERE Location IS NOT NULL') + for track in tracks: if not os.path.isfile(track['Location']): myDB.action('UPDATE tracks SET Location=? WHERE TrackID=?', [None, track['TrackID']]) - + # Clean up the new artist list unique_artists = {}.fromkeys(new_artists).keys() - current_artists = myDB.action('SELECT ArtistName from artists').fetchall() + current_artists = myDB.select('SELECT ArtistName from artists') - artist_list = [f for f in unique_artists if f not in current_artists] + artist_list = [f for f in unique_artists if f.lower() not in [x[0].lower() for x in current_artists]] - logger.info('Found %i artists to import: ' % len(artist_list)) \ No newline at end of file + logger.info('Found %i new artists to import.' % len(artist_list)) + + # Update track counts + for artist in current_artists: + havetracks = len(myDB.select('SELECT TrackTitle from tracks WHERE ArtistID like ?', [artist['ArtistID']])) + len(myDB.select('SELECT TrackTitle from have WHERE ArtistName like ?', [artist['ArtistName']])) + myDB.action('UPDATE artists SET HaveTracks=? WHERE ArtistID=?', [havetracks, artist['ArtistID']]) + + if headphones.ADD_ARTISTS: + importer.artistlist_to_mbids(artist_list) + else: + headphones.NEW_ARTISTS = artist_list + + if headphones.DETECT_BITRATE: + headphones.PREFERRED_BITRATE = float(sum(bitrates))/len(bitrates)/1000 \ No newline at end of file