def create_archive(songs): try: files = [] for song in songs: location = song["location"].encode("utf8") print type(location) zip_path = song["location"].replace(cfg["MUSIC_PATH"], "").encode("utf8") files.append((location, zip_path)) zip_cover_path = os.path.join(os.path.dirname(zip_path), "Cover.jpg") cover = (find_cover(song), zip_cover_path) if cover not in files: files.append(cover) path = os.path.join(cfg["CACHE_DIR"], "%s.zip") % hashlib.sha1(str(files)).hexdigest() logger.debug("Creating archive at %s" % path) logger.debug(files) archive = zipfile.ZipFile(path, "w", zipfile.ZIP_STORED) for item in files: logger.debug('Added "%s" to "%s"' % item) archive.write(*item) archive.close() return path except Exception as e: logger.exception(e)
def find_cover(song): """Attempts to locate a cover image that would be associated with a given file. """ logger.debug("Looking for a cover for %s" % song['location']) # Check the cache for the cover image and send that if we have it. img_path = os.path.join(cfg['CACHE_DIR'], hashlib.sha1(song['artist_hash'] + song['album_hash']).hexdigest() + '.jpg') if not os.path.exists(os.path.split(img_path)[0]): os.makedirs(os.path.split(img_path)[0]) if os.path.exists(img_path): if os.stat(img_path).st_size == 0: os.remove(img_path) else: logger.debug("Using cached cover image at %s" % img_path) return img_path # Try to get embedded cover art song_location = song['location'].encode('utf8') metadata = mutagen.File(song_location) pic = None if 'APIC:' in metadata.keys(): pic = metadata.get('APIC:').data elif 'covr' in metadata.keys(): pic = metadata.get('covr')[0] elif 'coverart' in metadata.keys(): data = metadata.get('coverart')[0] pic = base64.b64decode(data) elif 'metadata_block_picture' in metadata.keys(): data = metadata.get('metadata_block_picture')[0] pic = mutagen.flac.Picture(base64.b64decode(data)).data elif 'pictures' in metadata.keys(): pic = metadata.get('pictures')[0].data elif 'WM/Picture' in metadata.keys(): data = metadata.get('WM/Picture')[0].value pic = unpack_image(data)[1] else: try: for picture in metadata.pictures: if picture.type == 3: pic = picture.data break except: pass if pic: try: image = open(img_path, "wb") image.write(pic) logger.debug("Using cover image embedded in %s" % song['location']) return img_path except: pass finally: image.close() if os.stat(img_path).st_size == 0: os.remove(img_path) # Search the song's directory for images that might be cover art try: # Get the path to the folder containing the song for which we need a # cover image path = os.path.split(song['location'])[0].encode('utf8') # Look for any files in the path that are images and give them a score # based on their filename and append them to our results list. images = [] for item in os.listdir(path): name, extension = os.path.splitext(item) if extension.lower()[1:] in cfg['COVER_EXTENSIONS']: score = 0 if name.lower() in cfg['COVER_NAMES']: score += 1 images.append([score, os.path.join(path, item)]) # Sort our images by score and return the highest one. Seems like a pretty # ham fisted approach, will need to refine this later. images.sort(reverse=True) logger.debug("Using cover image at %s" % images[0][1]) return images[0][1] except Exception as e: logger.exception(e) logger.debug("Couldn't find any suitable cover image.") return None