예제 #1
0
def embedLyrics(downloaded_track_list):
    logger.info('Adding lyrics')
    
    # TODO: If adding lyrics for flac & lossy, only fetch the lyrics once
    # and apply it to both files
    for downloaded_track in downloaded_track_list:
        
        try:
            f = MediaFile(downloaded_track)
        except:
            logger.error('Could not read %s. Not checking lyrics' % downloaded_track.decode(headphones.SYS_ENCODING, 'replace'))
            continue
            
        if f.albumartist and f.title:
            metalyrics = lyrics.getLyrics(f.albumartist, f.title)
        elif f.artist and f.title:
            metalyrics = lyrics.getLyrics(f.artist, f.title)
        else:
            logger.info('No artist/track metadata found for track: %s. Not fetching lyrics' % downloaded_track.decode(headphones.SYS_ENCODING, 'replace'))
            metalyrics = None
            
        if lyrics:
            logger.debug('Adding lyrics to: %s' % downloaded_track.decode(headphones.SYS_ENCODING, 'replace'))
            f.lyrics = metalyrics
            f.save()
예제 #2
0
def embedLyrics(downloaded_track_list):
    logger.info('Adding lyrics')

    # TODO: If adding lyrics for flac & lossy, only fetch the lyrics once
    # and apply it to both files
    for downloaded_track in downloaded_track_list:

        try:
            f = MediaFile(downloaded_track)
        except:
            logger.error(
                'Could not read %s. Not checking lyrics' %
                downloaded_track.decode(headphones.SYS_ENCODING, 'replace'))
            continue

        if f.albumartist and f.title:
            metalyrics = lyrics.getLyrics(f.albumartist, f.title)
        elif f.artist and f.title:
            metalyrics = lyrics.getLyrics(f.artist, f.title)
        else:
            logger.info(
                'No artist/track metadata found for track: %s. Not fetching lyrics'
                % downloaded_track.decode(headphones.SYS_ENCODING, 'replace'))
            metalyrics = None

        if lyrics:
            logger.debug(
                'Adding lyrics to: %s' %
                downloaded_track.decode(headphones.SYS_ENCODING, 'replace'))
            f.lyrics = metalyrics
            f.save()
예제 #3
0
 def write(self):
     """Writes the item's metadata to the associated file.
     """
     f = MediaFile(syspath(self.path))
     for key in ITEM_KEYS_WRITABLE:
         setattr(f, key, getattr(self, key))
     f.save()
예제 #4
0
 def write(self):
     """Writes the item's metadata to the associated file.
     """
     f = MediaFile(syspath(self.path))
     for key in ITEM_KEYS_WRITABLE:
         setattr(f, key, getattr(self, key))
     f.save()
예제 #5
0
def embedLyrics(downloaded_track_list):
    logger.info('Adding lyrics')

    for downloaded_track in downloaded_track_list:

        try:
            f = MediaFile(downloaded_track)
        except:
            logger.error('Could not read %s. Not checking lyrics' %
                         downloaded_track)

        if f.albumartist and f.title:
            metalyrics = lyrics.getLyrics(f.albumartist, f.title)
        elif f.artist and f.title:
            metalyrics = lyrics.getLyrics(f.artist, f.title)
        else:
            logger.info(
                'No artist/track metadata found for track: %s. Not fetching lyrics'
                % downloaded_track)
            metalyrics = None

        if lyrics:
            logger.debug('Adding lyrics to: %s' % downloaded_track)
            f.lyrics = metalyrics
            f.save()
예제 #6
0
 def write(self):
     """Writes the item's metadata to the associated file.
     """
     f = MediaFile(syspath(self.path))
     for key in ITEM_KEYS_WRITABLE:
         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()
예제 #7
0
    def write(self):
        """Writes the item's metadata to the associated file.
        """
        f = MediaFile(syspath(self.path))
        plugins.send("write", item=self, mf=f)
        for key in ITEM_KEYS_WRITABLE:
            setattr(f, key, getattr(self, key))
        f.save()

        # The file has a new mtime.
        self.mtime = self.current_mtime()
예제 #8
0
    def write(self):
        """Writes the item's metadata to the associated file.
        """
        f = MediaFile(syspath(self.path))
        plugins.send('write', item=self, mf=f)
        for key in ITEM_KEYS_WRITABLE:
            setattr(f, key, getattr(self, key))
        f.save()

        # The file has a new mtime.
        self.mtime = self.current_mtime()
예제 #9
0
def embedAlbumArt(artwork, downloaded_track_list):
    logger.info("Embedding album art")

    for downloaded_track in downloaded_track_list:
        try:
            f = MediaFile(downloaded_track)
        except:
            logger.error("Could not read %s. Not adding album art" % downloaded_track)

        logger.debug("Adding album art to: %s" % downloaded_track)
        f.art = artwork
        f.save()
예제 #10
0
def embedAlbumArt(artwork, downloaded_track_list):
    logger.info('Embedding album art')
    
    for downloaded_track in downloaded_track_list:
        try:
            f = MediaFile(downloaded_track)
        except:
            logger.error(u'Could not read %s. Not adding album art' % downloaded_track.decode(headphones.SYS_ENCODING, 'replace'))
            continue
            
        logger.debug('Adding album art to: %s' % downloaded_track)
        f.art = artwork
        f.save()
예제 #11
0
def embedAlbumArt(artwork, downloaded_track_list):
    logger.info('Embedding album art')
    
    for downloaded_track in downloaded_track_list:
        try:
            f = MediaFile(downloaded_track)
        except:
            logger.error(u'Could not read %s. Not adding album art' % downloaded_track.decode(headphones.SYS_ENCODING, 'replace'))
            continue
            
        logger.debug('Adding album art to: %s' % downloaded_track)
        f.art = artwork
        f.save()
예제 #12
0
def embedAlbumArt(artwork, downloaded_track_list):
	logger.info('Embedding album art')
	
	for downloaded_track in downloaded_track_list:
		try:
			f = MediaFile(downloaded_track)
		except:
			logger.error('Could not read %s. Not adding album art' % downloaded_track)
			continue
			
		logger.debug('Adding album art to: %s' % downloaded_track)
		f.art = artwork
		f.save()
예제 #13
0
def embedAlbumArt(artwork, downloaded_track_list):
	logger.info('Embedding album art')
	
	for downloaded_track in downloaded_track_list:
		try:
			f = MediaFile(downloaded_track)
		except:
			logger.error('Could not read %s. Not adding album art' % downloaded_track)
			continue
			
		logger.debug('Adding album art to: %s' % downloaded_track)
		f.art = artwork
		f.save()
예제 #14
0
def embedLyrics(downloaded_track_list):
  logger.info('Adding lyrics')

  for downloaded_track in downloaded_track_list:
    try:
      f = MediaFile(downloaded_track)
    except:
      logger.error('Could not read %s. Not checking lyrics' % downloaded_track)

    if f.albumartist and f.title:
      metalyrics = lyrics.getLyrics(f.albumartist, f.title)
    elif f.artist and f.title:
      metalyrics = lyrics.getLyrics(f.artist, f.title)
    else:
      logger.info('No artist/track metadata found for track: %s. Not fetching lyrics' % downloaded_track)
      metalyrics = None

    if lyrics:
      logger.debug('Adding lyrics to: %s' % downloaded_track)
      f.lyrics = metalyrics
      f.save()
예제 #15
0
def libraryScan(dir=None):

    if not dir:
        dir = headphones.MUSIC_DIR

    try:
        dir = str(dir)
    except UnicodeEncodeError:
        dir = unicode(dir).encode('unicode_escape')

    if not os.path.isdir(dir):
        logger.warn('Cannot find directory: %s. Not scanning' % dir)
        return

    myDB = db.DBConnection()

    # 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'].encode(
                headphones.SYS_ENCODING)):
            myDB.action(
                'UPDATE tracks SET Location=?, BitRate=?, Format=? WHERE TrackID=?',
                [None, None, None, track['TrackID']])

    logger.info('Scanning music directory: %s' % dir)

    new_artists = []
    bitrates = []

    myDB.action('DELETE from have')

    for r, d, f in os.walk(dir):
        for files in f:
            # MEDIA_FORMATS = music file extensions, e.g. mp3, flac, etc
            if any(files.lower().endswith('.' + x.lower())
                   for x in headphones.MEDIA_FORMATS):

                song = os.path.join(r, files)
                file = unicode(os.path.join(r, files),
                               headphones.SYS_ENCODING,
                               errors='replace')

                # Try to read the metadata
                try:
                    f = MediaFile(song)

                except:
                    logger.error('Cannot read file: ' + file)
                    continue

                # Grab the bitrates for the auto detect bit rate option
                if f.bitrate:
                    bitrates.append(f.bitrate)

                # 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()

                    if track:
                        myDB.action(
                            'UPDATE tracks SET Location=?, BitRate=?, Format=? WHERE TrackID=?',
                            [file, f.bitrate, f.format, track['TrackID']])
                        continue

                # Try to match on mbid if available and we couldn't find a match based on metadata
                if 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 track:
                        myDB.action(
                            'UPDATE tracks SET Location=?, BitRate=?, Format=? WHERE TrackID=?',
                            [file, f.bitrate, f.format, 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 (ArtistName, AlbumTitle, TrackNumber, TrackTitle, TrackLength, BitRate, Genre, Date, TrackID, Location, CleanName, Format) 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), f.format
                    ])

    logger.info('Completed scanning of directory: %s' % dir)
    logger.info('Checking filepaths to see if we can find any matches')

    # 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 IS NULL')
    for track in tracks:

        release = myDB.action('SELECT * from albums WHERE AlbumID=?',
                              [track['AlbumID']]).fetchone()

        try:
            year = release['ReleaseDate'][:4]
        except TypeError:
            year = ''

        artist = release['ArtistName'].replace('/', '_')
        album = release['AlbumTitle'].replace('/', '_')
        releasetype = release['Type'].replace('/', '_')

        if release['ArtistName'].startswith('The '):
            sortname = release['ArtistName'][4:]
        else:
            sortname = release['ArtistName']

        if sortname.isdigit():
            firstchar = '0-9'
        else:
            firstchar = sortname[0]

        albumvalues = {
            '$Artist': artist,
            '$Album': album,
            '$Year': year,
            '$Type': releasetype,
            '$First': firstchar,
            '$artist': artist.lower(),
            '$album': album.lower(),
            '$year': year,
            '$type': releasetype.lower(),
            '$first': firstchar.lower()
        }

        folder = helpers.replace_all(headphones.FOLDER_FORMAT, albumvalues)
        folder = folder.replace('./', '_/').replace(':', '_').replace('?', '_')

        if folder.endswith('.'):
            folder = folder.replace(folder[len(folder) - 1], '_')

        if not track['TrackNumber']:
            tracknumber = ''
        else:
            tracknumber = '%02d' % track['TrackNumber']

        title = track['TrackTitle']

        trackvalues = {
            '$Track': tracknumber,
            '$Title': title,
            '$Artist': release['ArtistName'],
            '$Album': release['AlbumTitle'],
            '$Year': year,
            '$track': tracknumber,
            '$title': title.lower(),
            '$artist': release['ArtistName'].lower(),
            '$album': release['AlbumTitle'].lower(),
            '$year': year
        }

        new_file_name = helpers.replace_all(
            headphones.FILE_FORMAT, trackvalues).replace('/', '_') + '.*'

        new_file_name = new_file_name.replace('?', '_').replace(':', '_')

        full_path_to_file = os.path.normpath(
            os.path.join(headphones.MUSIC_DIR, folder,
                         new_file_name)).encode(headphones.SYS_ENCODING,
                                                'replace')

        match = glob.glob(full_path_to_file)

        if match:

            logger.info('Found a match: %s. Writing MBID to metadata' %
                        match[0])

            unipath = unicode(match[0],
                              headphones.SYS_ENCODING,
                              errors='replace')

            myDB.action('UPDATE tracks SET Location=? WHERE TrackID=?',
                        [unipath, track['TrackID']])
            myDB.action('DELETE from have WHERE Location=?', [unipath])

            # Try to insert the appropriate track id so we don't have to keep doing this
            try:
                f = MediaFile(match[0])
                f.mb_trackid = track['TrackID']
                f.save()
                myDB.action(
                    'UPDATE tracks SET BitRate=?, Format=? WHERE TrackID=?',
                    [f.bitrate, f.format, track['TrackID']])

                logger.debug('Wrote mbid to track: %s' % match[0])

            except:
                logger.error('Error embedding track id into: %s' % match[0])
                continue

    logger.info('Done checking empty filepaths')
    logger.info('Done syncing library with directory: %s' % dir)

    # Clean up the new artist list
    unique_artists = {}.fromkeys(new_artists).keys()
    current_artists = myDB.select('SELECT ArtistName, ArtistID from artists')

    artist_list = [
        f for f in unique_artists
        if f.lower() not in [x[0].lower() for x in current_artists]
    ]

    # Update track counts
    logger.info('Updating track counts')

    for artist in current_artists:
        havetracks = len(
            myDB.select(
                'SELECT TrackTitle from tracks WHERE ArtistID like ? AND Location IS NOT NULL',
                [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']])

    logger.info('Found %i new artists' % len(artist_list))

    if len(artist_list):
        if headphones.ADD_ARTISTS:
            logger.info('Importing %i new artists' % len(artist_list))
            importer.artistlist_to_mbids(artist_list)
        else:
            logger.info(
                'To add these artists, go to Manage->Manage New Artists')
            headphones.NEW_ARTISTS = artist_list

    if headphones.DETECT_BITRATE:
        headphones.PREFERRED_BITRATE = sum(bitrates) / len(bitrates) / 1000
예제 #16
0
  def fileSystemScan(self):
    # 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 IS NULL')

    for track in tracks:
      release = myDB.action('SELECT * from albums WHERE AlbumID=?', [track['AlbumID']]).fetchone()

      try:
        year = release['ReleaseDate'][:4]
      except TypeError:
        year = ''

      artist = release['ArtistName'].replace('/', '_')
      album = release['AlbumTitle'].replace('/', '_')

      if release['ArtistName'].startswith('The '):
        sortname = release['ArtistName'][4:]
      else:
        sortname = release['ArtistName']

      if sortname.isdigit():
        firstchar = '0-9'
      else:
        firstchar = sortname[0]

      lowerfirst = firstchar.lower()
      albumvalues = { 'artist': artist,
        'album':  album,
        'year':   year,
        'first':  firstchar,
        'lowerfirst': lowerfirst
      }

      folder = helpers.replace_all(headphones.FOLDER_FORMAT, albumvalues)
      folder = folder.replace('./', '_/').replace(':','_').replace('?','_')

      if folder.endswith('.'):
        folder = folder.replace(folder[len(folder)-1], '_')

      if not track['TrackNumber']:
        tracknumber = ''
      else:
        tracknumber = '%02d' % track['TrackNumber']

      trackvalues = { 'tracknumber':  tracknumber,
        'title':    track['TrackTitle'],
        'artist':   release['ArtistName'],
        'album':    release['AlbumTitle'],
        'year':     year
      }

      new_file_name = helpers.replace_all(headphones.FILE_FORMAT, trackvalues).replace('/','_') + '.*'
      new_file_name = new_file_name.replace('?','_').replace(':', '_')
      full_path_to_file = os.path.normpath(os.path.join(headphones.MUSIC_DIR, folder, new_file_name)).encode(headphones.SYS_ENCODING, 'replace')
      match = glob.glob(full_path_to_file)

      if match:
        logger.info('Found a match: %s. Writing MBID to metadata' % match[0])

        unipath = unicode(match[0], headphones.SYS_ENCODING, errors='replace')

        myDB.action('UPDATE tracks SET Location=? WHERE TrackID=?', [unipath, track['TrackID']])
        myDB.action('DELETE from have WHERE Location=?', [unipath])

        # Try to insert the appropriate track id so we don't have to keep doing this
        try:
          f = MediaFile(match[0])
          f.mb_trackid = track['TrackID']
          f.save()
          myDB.action('UPDATE tracks SET BitRate=? WHERE TrackID=?', [f.bitrate, track['TrackID']])

          logger.debug('Wrote mbid to track: %s' % match[0])
        except:
          logger.error('Error embedding track id into: %s' % match[0])
          continue
예제 #17
0
def libraryScan(dir=None):

	if not dir:
		dir = headphones.MUSIC_DIR
		
	try:
		dir = str(dir)
	except UnicodeEncodeError:
		dir = unicode(dir).encode('unicode_escape')
		
	if not os.path.isdir(dir):
		logger.warn('Cannot find directory: %s. Not scanning' % dir)
		return

	myDB = db.DBConnection()
	
	# 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'].encode(headphones.SYS_ENCODING)):
			myDB.action('UPDATE tracks SET Location=?, BitRate=?, Format=? WHERE TrackID=?', [None, None, None, track['TrackID']])

	logger.info('Scanning music directory: %s' % dir)

	new_artists = []
	bitrates = []

	myDB.action('DELETE from have')
	
	for r,d,f in os.walk(dir):
		for files in f:
			# MEDIA_FORMATS = music file extensions, e.g. mp3, flac, etc
			if any(files.lower().endswith('.' + x.lower()) for x in headphones.MEDIA_FORMATS):

				song = os.path.join(r, files)
				file = unicode(os.path.join(r, files), headphones.SYS_ENCODING, errors='replace')

				# Try to read the metadata
				try:
					f = MediaFile(song)

				except:
					logger.error('Cannot read file: ' + file)
					continue
					
				# Grab the bitrates for the auto detect bit rate option
				if f.bitrate:
					bitrates.append(f.bitrate)
				
				# 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()
					
					if track:
						myDB.action('UPDATE tracks SET Location=?, BitRate=?, Format=? WHERE TrackID=?', [file, f.bitrate, f.format, track['TrackID']])
						continue		
				
				# Try to match on mbid if available and we couldn't find a match based on metadata
				if 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 track:
						myDB.action('UPDATE tracks SET Location=?, BitRate=?, Format=? WHERE TrackID=?', [file, f.bitrate, f.format, 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 (ArtistName, AlbumTitle, TrackNumber, TrackTitle, TrackLength, BitRate, Genre, Date, TrackID, Location, CleanName, Format) 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), f.format])

	logger.info('Completed scanning of directory: %s' % dir)
	logger.info('Checking filepaths to see if we can find any matches')

	# 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 IS NULL')
	for track in tracks:
	
		release = myDB.action('SELECT * from albums WHERE AlbumID=?', [track['AlbumID']]).fetchone()

		try:
			year = release['ReleaseDate'][:4]
		except TypeError:
			year = ''
			
		artist = release['ArtistName'].replace('/', '_')
		album = release['AlbumTitle'].replace('/', '_')
	
		if release['ArtistName'].startswith('The '):
			sortname = release['ArtistName'][4:]
		else:
			sortname = release['ArtistName']
		
		if sortname.isdigit():
			firstchar = '0-9'
		else:
			firstchar = sortname[0]
			
		lowerfirst = firstchar.lower()
		
		albumvalues = {	'artist':	artist,
						'album':	album,
						'year':		year,
						'first':	firstchar,
						'lowerfirst':	lowerfirst
					}
				
		
		folder = helpers.replace_all(headphones.FOLDER_FORMAT, albumvalues)
		folder = folder.replace('./', '_/').replace(':','_').replace('?','_')
		
		if folder.endswith('.'):
			folder = folder.replace(folder[len(folder)-1], '_')

		if not track['TrackNumber']:
			tracknumber = ''
		else:
			tracknumber = '%02d' % track['TrackNumber']
			
		trackvalues = {	'tracknumber':	tracknumber,
						'title':		track['TrackTitle'],
						'artist':		release['ArtistName'],
						'album':		release['AlbumTitle'],
						'year':			year
						}
		
		new_file_name = helpers.replace_all(headphones.FILE_FORMAT, trackvalues).replace('/','_') + '.*'
		
		new_file_name = new_file_name.replace('?','_').replace(':', '_')
		
		full_path_to_file = os.path.normpath(os.path.join(headphones.MUSIC_DIR, folder, new_file_name)).encode(headphones.SYS_ENCODING, 'replace')

		match = glob.glob(full_path_to_file)
		
		if match:

			logger.info('Found a match: %s. Writing MBID to metadata' % match[0])
			
			unipath = unicode(match[0], headphones.SYS_ENCODING, errors='replace')

			myDB.action('UPDATE tracks SET Location=? WHERE TrackID=?', [unipath, track['TrackID']])
			myDB.action('DELETE from have WHERE Location=?', [unipath])
			
			# Try to insert the appropriate track id so we don't have to keep doing this
			try:
				f = MediaFile(match[0])
				f.mb_trackid = track['TrackID']
				f.save()
				myDB.action('UPDATE tracks SET BitRate=?, Format=? WHERE TrackID=?', [f.bitrate, f.format, track['TrackID']])

				logger.debug('Wrote mbid to track: %s' % match[0])

			except:
				logger.error('Error embedding track id into: %s' % match[0])
				continue

	logger.info('Done checking empty filepaths')
	logger.info('Done syncing library with directory: %s' % dir)
	
	# Clean up the new artist list
	unique_artists = {}.fromkeys(new_artists).keys()
	current_artists = myDB.select('SELECT ArtistName, ArtistID from artists')
	
	artist_list = [f for f in unique_artists if f.lower() not in [x[0].lower() for x in current_artists]]
	
	# Update track counts
	logger.info('Updating track counts')

	for artist in current_artists:
		havetracks = len(myDB.select('SELECT TrackTitle from tracks WHERE ArtistID like ? AND Location IS NOT NULL', [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']])
		
	logger.info('Found %i new artists' % len(artist_list))

	if len(artist_list):
		if headphones.ADD_ARTISTS:
			logger.info('Importing %i new artists' % len(artist_list))
			importer.artistlist_to_mbids(artist_list)
		else:
			logger.info('To add these artists, go to Manage->Manage New Artists')
			headphones.NEW_ARTISTS = artist_list
	
	if headphones.DETECT_BITRATE:
		headphones.PREFERRED_BITRATE = sum(bitrates)/len(bitrates)/1000
예제 #18
0
def libraryScan(dir=None):

    if not dir:
        dir = headphones.MUSIC_DIR

    try:
        dir = str(dir)
    except UnicodeEncodeError:
        dir = unicode(dir).encode("unicode_escape")

    if not os.path.isdir(dir):
        logger.warn("Cannot find directory: %s. Not scanning" % dir)
        return

    myDB = db.DBConnection()

    # 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"].encode(headphones.SYS_ENCODING)):
            myDB.action(
                "UPDATE tracks SET Location=?, BitRate=?, Format=? WHERE TrackID=?",
                [None, None, None, track["TrackID"]],
            )

    logger.info("Scanning music directory: %s" % dir)

    new_artists = []
    bitrates = []

    myDB.action("DELETE from have")

    for r, d, f in os.walk(dir):
        for files in f:
            # MEDIA_FORMATS = music file extensions, e.g. mp3, flac, etc
            if any(files.lower().endswith("." + x.lower()) for x in headphones.MEDIA_FORMATS):

                song = os.path.join(r, files)
                file = unicode(os.path.join(r, files), headphones.SYS_ENCODING, errors="replace")

                # Try to read the metadata
                try:
                    f = MediaFile(song)

                except:
                    logger.error("Cannot read file: " + file)
                    continue

                    # Grab the bitrates for the auto detect bit rate option
                if f.bitrate:
                    bitrates.append(f.bitrate)

                    # 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()

                    if track:
                        myDB.action(
                            "UPDATE tracks SET Location=?, BitRate=?, Format=? WHERE TrackID=?",
                            [file, f.bitrate, f.format, track["TrackID"]],
                        )
                        continue

                        # Try to match on mbid if available and we couldn't find a match based on metadata
                if 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 track:
                        myDB.action(
                            "UPDATE tracks SET Location=?, BitRate=?, Format=? WHERE TrackID=?",
                            [file, f.bitrate, f.format, 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 (ArtistName, AlbumTitle, TrackNumber, TrackTitle, TrackLength, BitRate, Genre, Date, TrackID, Location, CleanName, Format) 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),
                        f.format,
                    ],
                )

    logger.info("Completed scanning of directory: %s" % dir)
    logger.info("Checking filepaths to see if we can find any matches")

    # 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 IS NULL")
    for track in tracks:

        release = myDB.action("SELECT * from albums WHERE AlbumID=?", [track["AlbumID"]]).fetchone()

        try:
            year = release["ReleaseDate"][:4]
        except TypeError:
            year = ""

        artist = release["ArtistName"].replace("/", "_")
        album = release["AlbumTitle"].replace("/", "_")
        releasetype = release["Type"].replace("/", "_")

        if release["ArtistName"].startswith("The "):
            sortname = release["ArtistName"][4:]
        else:
            sortname = release["ArtistName"]

        if sortname.isdigit():
            firstchar = "0-9"
        else:
            firstchar = sortname[0]

        albumvalues = {
            "$Artist": artist,
            "$Album": album,
            "$Year": year,
            "$Type": releasetype,
            "$First": firstchar,
            "$artist": artist.lower(),
            "$album": album.lower(),
            "$year": year,
            "$type": releasetype.lower(),
            "$first": firstchar.lower(),
        }

        folder = helpers.replace_all(headphones.FOLDER_FORMAT, albumvalues)
        folder = folder.replace("./", "_/").replace(":", "_").replace("?", "_")

        if folder.endswith("."):
            folder = folder.replace(folder[len(folder) - 1], "_")

        if not track["TrackNumber"]:
            tracknumber = ""
        else:
            tracknumber = "%02d" % track["TrackNumber"]

        title = track["TrackTitle"]

        trackvalues = {
            "$Track": tracknumber,
            "$Title": title,
            "$Artist": release["ArtistName"],
            "$Album": release["AlbumTitle"],
            "$Year": year,
            "$track": tracknumber,
            "$title": title.lower(),
            "$artist": release["ArtistName"].lower(),
            "$album": release["AlbumTitle"].lower(),
            "$year": year,
        }

        new_file_name = helpers.replace_all(headphones.FILE_FORMAT, trackvalues).replace("/", "_") + ".*"

        new_file_name = new_file_name.replace("?", "_").replace(":", "_")

        full_path_to_file = os.path.normpath(os.path.join(headphones.MUSIC_DIR, folder, new_file_name)).encode(
            headphones.SYS_ENCODING, "replace"
        )

        match = glob.glob(full_path_to_file)

        if match:

            logger.info("Found a match: %s. Writing MBID to metadata" % match[0])

            unipath = unicode(match[0], headphones.SYS_ENCODING, errors="replace")

            myDB.action("UPDATE tracks SET Location=? WHERE TrackID=?", [unipath, track["TrackID"]])
            myDB.action("DELETE from have WHERE Location=?", [unipath])

            # Try to insert the appropriate track id so we don't have to keep doing this
            try:
                f = MediaFile(match[0])
                f.mb_trackid = track["TrackID"]
                f.save()
                myDB.action(
                    "UPDATE tracks SET BitRate=?, Format=? WHERE TrackID=?", [f.bitrate, f.format, track["TrackID"]]
                )

                logger.debug("Wrote mbid to track: %s" % match[0])

            except:
                logger.error("Error embedding track id into: %s" % match[0])
                continue

    logger.info("Done checking empty filepaths")
    logger.info("Done syncing library with directory: %s" % dir)

    # Clean up the new artist list
    unique_artists = {}.fromkeys(new_artists).keys()
    current_artists = myDB.select("SELECT ArtistName, ArtistID from artists")

    artist_list = [f for f in unique_artists if f.lower() not in [x[0].lower() for x in current_artists]]

    # Update track counts
    logger.info("Updating track counts")

    for artist in current_artists:
        havetracks = len(
            myDB.select(
                "SELECT TrackTitle from tracks WHERE ArtistID like ? AND Location IS NOT NULL", [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"]])

    logger.info("Found %i new artists" % len(artist_list))

    if len(artist_list):
        if headphones.ADD_ARTISTS:
            logger.info("Importing %i new artists" % len(artist_list))
            importer.artistlist_to_mbids(artist_list)
        else:
            logger.info("To add these artists, go to Manage->Manage New Artists")
            headphones.NEW_ARTISTS = artist_list

    if headphones.DETECT_BITRATE:
        headphones.PREFERRED_BITRATE = sum(bitrates) / len(bitrates) / 1000