Example #1
0
 def api_albumart_set(self, directory, imageurl):
     if not cherrypy.session['admin']:
         raise cherrypy.HTTPError(401, 'Unauthorized')
     b64imgpath = albumArtFilePath(directory)
     fetcher = albumartfetcher.AlbumArtFetcher()
     data, header = fetcher.retrieveData(imageurl)
     self.albumartcache_save(b64imgpath, data)
Example #2
0
 def api_albumart_set(self, directory, imageurl):
     if not cherrypy.session['admin']:
         raise cherrypy.HTTPError(401, 'Unauthorized')
     b64imgpath = albumArtFilePath(directory)
     fetcher = albumartfetcher.AlbumArtFetcher()
     data, header = fetcher.retrieveData(imageurl)
     self.albumartcache_save(b64imgpath, data)
Example #3
0
    def api_fetchalbumart(self, value):
        cherrypy.session.release_lock()
        params = json.loads(value)
        directory = params['directory']

        #try getting a cached album art image
        b64imgpath = albumArtFilePath(directory)
        img_data = self.albumartcache_load(b64imgpath)
        if img_data:
            cherrypy.response.headers["Content-Length"] = len(img_data)
            return img_data

        #try getting album art inside local folder
        fetcher = albumartfetcher.AlbumArtFetcher()
        localpath = os.path.join(cherry.config['media.basedir'], directory)
        header, data, resized = fetcher.fetchLocal(localpath)

        if header:
            if resized:
                #cache resized image for next time
                self.albumartcache_save(b64imgpath, data)
            cherrypy.response.headers.update(header)
            return data
        elif cherry.config['media.fetch_album_art']:
            #fetch album art from online source
            album = os.path.basename(directory)
            artist = os.path.basename(os.path.dirname(directory))
            keywords = artist + ' ' + album
            log.i("Fetching album art for keywords '%s'" % keywords)
            header, data = fetcher.fetch(keywords)
            if header:
                cherrypy.response.headers.update(header)
                self.albumartcache_save(b64imgpath, data)
                return data
        cherrypy.HTTPRedirect("/res/img/folder.png", 302)
Example #4
0
    def api_fetchalbumart(self, directory):
        cherrypy.session.release_lock()

        #try getting a cached album art image
        b64imgpath = albumArtFilePath(directory)
        img_data = self.albumartcache_load(b64imgpath)
        if img_data:
            cherrypy.response.headers["Content-Length"] = len(img_data)
            return img_data

        #try getting album art inside local folder
        fetcher = albumartfetcher.AlbumArtFetcher()
        localpath = os.path.join(cherry.config['media.basedir'], directory)
        header, data, resized = fetcher.fetchLocal(localpath)

        if header:
            if resized:
                #cache resized image for next time
                self.albumartcache_save(b64imgpath, data)
            cherrypy.response.headers.update(header)
            return data
        elif cherry.config['media.fetch_album_art']:
            #fetch album art from online source
            album = os.path.basename(directory)
            artist = os.path.basename(os.path.dirname(directory))
            keywords = artist+' '+album
            log.i("Fetching album art for keywords '%s'" % keywords)
            header, data = fetcher.fetch(keywords)
            if header:
                cherrypy.response.headers.update(header)
                self.albumartcache_save(b64imgpath, data)
                return data
        cherrypy.HTTPRedirect("/res/img/folder.png", 302)
Example #5
0
    def api_fetchalbumart(self, directory):
        _save_and_release_session()
        default_folder_image = "../res/img/folder.png"

        log.i('Fetching album art for: %s' % directory)
        filepath = os.path.join(cherry.config['media.basedir'], directory)

        if os.path.isfile(filepath):
            # if the given path is a file, try to get the image from ID3
            tag = TinyTag.get(filepath, image=True)
            image_data = tag.get_image()
            if image_data:
                log.d('Image found in tag.')
                header = {'Content-Type': 'image/jpg', 'Content-Length': len(image_data)}
                cherrypy.response.headers.update(header)
                return image_data
            else:
                # if the file does not contain an image, display the image of the
                # parent directory
                directory = os.path.dirname(directory)

        #try getting a cached album art image
        b64imgpath = albumArtFilePath(directory)
        img_data = self.albumartcache_load(b64imgpath)
        if img_data:
            cherrypy.response.headers["Content-Length"] = len(img_data)
            return img_data

        #try getting album art inside local folder
        fetcher = albumartfetcher.AlbumArtFetcher()
        localpath = os.path.join(cherry.config['media.basedir'], directory)
        header, data, resized = fetcher.fetchLocal(localpath)

        if header:
            if resized:
                #cache resized image for next time
                self.albumartcache_save(b64imgpath, data)
            cherrypy.response.headers.update(header)
            return data
        elif cherry.config['media.fetch_album_art']:
            #fetch album art from online source
            try:
                foldername = os.path.basename(directory)
                keywords = foldername
                log.i(_("Fetching album art for keywords {keywords!r}").format(keywords=keywords))
                header, data = fetcher.fetch(keywords)
                if header:
                    cherrypy.response.headers.update(header)
                    self.albumartcache_save(b64imgpath, data)
                    return data
                else:
                    # albumart fetcher failed, so we serve a standard image
                    raise cherrypy.HTTPRedirect(default_folder_image, 302)
            except:
                # albumart fetcher threw exception, so we serve a standard image
                raise cherrypy.HTTPRedirect(default_folder_image, 302)
        else:
            # no local album art found, online fetching deactivated, show default
            raise cherrypy.HTTPRedirect(default_folder_image, 302)
Example #6
0
    def api_fetchalbumart(self, directory):
        cherrypy.session.release_lock()
        default_folder_image = "/res/img/folder.png"

        #try getting a cached album art image
        b64imgpath = albumArtFilePath(directory)
        img_data = self.albumartcache_load(b64imgpath)
        if img_data:
            cherrypy.response.headers["Content-Length"] = len(img_data)
            return img_data

        #try getting album art inside local folder
        fetcher = albumartfetcher.AlbumArtFetcher()
        localpath = os.path.join(cherry.config['media.basedir'], directory)
        header, data, resized = fetcher.fetchLocal(localpath)

        if header:
            if resized:
                #cache resized image for next time
                self.albumartcache_save(b64imgpath, data)
            cherrypy.response.headers.update(header)
            return data
        elif cherry.config['media.fetch_album_art']:
            #fetch album art from online source
            try:
                foldername = os.path.basename(directory)
                keywords = foldername
                log.i(
                    _("Fetching album art for keywords {keywords!r}").format(
                        keywords=keywords))
                header, data = fetcher.fetch(keywords)
                if header:
                    cherrypy.response.headers.update(header)
                    self.albumartcache_save(b64imgpath, data)
                    return data
                else:
                    # albumart fetcher failed, so we serve a standard image
                    raise cherrypy.HTTPRedirect(default_folder_image, 302)
            except:
                # albumart fetcher threw exception, so we serve a standard image
                raise cherrypy.HTTPRedirect(default_folder_image, 302)
        else:
            # no local album art found, online fetching deactivated, show default
            raise cherrypy.HTTPRedirect(default_folder_image, 302)
Example #7
0
def migrate():
    """ Migrate if necessary, exit(1) on error """
    artfolder = pathprovider.albumArtFilePath('')
    hashpathfile = os.path.join(artfolder, _DONE_FILE)
    if os.path.exists(hashpathfile):
        log.debug('Saved album art filenames already migrated. Skipping.')
        return

    try:
        log.info('Migrating saved album art filenames...')
        _migrate(artfolder)
    except:
        errmsg = _ERR_MSG.format(artfolder=artfolder)
        log.exception('Error during album art migration')
        log.critical(errmsg)
        sys.exit(1)
    else:
        open(hashpathfile, 'a').close()
        log.info('Album art filename migration done.')
Example #8
0
    def api_fetchalbumart(self, directory):
        cherrypy.session.release_lock()
        default_folder_image = "/res/img/folder.png"

        #try getting a cached album art image
        b64imgpath = albumArtFilePath(directory)
        img_data = self.albumartcache_load(b64imgpath)
        if img_data:
            cherrypy.response.headers["Content-Length"] = len(img_data)
            return img_data

        #try getting album art inside local folder
        fetcher = albumartfetcher.AlbumArtFetcher()
        localpath = os.path.join(cherry.config['media.basedir'], directory)
        header, data, resized = fetcher.fetchLocal(localpath)

        if header:
            if resized:
                #cache resized image for next time
                self.albumartcache_save(b64imgpath, data)
            cherrypy.response.headers.update(header)
            return data
        elif cherry.config['media.fetch_album_art']:
            #fetch album art from online source
            try:
                foldername = os.path.basename(directory)
                keywords = foldername
                log.i(_("Fetching album art for keywords {keywords!r}").format(keywords=keywords))
                header, data = fetcher.fetch(keywords)
                if header:
                    cherrypy.response.headers.update(header)
                    self.albumartcache_save(b64imgpath, data)
                    return data
                else:
                    # albumart fetcher failed, so we serve a standard image
                    raise cherrypy.HTTPRedirect(default_folder_image, 302)
            except:
                # albumart fetcher threw exception, so we serve a standard image
                raise cherrypy.HTTPRedirect(default_folder_image, 302)
        else:
            # no local album art found, online fetching deactivated, show default
            raise cherrypy.HTTPRedirect(default_folder_image, 302)
Example #9
0
def _migrate(sourcedir):
    """ migrate into different dir and then swap it in, to mitigate mishaps """
    targetdir = sourcedir.rstrip(os.path.sep) + _MIGRATION_SUFFIX
    try:
        os.mkdir(targetdir)
    except OSError as err:
        # ignore if targetdir exists to allow restarting aborted migrations
        if err.errno != errno.EEXIST:
            raise

    _base64_artfile_regex = re.compile(
        '^'
        '([\da-zA-Z+-]{4})*'             # pathprovider uses '-' instead of '\'
        '([\da-zA-Z+-]{3}=|[\da-zA-Z+-]{2}==)?'
        '$')
    is_base64 = lambda s: bool(_base64_artfile_regex.match(s))

    all_filenames = os.listdir(sourcedir)
    migratable_filenames = (f for f in all_filenames if is_base64(f))
    unmigratable_filenames = (f for f in all_filenames if not is_base64(f))

    # move any non-albumart files first (which shouldn't exist, but who knows)
    for filename in unmigratable_filenames:
        oldpath = os.path.join(sourcedir, filename)
        newpath = os.path.join(targetdir, filename)
        _move_if_exists(oldpath, newpath)

    # migrate albumart files
    for filename in migratable_filenames:
        ownerpath = _base64decode(filename)
        oldpath = os.path.join(sourcedir, filename)
        newname = os.path.basename(pathprovider.albumArtFilePath(ownerpath))
        newpath = os.path.join(targetdir, newname)
        _move_if_exists(oldpath, newpath)

    os.rmdir(sourcedir)
    os.rename(targetdir, sourcedir)
Example #10
0
def test_albumArtFilePath():
    """albumArtFilePath contains md5-filename, or no filename with empty argument"""
    testpath = pathprovider.albumArtFilePath('a/s/d')
    artfolder, filename = os.path.split(testpath)
    ok_(re.match(r'^[0-9a-fA-F]{32}\.thumb$', filename), filename)
    eq_(artfolder, pathprovider.albumArtFilePath('').rstrip(os.path.sep))
Example #11
0
    def api_fetchalbumart(self, directory):
        _save_and_release_session()
        default_folder_image = "../res/img/folder.png"

        log.i('Fetching album art for: %s' % directory)
        filepath = os.path.join(cherry.config['media.basedir'], directory)

        if os.path.isfile(filepath):
            # if the given path is a file, try to get the image from ID3
            tag = TinyTag.get(filepath, image=True)
            image_data = tag.get_image()
            if image_data:
                log.d('Image found in tag.')
                header = {'Content-Type': 'image/jpg', 'Content-Length': len(image_data)}
                cherrypy.response.headers.update(header)
                return image_data
            else:
                # if the file does not contain an image, display the image of the
                # parent directory
                directory = os.path.dirname(directory)

        #try getting a cached album art image
        b64imgpath = albumArtFilePath(directory)
        img_data = self.albumartcache_load(b64imgpath)
        if img_data:
            cherrypy.response.headers["Content-Length"] = len(img_data)
            return img_data

        #try getting album art inside local folder
        fetcher = albumartfetcher.AlbumArtFetcher()
        localpath = os.path.join(cherry.config['media.basedir'], directory)
        header, data, resized = fetcher.fetchLocal(localpath)

        if header:
            if resized:
                #cache resized image for next time
                self.albumartcache_save(b64imgpath, data)
            cherrypy.response.headers.update(header)
            return data
        elif cherry.config['media.fetch_album_art']:
            # maximum of files to try to fetch metadata for albumart keywords
            METADATA_ALBUMART_MAX_FILES = 10
            #fetch album art from online source
            try:
                foldername = os.path.basename(directory)
                keywords = foldername
                # remove any odd characters from the folder name
                keywords = re.sub('[^A-Za-z\s]', ' ', keywords)
                # try getting metadata from files in the folder for a more
                # accurate match
                files = os.listdir(localpath)
                for i, filename in enumerate(files):
                    if i >= METADATA_ALBUMART_MAX_FILES:
                        break
                    path = os.path.join(localpath, filename)
                    metadata = metainfo.getSongInfo(path)
                    if metadata.artist and metadata.album:
                        keywords = '{} - {}'.format(metadata.artist, metadata.album)
                        break

                log.i(_("Fetching album art for keywords {keywords!r}").format(keywords=keywords))
                header, data = fetcher.fetch(keywords)
                if header:
                    cherrypy.response.headers.update(header)
                    self.albumartcache_save(b64imgpath, data)
                    return data
                else:
                    # albumart fetcher failed, so we serve a standard image
                    raise cherrypy.HTTPRedirect(default_folder_image, 302)
            except:
                # albumart fetcher threw exception, so we serve a standard image
                raise cherrypy.HTTPRedirect(default_folder_image, 302)
        else:
            # no local album art found, online fetching deactivated, show default
            raise cherrypy.HTTPRedirect(default_folder_image, 302)
Example #12
0
    def api_fetchalbumart(self, directory):
        _save_and_release_session()
        default_folder_image = "../res/img/folder.png"

        log.i('Fetching album art for: %s' % directory)
        filepath = os.path.join(cherry.config['media.basedir'], directory)

        if os.path.isfile(filepath):
            # if the given path is a file, try to get the image from ID3
            tag = TinyTag.get(filepath, image=True)
            image_data = tag.get_image()
            if image_data:
                log.d('Image found in tag.')
                header = {
                    'Content-Type': 'image/jpg',
                    'Content-Length': len(image_data)
                }
                cherrypy.response.headers.update(header)
                return image_data
            else:
                # if the file does not contain an image, display the image of the
                # parent directory
                directory = os.path.dirname(directory)

        #try getting a cached album art image
        b64imgpath = albumArtFilePath(directory)
        img_data = self.albumartcache_load(b64imgpath)
        if img_data:
            cherrypy.response.headers["Content-Length"] = len(img_data)
            return img_data

        #try getting album art inside local folder
        fetcher = albumartfetcher.AlbumArtFetcher()
        localpath = os.path.join(cherry.config['media.basedir'], directory)
        header, data, resized = fetcher.fetchLocal(localpath)

        if header:
            if resized:
                #cache resized image for next time
                self.albumartcache_save(b64imgpath, data)
            cherrypy.response.headers.update(header)
            return data
        elif cherry.config['media.fetch_album_art']:
            #fetch album art from online source
            try:
                foldername = os.path.basename(directory)
                keywords = foldername
                log.i(
                    _("Fetching album art for keywords {keywords!r}").format(
                        keywords=keywords))
                header, data = fetcher.fetch(keywords)
                if header:
                    cherrypy.response.headers.update(header)
                    self.albumartcache_save(b64imgpath, data)
                    return data
                else:
                    # albumart fetcher failed, so we serve a standard image
                    raise cherrypy.HTTPRedirect(default_folder_image, 302)
            except:
                # albumart fetcher threw exception, so we serve a standard image
                raise cherrypy.HTTPRedirect(default_folder_image, 302)
        else:
            # no local album art found, online fetching deactivated, show default
            raise cherrypy.HTTPRedirect(default_folder_image, 302)
def test_albumArtFilePath():
    """albumArtFilePath contains md5-filename, or no filename with empty argument"""
    testpath = pathprovider.albumArtFilePath('a/s/d')
    artfolder, filename = os.path.split(testpath)
    ok_(re.match(r'^[0-9a-fA-F]{32}\.thumb$', filename), filename)
    eq_(artfolder, pathprovider.albumArtFilePath('').rstrip(os.path.sep))