Exemple #1
0
    def _sendhttp(self, host, command):
        url_command = urllib.urlencode(command)
        url = host + '/xbmcCmds/xbmcHttp/?' + url_command

        if self.password:
            return request.request_content(url, auth=(self.username, self.password))
        else:
            return request.request_content(url)
Exemple #2
0
    def _sendhttp(self, host, command):
        url_command = urllib.urlencode(command)
        url = host + '/xbmcCmds/xbmcHttp/?' + url_command

        if self.password:
            return request.request_content(url, auth=(self.username, self.password))
        else:
            return request.request_content(url)
Exemple #3
0
def getLyrics(artist, song):

    params = {
        "artist": artist.encode('utf-8'),
        "song": song.encode('utf-8'),
        "fmt": 'xml'
    }

    url = 'http://lyrics.wikia.com/api.php'
    data = request.request_minidom(url, params=params)

    if not data:
        return

    url = data.getElementsByTagName("url")

    if url:
        lyricsurl = url[0].firstChild.nodeValue
    else:
        logger.info('No lyrics found for %s - %s' % (artist, song))
        return

    lyricspage = request.request_content(lyricsurl)

    if not lyricspage:
        logger.warn('Error fetching lyrics from: %s' % lyricsurl)
        return

    m = re.compile(
        '''<div class='lyricbox'><div class='rtMatcher'>.*?</div>(.*?)<!--'''
    ).search(lyricspage)

    if not m:
        m = re.compile(
            '''<div class='lyricbox'><span style="padding:1em"><a href="/Category:Instrumental" title="Instrumental">'''
        ).search(lyricspage)
        if m:
            return u'(Instrumental)'
        else:
            logger.warn('Cannot find lyrics on: %s' % lyricsurl)
            return

    lyrics = convert_html_entities(m.group(1)).replace('<br />', '\n')
    lyrics = re.sub('<.*?>', '', lyrics)

    return lyrics
Exemple #4
0
def getCachedArt(albumid):
    from headphones import cache

    c = cache.Cache()
    artwork_path = c.get_artwork_from_cache(AlbumID=albumid)

    if not artwork_path:
        return

    if artwork_path.startswith('http://'):
        artwork = request.request_content(artwork_path, timeout=20)

        if not artwork:
            logger.warn("Unable to open url: %s", artwork_path)
            return
    else:
        with open(artwork_path, "r") as fp:
            return fp.read()
Exemple #5
0
def getLyrics(artist, song):
    params = {"artist": artist.encode('utf-8'),
              "song": song.encode('utf-8'),
              "fmt": 'xml'
              }

    url = 'http://lyrics.wikia.com/api.php'
    data = request.request_minidom(url, params=params)

    if not data:
        return

    url = data.getElementsByTagName("url")

    if url:
        lyricsurl = url[0].firstChild.nodeValue
    else:
        logger.info('No lyrics found for %s - %s' % (artist, song))
        return

    lyricspage = request.request_content(lyricsurl)

    if not lyricspage:
        logger.warn('Error fetching lyrics from: %s' % lyricsurl)
        return

    m = re.compile('''<div class='lyricbox'><div class='rtMatcher'>.*?</div>(.*?)<!--''').search(
        lyricspage)

    if not m:
        m = re.compile(
            '''<div class='lyricbox'><span style="padding:1em"><a href="/Category:Instrumental" title="Instrumental">''').search(
            lyricspage)
        if m:
            return u'(Instrumental)'
        else:
            logger.warn('Cannot find lyrics on: %s' % lyricsurl)
            return

    lyrics = convert_html_entities(m.group(1)).replace('<br />', '\n')
    lyrics = re.sub('<.*?>', '', lyrics)

    return lyrics
Exemple #6
0
def update():
    if headphones.INSTALL_TYPE == 'win':
        logger.info('Windows .exe updating not supported yet.')

    elif headphones.INSTALL_TYPE == 'git':
        output, err = runGit('pull origin ' + headphones.GIT_BRANCH)

        if not output:
            logger.error('Couldn\'t download latest version')

        for line in output.split('\n'):

            if 'Already up-to-date.' in line:
                logger.info('No update available, not updating')
                logger.info('Output: ' + str(output))
            elif line.endswith('Aborting.'):
                logger.error('Unable to update from git: '+line)
                logger.info('Output: ' + str(output))

    else:
        tar_download_url = 'https://github.com/%s/headphones/tarball/%s' % (headphones.GIT_USER, headphones.GIT_BRANCH)
        update_dir = os.path.join(headphones.PROG_DIR, 'update')
        version_path = os.path.join(headphones.PROG_DIR, 'version.txt')

        logger.info('Downloading update from: '+ tar_download_url)
        data = request.request_content(tar_download_url)

        if not data:
            logger.error("Unable to retrieve new version from '%s', can't update", tar_download_url)
            return

        download_name = headphones.GIT_BRANCH + '-github'
        tar_download_path = os.path.join(headphones.PROG_DIR, download_name)

        # Save tar to disk
        with open(tar_download_path, 'wb') as f:
            f.write(data)

        # Extract the tar to update folder
        logger.info('Extracting file: ' + tar_download_path)
        tar = tarfile.open(tar_download_path)
        tar.extractall(update_dir)
        tar.close()

        # Delete the tar.gz
        logger.info('Deleting file: ' + tar_download_path)
        os.remove(tar_download_path)

        # Find update dir name
        update_dir_contents = [x for x in os.listdir(update_dir) if os.path.isdir(os.path.join(update_dir, x))]
        if len(update_dir_contents) != 1:
            logger.error("Invalid update data, update failed: "+str(update_dir_contents))
            return
        content_dir = os.path.join(update_dir, update_dir_contents[0])

        # walk temp folder and move files to main folder
        for dirname, dirnames, filenames in os.walk(content_dir):
            dirname = dirname[len(content_dir)+1:]
            for curfile in filenames:
                old_path = os.path.join(content_dir, dirname, curfile)
                new_path = os.path.join(headphones.PROG_DIR, dirname, curfile)

                if os.path.isfile(new_path):
                    os.remove(new_path)
                os.renames(old_path, new_path)

        # Update version.txt
        try:
            with open(version_path, 'w') as f:
                f.write(str(headphones.LATEST_VERSION))
        except IOError as e:
            logger.error("Unable to write current version to version.txt, " \
                "update not complete: ", e)
            return
Exemple #7
0
    def _update_cache(self):
        """
        Since we call the same url for both info and artwork, we'll update both at the same time
        """

        myDB = db.DBConnection()

        if self.id_type == 'artist':

            try:
                data = Artist.get(id=self.id)
            except Exception as e:
                dbartist = myDB.action(
                    'SELECT ArtistName, Type FROM artists WHERE ArtistID=?',
                    [self.id]).fetchone()[0]
                if dbartist:
                    logger.debug('Fanart.tv artist lookup error for %s: %s',
                                 dbartist, e)
                    logger.debug('Stored id for %s is: %s', dbartist, self.id)
                else:
                    logger.debug('Fanart.tv artist lookup error for %s: %s',
                                 self.id, e)
                return

            artist_url = None
            thumb_url = None
            image_url = None

            if data.thumbs:
                for thumbs in data.thumbs[0:1]:
                    artist_url = str(thumbs.url)

            if artist_url:
                thumb_url = artist_url.replace('fanart/', 'preview/')
                image_url = thumb_url
                logger.debug('Fanart.tv artist image url: %s', thumb_url)
            else:
                logger.debug('Fanart.tv no artist image found for: %s',
                             self.id)

            data = lastfm.request_lastfm("artist.getinfo",
                                         mbid=self.id,
                                         api_key=LASTFM_API_KEY)

            # Try with name if not found
            if not data:
                dbartist = myDB.action(
                    'SELECT ArtistName, Type FROM artists WHERE ArtistID=?',
                    [self.id]).fetchone()[0]
                if dbartist:
                    data = lastfm.request_lastfm(
                        "artist.getinfo",
                        artist=helpers.clean_musicbrainz_name(
                            dbartist['ArtistName']),
                        api_key=LASTFM_API_KEY)

            if not data:
                logger.debug('Last.fm connection cannot be made')

            try:
                self.info_summary = data['artist']['bio']['summary']
            except KeyError:
                logger.debug('No artist bio summary found')
                self.info_summary = None
            try:
                self.info_content = data['artist']['bio']['content']
            except KeyError:
                logger.debug('No artist bio found')
                self.info_content = None

        else:

            # get ArtistID from AlbumID lookup - ArtistID not passed into this function otherwise
            myDB = db.DBConnection()
            ArtistID = myDB.action(
                'SELECT ArtistID FROM albums WHERE ReleaseID=?',
                [self.id]).fetchone()[0]

            try:
                data = Artist.get(id=ArtistID)
            except Exception as e:
                dbartist = myDB.action(
                    'SELECT ArtistName, Type FROM artists WHERE ArtistID=?',
                    [ArtistID]).fetchone()[0]
                if dbartist:
                    logger.debug('Fanart.tv artist lookup error for %s: %s',
                                 dbartist, e)
                    logger.debug('Stored id for %s is: %s', dbartist, ArtistID)
                else:
                    logger.debug('Fanart.tv artist lookup error for %s: %s',
                                 ArtistID, e)
                return

            album_url = None
            thumb_url = None
            image_url = None

            if data.albums:
                for x in data.albums:
                    if x.mbid == self.id:
                        album_url = str(x.covers[0])

            if album_url:
                thumb_url = album_url.replace('fanart/', 'preview/')
                image_url = thumb_url
                logger.debug('Fanart.tv album url: %s', thumb_url)
            else:
                logger.debug('Fanart.tv no album image found for: %s', self.id)

        # Save the image URL to the database
        if image_url:
            if self.id_type == 'artist':
                myDB.action('UPDATE artists SET ArtworkURL=? WHERE ArtistID=?',
                            [image_url, self.id])
            else:
                myDB.action('UPDATE albums SET ArtworkURL=? WHERE AlbumID=?',
                            [image_url, self.id])

        # Save the thumb URL to the database
        if thumb_url:
            if self.id_type == 'artist':
                myDB.action('UPDATE artists SET ThumbURL=? WHERE ArtistID=?',
                            [thumb_url, self.id])
            else:
                myDB.action('UPDATE albums SET ThumbURL=? WHERE AlbumID=?',
                            [thumb_url, self.id])

        # Should we grab the artwork here if we're just grabbing thumbs or
        # info? Probably not since the files can be quite big

        # With fanart.tv only one url is used for both thumb_url and image_url - so only making one request
        # If seperate ones are desired in the future, the artwork vars below will need to be uncommented

        if image_url is not None:
            artwork = request.request_content(image_url, timeout=20)

        if image_url and self.query_type == 'artwork':
            # artwork = request.request_content(image_url, timeout=20)

            if artwork:
                # Make sure the artwork dir exists:
                if not os.path.isdir(self.path_to_art_cache):
                    try:
                        os.makedirs(self.path_to_art_cache)
                        os.chmod(self.path_to_art_cache,
                                 int(headphones.CONFIG.FOLDER_PERMISSIONS, 8))
                    except OSError as e:
                        logger.error(
                            'Unable to create artwork cache dir. Error: %s', e)
                        self.artwork_errors = True
                        self.artwork_url = image_url

                # Delete the old stuff
                for artwork_file in self.artwork_files:
                    try:
                        os.remove(artwork_file)
                    except:
                        logger.error('Error deleting file from the cache: %s',
                                     artwork_file)

                ext = os.path.splitext(image_url)[1]

                artwork_path = os.path.join(
                    self.path_to_art_cache,
                    self.id + '.' + helpers.today() + ext)
                try:
                    with open(artwork_path, 'wb') as f:
                        f.write(artwork)

                    os.chmod(artwork_path,
                             int(headphones.CONFIG.FILE_PERMISSIONS, 8))
                except (OSError, IOError) as e:
                    logger.error('Unable to write to the cache dir: %s', e)
                    self.artwork_errors = True
                    self.artwork_url = image_url

        # Grab the thumbnail as well if we're getting the full artwork (as long
        # as it's missing/outdated.
        if thumb_url and self.query_type in [
                'thumb', 'artwork'
        ] and not (self.thumb_files and self._is_current(self.thumb_files[0])):
            # artwork = request.request_content(thumb_url, timeout=20)

            if artwork:
                # Make sure the artwork dir exists:
                if not os.path.isdir(self.path_to_art_cache):
                    try:
                        os.makedirs(self.path_to_art_cache)
                        os.chmod(self.path_to_art_cache,
                                 int(headphones.CONFIG.FOLDER_PERMISSIONS, 8))
                    except OSError as e:
                        logger.error(
                            'Unable to create artwork cache dir. Error: %s' +
                            e)
                        self.thumb_errors = True
                        self.thumb_url = thumb_url

                # Delete the old stuff
                for thumb_file in self.thumb_files:
                    try:
                        os.remove(thumb_file)
                    except OSError as e:
                        logger.error('Error deleting file from the cache: %s',
                                     thumb_file)

                ext = os.path.splitext(image_url)[1]

                thumb_path = os.path.join(
                    self.path_to_art_cache,
                    'T_' + self.id + '.' + helpers.today() + ext)
                try:
                    with open(thumb_path, 'wb') as f:
                        f.write(artwork)

                    os.chmod(thumb_path,
                             int(headphones.CONFIG.FILE_PERMISSIONS, 8))
                except (OSError, IOError) as e:
                    logger.error('Unable to write to the cache dir: %s', e)
                    self.thumb_errors = True
                    self.thumb_url = image_url

            dbalbum = myDB.action(
                'SELECT ArtistName, AlbumTitle, ReleaseID, Type FROM albums WHERE AlbumID=?',
                [self.id]).fetchone()
            if dbalbum:
                if dbalbum['ReleaseID'] != self.id:
                    data = lastfm.request_lastfm("album.getinfo",
                                                 mbid=dbalbum['ReleaseID'],
                                                 api_key=LASTFM_API_KEY)
                    if not data:
                        data = lastfm.request_lastfm(
                            "album.getinfo",
                            artist=helpers.clean_musicbrainz_name(
                                dbalbum['ArtistName']),
                            album=helpers.clean_musicbrainz_name(
                                dbalbum['AlbumTitle']),
                            api_key=LASTFM_API_KEY)
                else:
                    if dbalbum['Type'] != "part of":
                        data = lastfm.request_lastfm(
                            "album.getinfo",
                            artist=helpers.clean_musicbrainz_name(
                                dbalbum['ArtistName']),
                            album=helpers.clean_musicbrainz_name(
                                dbalbum['AlbumTitle']),
                            api_key=LASTFM_API_KEY)
                    else:
                        # Series, use actual artist for the release-group
                        artist = mb.getArtistForReleaseGroup(self.id)
                        if artist:
                            data = lastfm.request_lastfm(
                                "album.getinfo",
                                artist=helpers.clean_musicbrainz_name(artist),
                                album=helpers.clean_musicbrainz_name(
                                    dbalbum['AlbumTitle']),
                                api_key=LASTFM_API_KEY)

            if not data:
                logger.debug('Last.fm connection cannot be made')

            try:
                self.info_summary = data['album']['wiki']['summary']
            except KeyError:
                logger.debug('No album summary found')
                self.info_summary = None
            try:
                self.info_content = data['album']['wiki']['content']
            except KeyError:
                logger.debug('No album infomation found')
                self.info_content = None

        # Save the content & summary to the database no matter what if we've
        # opened up the url
        if self.id_type == 'artist':
            controlValueDict = {"ArtistID": self.id}
        else:
            controlValueDict = {"ReleaseGroupID": self.id}

        newValueDict = {
            "Summary": self.info_summary,
            "Content": self.info_content,
            "LastUpdated": helpers.today()
        }

        myDB.upsert("descriptions", newValueDict, controlValueDict)
Exemple #8
0
                logger.error("Track file is not writeable, which is required for some post processing steps: %s", downloaded_track.decode(headphones.SYS_ENCODING, 'replace'))
                return

    #start encoding
    if headphones.MUSIC_ENCODER:
        downloaded_track_list=music_encoder.encode(albumpath)
       
        if not downloaded_track_list:
            return

    artwork = None
    album_art_path = albumart.getAlbumArt(albumid)
    if headphones.EMBED_ALBUM_ART or headphones.ADD_ALBUM_ART:
        
        if album_art_path:
            artwork = request.request_content(album_art_path)
        else:
            artwork = None

        if not album_art_path or not artwork or len(artwork) < 100:
            logger.info("No suitable album art found from Amazon. Checking Last.FM....")
            artwork = albumart.getCachedArt(albumid)
            if not artwork or len(artwork) < 100:
                artwork = False
                logger.info("No suitable album art found from Last.FM. Not adding album art")
    
    if headphones.EMBED_ALBUM_ART and artwork:
        embedAlbumArt(artwork, downloaded_track_list)
    
    if headphones.CLEANUP_FILES:
        cleanupFiles(albumpath)
Exemple #9
0
 def _send(self, data):
     return request.request_content('https://www.notifymyandroid.com/publicapi/notify', data=data)
Exemple #10
0
                ext = os.path.splitext(image_url)[1]

                artwork_path = os.path.join(self.path_to_art_cache, self.id + '.' + helpers.today() + ext)
                try:
                    f = open(artwork_path, 'wb')
                    f.write(artwork)
                    f.close()
                except Exception, e:
                    logger.error('Unable to write to the cache dir: %s', e)
                    self.artwork_errors = True
                    self.artwork_url = image_url

        # Grab the thumbnail as well if we're getting the full artwork (as long as it's missing/outdated
        if thumb_url and self.query_type in ['thumb','artwork'] and not (self.thumb_files and self._is_current(self.thumb_files[0])):
            artwork = request.request_content(thumb_url, timeout=20)

            if artwork:
                # Make sure the artwork dir exists:
                if not os.path.isdir(self.path_to_art_cache):
                    try:
                        os.makedirs(self.path_to_art_cache)
                    except Exception, e:
                        logger.error('Unable to create artwork cache dir. Error: %s' + e)
                        self.thumb_errors = True
                        self.thumb_url = thumb_url

                #Delete the old stuff
                for thumb_file in self.thumb_files:
                    try:
                        os.remove(thumb_file)
Exemple #11
0
    def _update_cache(self):
        '''
        Since we call the same url for both info and artwork, we'll update both at the same time
        '''
        myDB = db.DBConnection()

        # Since lastfm uses release ids rather than release group ids for albums, we have to do a artist + album search for albums
        if self.id_type == 'artist':

            data = lastfm.request_lastfm("artist.getinfo",
                                         mbid=self.id,
                                         api_key=lastfm_apikey)

            if not data:
                return

            try:
                self.info_summary = data['artist']['bio']['summary']
            except Exception:
                logger.debug('No artist bio summary found')
                self.info_summary = None
            try:
                self.info_content = data['artist']['bio']['content']
            except Exception:
                logger.debug('No artist bio found')
                self.info_content = None
            try:
                image_url = data['artist']['image'][-1]['#text']
            except Exception:
                logger.debug('No artist image found')
                image_url = None

            thumb_url = self._get_thumb_url(data)
            if not thumb_url:
                logger.debug('No artist thumbnail image found')

        else:

            dbartist = myDB.action(
                'SELECT ArtistName, AlbumTitle FROM albums WHERE AlbumID=?',
                [self.id]).fetchone()
            data = lastfm.request_lastfm("album.getinfo",
                                         artist=dbartist['ArtistName'],
                                         album=dbartist['AlbumTitle'],
                                         api_key=lastfm_apikey)

            if not data:
                return

            try:
                self.info_summary = data['album']['wiki']['summary']
            except Exception:
                logger.debug('No album summary found')
                self.info_summary = None
            try:
                self.info_content = data['album']['wiki']['content']
            except Exception:
                logger.debug('No album infomation found')
                self.info_content = None
            try:
                image_url = data['album']['image'][-1]['#text']
            except Exception:
                logger.debug('No album image link found')
                image_url = None

            thumb_url = self._get_thumb_url(data)

            if not thumb_url:
                logger.debug('No album thumbnail image found')

        #Save the content & summary to the database no matter what if we've opened up the url
        if self.id_type == 'artist':
            controlValueDict = {"ArtistID": self.id}
        else:
            controlValueDict = {"ReleaseGroupID": self.id}

        newValueDict = {
            "Summary": self.info_summary,
            "Content": self.info_content,
            "LastUpdated": helpers.today()
        }

        myDB.upsert("descriptions", newValueDict, controlValueDict)

        # Save the image URL to the database
        if image_url:
            if self.id_type == 'artist':
                myDB.action('UPDATE artists SET ArtworkURL=? WHERE ArtistID=?',
                            [image_url, self.id])
            else:
                myDB.action('UPDATE albums SET ArtworkURL=? WHERE AlbumID=?',
                            [image_url, self.id])

        # Save the thumb URL to the database
        if thumb_url:
            if self.id_type == 'artist':
                myDB.action('UPDATE artists SET ThumbURL=? WHERE ArtistID=?',
                            [thumb_url, self.id])
            else:
                myDB.action('UPDATE albums SET ThumbURL=? WHERE AlbumID=?',
                            [thumb_url, self.id])

        # Should we grab the artwork here if we're just grabbing thumbs or info?? Probably not since the files can be quite big
        if image_url and self.query_type == 'artwork':
            artwork = request.request_content(image_url, timeout=20)

            if artwork:
                # Make sure the artwork dir exists:
                if not os.path.isdir(self.path_to_art_cache):
                    try:
                        os.makedirs(self.path_to_art_cache)
                    except Exception, e:
                        logger.error(
                            'Unable to create artwork cache dir. Error: %s', e)
                        self.artwork_errors = True
                        self.artwork_url = image_url

                #Delete the old stuff
                for artwork_file in self.artwork_files:
                    try:
                        os.remove(artwork_file)
                    except:
                        logger.error('Error deleting file from the cache: %s',
                                     artwork_file)

                ext = os.path.splitext(image_url)[1]

                artwork_path = os.path.join(
                    self.path_to_art_cache,
                    self.id + '.' + helpers.today() + ext)
                try:
                    f = open(artwork_path, 'wb')
                    f.write(artwork)
                    f.close()
                except Exception, e:
                    logger.error('Unable to write to the cache dir: %s', e)
                    self.artwork_errors = True
                    self.artwork_url = image_url
Exemple #12
0
                    self.path_to_art_cache,
                    self.id + '.' + helpers.today() + ext)
                try:
                    f = open(artwork_path, 'wb')
                    f.write(artwork)
                    f.close()
                except Exception, e:
                    logger.error('Unable to write to the cache dir: %s', e)
                    self.artwork_errors = True
                    self.artwork_url = image_url

        # Grab the thumbnail as well if we're getting the full artwork (as long as it's missing/outdated
        if thumb_url and self.query_type in [
                'thumb', 'artwork'
        ] and not (self.thumb_files and self._is_current(self.thumb_files[0])):
            artwork = request.request_content(thumb_url, timeout=20)

            if artwork:
                # Make sure the artwork dir exists:
                if not os.path.isdir(self.path_to_art_cache):
                    try:
                        os.makedirs(self.path_to_art_cache)
                    except Exception, e:
                        logger.error(
                            'Unable to create artwork cache dir. Error: %s' +
                            e)
                        self.thumb_errors = True
                        self.thumb_url = thumb_url

                #Delete the old stuff
                for thumb_file in self.thumb_files:
Exemple #13
0
class Cache(object):
    """
    This class deals with getting, storing and serving up artwork (album
    art, artist images, etc) and info/descriptions (album info, artist descrptions)
    to and from the cache folder. This can be called from within a web interface,
    for example, using the helper functions getInfo(id) and getArtwork(id), to utilize the cached
    images rather than having to retrieve them every time the page is reloaded.

    So you can call cache.getArtwork(id) which will return an absolute path
    to the image file on the local machine, or if the cache directory
    doesn't exist, or can not be written to, it will return a url to the image.

    Call cache.getInfo(id) to grab the artist/album info; will return the text description

    The basic format for art in the cache is <musicbrainzid>.<date>.<ext>
    and for info it is <musicbrainzid>.<date>.txt
    """

    path_to_art_cache = os.path.join(headphones.CACHE_DIR, 'artwork')

    def __init__(self):
        self.id = None
        self.id_type = None # 'artist' or 'album' - set automatically depending on whether ArtistID or AlbumID is passed
        self.query_type = None # 'artwork','thumb' or 'info' - set automatically

        self.artwork_files = []
        self.thumb_files = []

        self.artwork_errors = False
        self.artwork_url = None

        self.thumb_errors = False
        self.thumb_url = None

        self.info_summary = None
        self.info_content = None

    def _findfilesstartingwith(self,pattern,folder):
        files = []
        if os.path.exists(folder):
            for fname in os.listdir(folder):
                if fname.startswith(pattern):
                    files.append(os.path.join(folder,fname))
        return files

    def _exists(self, type):
        self.artwork_files = []
        self.thumb_files = []

        if type == 'artwork':
            self.artwork_files = self._findfilesstartingwith(self.id,self.path_to_art_cache)
            if self.artwork_files:
                return True
            else:
                return False

        elif type == 'thumb':
            self.thumb_files = self._findfilesstartingwith("T_" + self.id,self.path_to_art_cache)
            if self.thumb_files:
                return True
            else:
                return False

    def _get_age(self, date):
        # There's probably a better way to do this
        split_date = date.split('-')
        days_old = int(split_date[0])*365 + int(split_date[1])*30 + int(split_date[2])

        return days_old


    def _is_current(self, filename=None, date=None):

        if filename:
            base_filename = os.path.basename(filename)
            date = base_filename.split('.')[1]

        # Calculate how old the cached file is based on todays date & file date stamp
        # helpers.today() returns todays date in yyyy-mm-dd format
        if self._get_age(helpers.today()) - self._get_age(date) < 30:
            return True
        else:
            return False

    def _get_thumb_url(self, data):

        thumb_url = None

        try:
            images = data[self.id_type]['image']
        except KeyError:
            return None

        for image in images:
            if image['size'] == 'medium':
                thumb_url = image['#text']
                break

        return thumb_url

    def get_artwork_from_cache(self, ArtistID=None, AlbumID=None):
        """
        Pass a musicbrainz id to this function (either ArtistID or AlbumID)
        """

        self.query_type = 'artwork'

        if ArtistID:
            self.id = ArtistID
            self.id_type = 'artist'
        else:
            self.id = AlbumID
            self.id_type = 'album'

        if self._exists('artwork') and self._is_current(filename=self.artwork_files[0]):
            return self.artwork_files[0]
        else:
            self._update_cache()
            # If we failed to get artwork, either return the url or the older file
            if self.artwork_errors and self.artwork_url:
                return self.artwork_url
            elif self._exists('artwork'):
                return self.artwork_files[0]
            else:
                return None

    def get_thumb_from_cache(self, ArtistID=None, AlbumID=None):
        """
        Pass a musicbrainz id to this function (either ArtistID or AlbumID)
        """

        self.query_type = 'thumb'

        if ArtistID:
            self.id = ArtistID
            self.id_type = 'artist'
        else:
            self.id = AlbumID
            self.id_type = 'album'

        if self._exists('thumb') and self._is_current(filename=self.thumb_files[0]):
            return self.thumb_files[0]
        else:
            self._update_cache()
            # If we failed to get artwork, either return the url or the older file
            if self.thumb_errors and self.thumb_url:
                return self.thumb_url
            elif self._exists('thumb'):
                return self.thumb_files[0]
            else:
                return None

    def get_info_from_cache(self, ArtistID=None, AlbumID=None):

        self.query_type = 'info'
        myDB = db.DBConnection()

        if ArtistID:
            self.id = ArtistID
            self.id_type = 'artist'
            db_info = myDB.action('SELECT Summary, Content, LastUpdated FROM descriptions WHERE ArtistID=?', [self.id]).fetchone()
        else:
            self.id = AlbumID
            self.id_type = 'album'
            db_info = myDB.action('SELECT Summary, Content, LastUpdated FROM descriptions WHERE ReleaseGroupID=?', [self.id]).fetchone()

        if not db_info or not db_info['LastUpdated'] or not self._is_current(date=db_info['LastUpdated']):

            self._update_cache()
            info_dict = { 'Summary' : self.info_summary, 'Content' : self.info_content }
            return info_dict

        else:
            info_dict = { 'Summary' : db_info['Summary'], 'Content' : db_info['Content'] }
            return info_dict

    def get_image_links(self, ArtistID=None, AlbumID=None):
        '''
        Here we're just going to open up the last.fm url, grab the image links and return them
        Won't save any image urls, or save the artwork in the cache. Useful for search results, etc.
        '''
        if ArtistID:

            self.id_type = 'artist'
            data = lastfm.request_lastfm("artist.getinfo", mbid=ArtistID, api_key=LASTFM_API_KEY)

            if not data:
                return

            try:
                image_url = data['artist']['image'][-1]['#text']
            except (KeyError, IndexError):
                logger.debug('No artist image found')
                image_url = None

            thumb_url = self._get_thumb_url(data)
            if not thumb_url:
                logger.debug('No artist thumbnail image found')

        else:

            self.id_type = 'album'
            data = lastfm.request_lastfm("album.getinfo", mbid=AlbumID, api_key=LASTFM_API_KEY)

            if not data:
                return

            try:
                image_url = data['album']['image'][-1]['#text']
            except (KeyError, IndexError):
                logger.debug('No album image found on last.fm')
                image_url = None

            thumb_url = self._get_thumb_url(data)

            if not thumb_url:
                logger.debug('No album thumbnail image found on last.fm')

        return {'artwork' : image_url, 'thumbnail' : thumb_url }

    def _update_cache(self):
        '''
        Since we call the same url for both info and artwork, we'll update both at the same time
        '''
        myDB = db.DBConnection()

        # Since lastfm uses release ids rather than release group ids for albums, we have to do a artist + album search for albums
        if self.id_type == 'artist':

            data = lastfm.request_lastfm("artist.getinfo", mbid=self.id, api_key=LASTFM_API_KEY)

            if not data:
                return

            try:
                self.info_summary = data['artist']['bio']['summary']
            except KeyError:
                logger.debug('No artist bio summary found')
                self.info_summary = None
            try:
                self.info_content = data['artist']['bio']['content']
            except KeyError:
                logger.debug('No artist bio found')
                self.info_content = None
            try:
                image_url = data['artist']['image'][-1]['#text']
            except KeyError:
                logger.debug('No artist image found')
                image_url = None

            thumb_url = self._get_thumb_url(data)
            if not thumb_url:
                logger.debug('No artist thumbnail image found')

        else:

            dbartist = myDB.action('SELECT ArtistName, AlbumTitle FROM albums WHERE AlbumID=?', [self.id]).fetchone()
            data = lastfm.request_lastfm("album.getinfo", artist=dbartist['ArtistName'], album=dbartist['AlbumTitle'], api_key=LASTFM_API_KEY)

            if not data:
                return

            try:
                self.info_summary = data['album']['wiki']['summary']
            except KeyError:
                logger.debug('No album summary found')
                self.info_summary = None
            try:
                self.info_content = data['album']['wiki']['content']
            except KeyError:
                logger.debug('No album infomation found')
                self.info_content = None
            try:
                image_url = data['album']['image'][-1]['#text']
            except KeyError:
                logger.debug('No album image link found')
                image_url = None

            thumb_url = self._get_thumb_url(data)

            if not thumb_url:
                logger.debug('No album thumbnail image found')

        #Save the content & summary to the database no matter what if we've opened up the url
        if self.id_type == 'artist':
            controlValueDict = {"ArtistID":     self.id}
        else:
            controlValueDict = {"ReleaseGroupID":     self.id}

        newValueDict = {"Summary":       self.info_summary,
                        "Content":       self.info_content,
                        "LastUpdated":   helpers.today()}

        myDB.upsert("descriptions", newValueDict, controlValueDict)

        # Save the image URL to the database
        if image_url:
            if self.id_type == 'artist':
                myDB.action('UPDATE artists SET ArtworkURL=? WHERE ArtistID=?', [image_url, self.id])
            else:
                myDB.action('UPDATE albums SET ArtworkURL=? WHERE AlbumID=?', [image_url, self.id])

        # Save the thumb URL to the database
        if thumb_url:
            if self.id_type == 'artist':
                myDB.action('UPDATE artists SET ThumbURL=? WHERE ArtistID=?', [thumb_url, self.id])
            else:
                myDB.action('UPDATE albums SET ThumbURL=? WHERE AlbumID=?', [thumb_url, self.id])

        # Should we grab the artwork here if we're just grabbing thumbs or info?? Probably not since the files can be quite big
        if image_url and self.query_type == 'artwork':
            artwork = request.request_content(image_url, timeout=20)

            if artwork:
                # Make sure the artwork dir exists:
                if not os.path.isdir(self.path_to_art_cache):
                    try:
                        os.makedirs(self.path_to_art_cache)
                    except Exception, e:
                        logger.error('Unable to create artwork cache dir. Error: %s', e)
                        self.artwork_errors = True
                        self.artwork_url = image_url

                #Delete the old stuff
                for artwork_file in self.artwork_files:
                    try:
                        os.remove(artwork_file)
                    except:
                        logger.error('Error deleting file from the cache: %s', artwork_file)

                ext = os.path.splitext(image_url)[1]

                artwork_path = os.path.join(self.path_to_art_cache, self.id + '.' + helpers.today() + ext)
                try:
                    with open(artwork_path, 'wb') as f:
                        f.write(artwork)
                except IOError as e:
                    logger.error('Unable to write to the cache dir: %s', e)
                    self.artwork_errors = True
                    self.artwork_url = image_url

        # Grab the thumbnail as well if we're getting the full artwork (as long as it's missing/outdated
        if thumb_url and self.query_type in ['thumb','artwork'] and not (self.thumb_files and self._is_current(self.thumb_files[0])):
            artwork = request.request_content(thumb_url, timeout=20)

            if artwork:
                # Make sure the artwork dir exists:
                if not os.path.isdir(self.path_to_art_cache):
                    try:
                        os.makedirs(self.path_to_art_cache)
                    except Exception as e:
                        logger.error('Unable to create artwork cache dir. Error: %s' + e)
                        self.thumb_errors = True
                        self.thumb_url = thumb_url

                #Delete the old stuff
                for thumb_file in self.thumb_files:
                    try:
                        os.remove(thumb_file)
                    except Exception as e:
                        logger.error('Error deleting file from the cache: %s', thumb_file)

                ext = os.path.splitext(image_url)[1]

                thumb_path = os.path.join(self.path_to_art_cache, 'T_' + self.id + '.' + helpers.today() + ext)
                try:
                    with open(thumb_path, 'wb') as f:
                        f.write(artwork)
                except IOError as e:
                    logger.error('Unable to write to the cache dir: %s', e)
                    self.thumb_errors = True
                    self.thumb_url = image_url
Exemple #14
0
    def _update_cache(self):
        """
        Since we call the same url for both info and artwork, we'll update both at the same time
        """

        myDB = db.DBConnection()
        fanart = False

        # Since lastfm uses release ids rather than release group ids for albums, we have to do a artist + album search for albums
        # Exception is when adding albums manually, then we should use release id
        if self.id_type == 'artist':

            data = lastfm.request_lastfm("artist.getinfo",
                                         mbid=self.id,
                                         api_key=LASTFM_API_KEY)

            # Try with name if not found
            if not data:
                dbartist = myDB.action(
                    'SELECT ArtistName, Type FROM artists WHERE ArtistID=?',
                    [self.id]).fetchone()
                if dbartist:
                    data = lastfm.request_lastfm(
                        "artist.getinfo",
                        artist=helpers.clean_musicbrainz_name(
                            dbartist['ArtistName']),
                        api_key=LASTFM_API_KEY)

            if not data:
                return

            try:
                self.info_summary = data['artist']['bio']['summary']
            except KeyError:
                logger.debug('No artist bio summary found')
                self.info_summary = None
            try:
                self.info_content = data['artist']['bio']['content']
            except KeyError:
                logger.debug('No artist bio found')
                self.info_content = None

            # 2019 last.fm no longer allows access to artist images, try fanart.tv instead
            image_url = None
            thumb_url = None
            data = request.request_json(FANART_URL + self.id,
                                        whitelist_status_code=404,
                                        headers={
                                            'api-key': FANART_PROJECT_KEY,
                                            'client-key': FANART_CLIENT_KEY
                                        })

            if data.get('artistthumb'):
                image_url = data['artistthumb'][0]['url']
            elif data.get('artistbackground'):
                image_url = data['artistbackground'][0]['url']
            # elif data.get('hdmusiclogo'):
            #    image_url = data['hdmusiclogo'][0]['url']

            # fallback to 1st album cover if none of the above
            elif 'albums' in data:
                for mbid, art in data.get('albums', dict()).items():
                    if 'albumcover' in art:
                        image_url = art['albumcover'][0]['url']
                        break

            # finally, use 1st album cover from last.fm
            if image_url:
                fanart = True
                thumb_url = image_url
            else:
                dbalbum = myDB.action(
                    'SELECT ArtworkURL, ThumbURL FROM albums WHERE ArtworkURL IS NOT NULL AND ArtistID=?',
                    [self.id]).fetchone()
                if dbalbum:
                    fanart = True
                    image_url = dbalbum['ArtworkURL']
                    thumb_url = dbalbum['ThumbURL']

            if not image_url:
                logger.debug(
                    'No artist image found on fanart.tv for Artist Id: %s',
                    self.id)

        else:
            dbalbum = myDB.action(
                'SELECT ArtistName, AlbumTitle, ReleaseID, Type FROM albums WHERE AlbumID=?',
                [self.id]).fetchone()
            if dbalbum['ReleaseID'] != self.id:
                data = lastfm.request_lastfm("album.getinfo",
                                             mbid=dbalbum['ReleaseID'],
                                             api_key=LASTFM_API_KEY)
                if not data:
                    data = lastfm.request_lastfm(
                        "album.getinfo",
                        artist=helpers.clean_musicbrainz_name(
                            dbalbum['ArtistName']),
                        album=helpers.clean_musicbrainz_name(
                            dbalbum['AlbumTitle']),
                        api_key=LASTFM_API_KEY)
            else:
                if dbalbum['Type'] != "part of":
                    data = lastfm.request_lastfm(
                        "album.getinfo",
                        artist=helpers.clean_musicbrainz_name(
                            dbalbum['ArtistName']),
                        album=helpers.clean_musicbrainz_name(
                            dbalbum['AlbumTitle']),
                        api_key=LASTFM_API_KEY)
                else:

                    # Series, use actual artist for the release-group
                    artist = mb.getArtistForReleaseGroup(self.id)
                    if artist:
                        data = lastfm.request_lastfm(
                            "album.getinfo",
                            artist=helpers.clean_musicbrainz_name(artist),
                            album=helpers.clean_musicbrainz_name(
                                dbalbum['AlbumTitle']),
                            api_key=LASTFM_API_KEY)

            if not data:
                return

            try:
                self.info_summary = data['album']['wiki']['summary']
            except KeyError:
                logger.debug('No album summary found')
                self.info_summary = None
            try:
                self.info_content = data['album']['wiki']['content']
            except KeyError:
                logger.debug('No album infomation found')
                self.info_content = None
            try:
                image_url = data['album']['image'][-1]['#text']
            except KeyError:
                logger.debug('No album image link found')
                image_url = None

            thumb_url = self._get_thumb_url(data)

            if not thumb_url:
                logger.debug('No album thumbnail image found')

        # Save the content & summary to the database no matter what if we've
        # opened up the url
        if self.id_type == 'artist':
            controlValueDict = {"ArtistID": self.id}
        else:
            controlValueDict = {"ReleaseGroupID": self.id}

        newValueDict = {
            "Summary": self.info_summary,
            "Content": self.info_content,
            "LastUpdated": helpers.today()
        }

        myDB.upsert("descriptions", newValueDict, controlValueDict)

        # Save the image URL to the database
        if image_url:
            if self.id_type == 'artist':
                myDB.action('UPDATE artists SET ArtworkURL=? WHERE ArtistID=?',
                            [image_url, self.id])
            else:
                myDB.action('UPDATE albums SET ArtworkURL=? WHERE AlbumID=?',
                            [image_url, self.id])

        # Save the thumb URL to the database
        if thumb_url:
            if self.id_type == 'artist':
                myDB.action('UPDATE artists SET ThumbURL=? WHERE ArtistID=?',
                            [thumb_url, self.id])
            else:
                myDB.action('UPDATE albums SET ThumbURL=? WHERE AlbumID=?',
                            [thumb_url, self.id])

        # Should we grab the artwork here if we're just grabbing thumbs or
        # info? Probably not since the files can be quite big
        if image_url and self.query_type == 'artwork':
            artwork = request.request_content(image_url, timeout=20)

            if artwork:
                # Make sure the artwork dir exists:
                if not os.path.isdir(self.path_to_art_cache):
                    try:
                        os.makedirs(self.path_to_art_cache)
                        os.chmod(self.path_to_art_cache,
                                 int(headphones.CONFIG.FOLDER_PERMISSIONS, 8))
                    except OSError as e:
                        logger.error(
                            'Unable to create artwork cache dir. Error: %s', e)
                        self.artwork_errors = True
                        self.artwork_url = image_url

                # Delete the old stuff
                for artwork_file in self.artwork_files:
                    try:
                        os.remove(artwork_file)
                    except:
                        logger.error('Error deleting file from the cache: %s',
                                     artwork_file)

                ext = os.path.splitext(image_url)[1]

                if fanart:
                    artwork_path = os.path.join(
                        self.path_to_art_cache,
                        self.id + '_fanart_' + '.' + helpers.today() + ext)
                else:
                    artwork_path = os.path.join(
                        self.path_to_art_cache,
                        self.id + '.' + helpers.today() + ext)
                try:
                    with open(artwork_path, 'wb') as f:
                        f.write(artwork)

                    os.chmod(artwork_path,
                             int(headphones.CONFIG.FILE_PERMISSIONS, 8))
                except (OSError, IOError) as e:
                    logger.error('Unable to write to the cache dir: %s', e)
                    self.artwork_errors = True
                    self.artwork_url = image_url

        # Grab the thumbnail as well if we're getting the full artwork (as long
        # as it's missing/outdated.
        if thumb_url and self.query_type in [
                'thumb', 'artwork'
        ] and not (self.thumb_files and self._is_current(self.thumb_files[0])):

            if not (self.query_type == 'artwork' and 'fanart' in thumb_url
                    and artwork):
                artwork = request.request_content(thumb_url, timeout=20)

            if artwork:
                # Make sure the artwork dir exists:
                if not os.path.isdir(self.path_to_art_cache):
                    try:
                        os.makedirs(self.path_to_art_cache)
                        os.chmod(self.path_to_art_cache,
                                 int(headphones.CONFIG.FOLDER_PERMISSIONS, 8))
                    except OSError as e:
                        logger.error(
                            'Unable to create artwork cache dir. Error: %s' +
                            e)
                        self.thumb_errors = True
                        self.thumb_url = thumb_url

                # Delete the old stuff
                for thumb_file in self.thumb_files:
                    try:
                        os.remove(thumb_file)
                    except OSError as e:
                        logger.error('Error deleting file from the cache: %s',
                                     thumb_file)

                ext = os.path.splitext(image_url)[1]

                if fanart:
                    thumb_path = os.path.join(
                        self.path_to_art_cache, 'T_' + self.id + '_fanart_' +
                        '.' + helpers.today() + ext)
                else:
                    thumb_path = os.path.join(
                        self.path_to_art_cache,
                        'T_' + self.id + '.' + helpers.today() + ext)
                try:
                    if self.id_type != 'artist':
                        with open(thumb_path, 'wb') as f:
                            f.write(artwork)
                    else:

                        # 2019 last.fm no longer allows access to artist images, use the fanart.tv image to create a thumb
                        artwork_thumb = None
                        if 'fanart' in thumb_url:
                            # Create thumb using image resizing service
                            artwork_path = '{0}?{1}'.format(
                                'http://images.weserv.nl/',
                                urlencode({
                                    'url':
                                    thumb_url.replace('http://', ''),
                                    'w':
                                    300,
                                }))
                            artwork_thumb = request.request_content(
                                artwork_path,
                                timeout=20,
                                whitelist_status_code=404)

                        if artwork_thumb:
                            with open(thumb_path, 'wb') as f:
                                f.write(artwork_thumb)
                        else:
                            with open(thumb_path, 'wb') as f:
                                f.write(artwork)

                    os.chmod(thumb_path,
                             int(headphones.CONFIG.FILE_PERMISSIONS, 8))
                except (OSError, IOError) as e:
                    logger.error('Unable to write to the cache dir: %s', e)
                    self.thumb_errors = True
                    self.thumb_url = image_url
Exemple #15
0
def update():
    if headphones.INSTALL_TYPE == "win":
        logger.info("Windows .exe updating not supported yet.")

    elif headphones.INSTALL_TYPE == "git":
        output, err = runGit("pull origin " + headphones.CONFIG.GIT_BRANCH)

        if not output:
            logger.error("Couldn't download latest version")

        for line in output.split("\n"):

            if "Already up-to-date." in line:
                logger.info("No update available, not updating")
                logger.info("Output: " + str(output))
            elif line.endswith("Aborting."):
                logger.error("Unable to update from git: " + line)
                logger.info("Output: " + str(output))

    else:
        tar_download_url = "https://github.com/%s/headphones/tarball/%s" % (
            headphones.CONFIG.GIT_USER,
            headphones.CONFIG.GIT_BRANCH,
        )
        update_dir = os.path.join(headphones.PROG_DIR, "update")
        version_path = os.path.join(headphones.PROG_DIR, "version.txt")

        logger.info("Downloading update from: " + tar_download_url)
        data = request.request_content(tar_download_url)

        if not data:
            logger.error("Unable to retrieve new version from '%s', can't update", tar_download_url)
            return

        download_name = headphones.CONFIG.GIT_BRANCH + "-github"
        tar_download_path = os.path.join(headphones.PROG_DIR, download_name)

        # Save tar to disk
        with open(tar_download_path, "wb") as f:
            f.write(data)

        # Extract the tar to update folder
        logger.info("Extracting file: " + tar_download_path)
        tar = tarfile.open(tar_download_path)
        tar.extractall(update_dir)
        tar.close()

        # Delete the tar.gz
        logger.info("Deleting file: " + tar_download_path)
        os.remove(tar_download_path)

        # Find update dir name
        update_dir_contents = [x for x in os.listdir(update_dir) if os.path.isdir(os.path.join(update_dir, x))]
        if len(update_dir_contents) != 1:
            logger.error("Invalid update data, update failed: " + str(update_dir_contents))
            return
        content_dir = os.path.join(update_dir, update_dir_contents[0])

        # walk temp folder and move files to main folder
        for dirname, dirnames, filenames in os.walk(content_dir):
            dirname = dirname[len(content_dir) + 1 :]
            for curfile in filenames:
                old_path = os.path.join(content_dir, dirname, curfile)
                new_path = os.path.join(headphones.PROG_DIR, dirname, curfile)

                if os.path.isfile(new_path):
                    os.remove(new_path)
                os.renames(old_path, new_path)

        # Update version.txt
        try:
            with open(version_path, "w") as f:
                f.write(str(headphones.LATEST_VERSION))
        except IOError as e:
            logger.error("Unable to write current version to version.txt, update not complete: %s", e)
            return
Exemple #16
0
    def _update_cache(self):
        """
        Since we call the same url for both info and artwork, we'll update both at the same time
        """

        myDB = db.DBConnection()

        # Since lastfm uses release ids rather than release group ids for albums, we have to do a artist + album search for albums
        # Exception is when adding albums manually, then we should use release id
        if self.id_type == 'artist':

            data = lastfm.request_lastfm("artist.getinfo",
                                         mbid=self.id,
                                         api_key=LASTFM_API_KEY)

            if not data:
                return

            try:
                self.info_summary = data['artist']['bio']['summary']
            except KeyError:
                logger.debug('No artist bio summary found')
                self.info_summary = None
            try:
                self.info_content = data['artist']['bio']['content']
            except KeyError:
                logger.debug('No artist bio found')
                self.info_content = None
            try:
                image_url = data['artist']['image'][-1]['#text']
            except KeyError:
                logger.debug('No artist image found')
                image_url = None

            thumb_url = self._get_thumb_url(data)
            if not thumb_url:
                logger.debug('No artist thumbnail image found')

        else:
            dbalbum = myDB.action(
                'SELECT ArtistName, AlbumTitle, ReleaseID FROM albums WHERE AlbumID=?',
                [self.id]).fetchone()
            if dbalbum['ReleaseID'] != self.id:
                data = lastfm.request_lastfm("album.getinfo",
                                             mbid=dbalbum['ReleaseID'],
                                             api_key=LASTFM_API_KEY)
                if not data:
                    data = lastfm.request_lastfm("album.getinfo",
                                                 artist=dbalbum['ArtistName'],
                                                 album=dbalbum['AlbumTitle'],
                                                 api_key=LASTFM_API_KEY)
            else:
                data = lastfm.request_lastfm("album.getinfo",
                                             artist=dbalbum['ArtistName'],
                                             album=dbalbum['AlbumTitle'],
                                             api_key=LASTFM_API_KEY)

            if not data:
                return

            try:
                self.info_summary = data['album']['wiki']['summary']
            except KeyError:
                logger.debug('No album summary found')
                self.info_summary = None
            try:
                self.info_content = data['album']['wiki']['content']
            except KeyError:
                logger.debug('No album infomation found')
                self.info_content = None
            try:
                image_url = data['album']['image'][-1]['#text']
            except KeyError:
                logger.debug('No album image link found')
                image_url = None

            thumb_url = self._get_thumb_url(data)

            if not thumb_url:
                logger.debug('No album thumbnail image found')

        # Save the content & summary to the database no matter what if we've
        # opened up the url
        if self.id_type == 'artist':
            controlValueDict = {"ArtistID": self.id}
        else:
            controlValueDict = {"ReleaseGroupID": self.id}

        newValueDict = {
            "Summary": self.info_summary,
            "Content": self.info_content,
            "LastUpdated": helpers.today()
        }

        myDB.upsert("descriptions", newValueDict, controlValueDict)

        # Save the image URL to the database
        if image_url:
            if self.id_type == 'artist':
                myDB.action('UPDATE artists SET ArtworkURL=? WHERE ArtistID=?',
                            [image_url, self.id])
            else:
                myDB.action('UPDATE albums SET ArtworkURL=? WHERE AlbumID=?',
                            [image_url, self.id])

        # Save the thumb URL to the database
        if thumb_url:
            if self.id_type == 'artist':
                myDB.action('UPDATE artists SET ThumbURL=? WHERE ArtistID=?',
                            [thumb_url, self.id])
            else:
                myDB.action('UPDATE albums SET ThumbURL=? WHERE AlbumID=?',
                            [thumb_url, self.id])

        # Should we grab the artwork here if we're just grabbing thumbs or
        # info? Probably not since the files can be quite big
        if image_url and self.query_type == 'artwork':
            artwork = request.request_content(image_url, timeout=20)

            if artwork:
                # Make sure the artwork dir exists:
                if not os.path.isdir(self.path_to_art_cache):
                    try:
                        os.makedirs(self.path_to_art_cache)
                        os.chmod(self.path_to_art_cache,
                                 int(headphones.CONFIG.FOLDER_PERMISSIONS, 8))
                    except OSError as e:
                        logger.error(
                            'Unable to create artwork cache dir. Error: %s', e)
                        self.artwork_errors = True
                        self.artwork_url = image_url

                # Delete the old stuff
                for artwork_file in self.artwork_files:
                    try:
                        os.remove(artwork_file)
                    except:
                        logger.error('Error deleting file from the cache: %s',
                                     artwork_file)

                ext = os.path.splitext(image_url)[1]

                artwork_path = os.path.join(
                    self.path_to_art_cache,
                    self.id + '.' + helpers.today() + ext)
                try:
                    with open(artwork_path, 'wb') as f:
                        f.write(artwork)

                    os.chmod(artwork_path,
                             int(headphones.CONFIG.FILE_PERMISSIONS, 8))
                except (OSError, IOError) as e:
                    logger.error('Unable to write to the cache dir: %s', e)
                    self.artwork_errors = True
                    self.artwork_url = image_url

        # Grab the thumbnail as well if we're getting the full artwork (as long
        # as it's missing/outdated.
        if thumb_url and self.query_type in [
                'thumb', 'artwork'
        ] and not (self.thumb_files and self._is_current(self.thumb_files[0])):
            artwork = request.request_content(thumb_url, timeout=20)

            if artwork:
                # Make sure the artwork dir exists:
                if not os.path.isdir(self.path_to_art_cache):
                    try:
                        os.makedirs(self.path_to_art_cache)
                        os.chmod(self.path_to_art_cache,
                                 int(headphones.CONFIG.FOLDER_PERMISSIONS, 8))
                    except OSError as e:
                        logger.error(
                            'Unable to create artwork cache dir. Error: %s' +
                            e)
                        self.thumb_errors = True
                        self.thumb_url = thumb_url

                # Delete the old stuff
                for thumb_file in self.thumb_files:
                    try:
                        os.remove(thumb_file)
                    except OSError as e:
                        logger.error('Error deleting file from the cache: %s',
                                     thumb_file)

                ext = os.path.splitext(image_url)[1]

                thumb_path = os.path.join(
                    self.path_to_art_cache,
                    'T_' + self.id + '.' + helpers.today() + ext)
                try:
                    with open(thumb_path, 'wb') as f:
                        f.write(artwork)

                    os.chmod(thumb_path,
                             int(headphones.CONFIG.FILE_PERMISSIONS, 8))
                except (OSError, IOError) as e:
                    logger.error('Unable to write to the cache dir: %s', e)
                    self.thumb_errors = True
                    self.thumb_url = image_url
Exemple #17
0
def update():
    if headphones.INSTALL_TYPE == 'win':
        logger.info('Windows .exe updating not supported yet.')

    elif headphones.INSTALL_TYPE == 'git':
        output, err = runGit('pull origin ' + headphones.GIT_BRANCH)

        if not output:
            logger.error('Couldn\'t download latest version')

        for line in output.split('\n'):

            if 'Already up-to-date.' in line:
                logger.info('No update available, not updating')
                logger.info('Output: ' + str(output))
            elif line.endswith('Aborting.'):
                logger.error('Unable to update from git: ' + line)
                logger.info('Output: ' + str(output))

    else:
        tar_download_url = 'https://github.com/%s/headphones/tarball/%s' % (
            headphones.GIT_USER, headphones.GIT_BRANCH)
        update_dir = os.path.join(headphones.PROG_DIR, 'update')
        version_path = os.path.join(headphones.PROG_DIR, 'version.txt')

        logger.info('Downloading update from: ' + tar_download_url)
        data = request.request_content(tar_download_url)

        if not data:
            logger.error(
                "Unable to retrieve new version from '%s', can't update",
                tar_download_url)
            return

        download_name = headphones.GIT_BRANCH + '-github'
        tar_download_path = os.path.join(headphones.PROG_DIR, download_name)

        # Save tar to disk
        with open(tar_download_path, 'wb') as f:
            f.write(data)

        # Extract the tar to update folder
        logger.info('Extracting file: ' + tar_download_path)
        tar = tarfile.open(tar_download_path)
        tar.extractall(update_dir)
        tar.close()

        # Delete the tar.gz
        logger.info('Deleting file: ' + tar_download_path)
        os.remove(tar_download_path)

        # Find update dir name
        update_dir_contents = [
            x for x in os.listdir(update_dir)
            if os.path.isdir(os.path.join(update_dir, x))
        ]
        if len(update_dir_contents) != 1:
            logger.error("Invalid update data, update failed: " +
                         str(update_dir_contents))
            return
        content_dir = os.path.join(update_dir, update_dir_contents[0])

        # walk temp folder and move files to main folder
        for dirname, dirnames, filenames in os.walk(content_dir):
            dirname = dirname[len(content_dir) + 1:]
            for curfile in filenames:
                old_path = os.path.join(content_dir, dirname, curfile)
                new_path = os.path.join(headphones.PROG_DIR, dirname, curfile)

                if os.path.isfile(new_path):
                    os.remove(new_path)
                os.renames(old_path, new_path)

        # Update version.txt
        try:
            with open(version_path, 'w') as f:
                f.write(str(headphones.LATEST_VERSION))
        except IOError as e:
            logger.error("Unable to write current version to version.txt, " \
                "update not complete: ", e)
            return
Exemple #18
0
    def _update_cache(self):
        """
        Since we call the same url for both info and artwork, we'll update both at the same time
        """

        myDB = db.DBConnection()

        # Since lastfm uses release ids rather than release group ids for albums, we have to do a artist + album search for albums
        # Exception is when adding albums manually, then we should use release id
        if self.id_type == 'artist':

            data = lastfm.request_lastfm("artist.getinfo", mbid=self.id, api_key=LASTFM_API_KEY)

            if not data:
                return

            try:
                self.info_summary = data['artist']['bio']['summary']
            except KeyError:
                logger.debug('No artist bio summary found')
                self.info_summary = None
            try:
                self.info_content = data['artist']['bio']['content']
            except KeyError:
                logger.debug('No artist bio found')
                self.info_content = None
            try:
                image_url = data['artist']['image'][-1]['#text']
            except KeyError:
                logger.debug('No artist image found')
                image_url = None

            thumb_url = self._get_thumb_url(data)
            if not thumb_url:
                logger.debug('No artist thumbnail image found')

        else:
            dbalbum = myDB.action(
                'SELECT ArtistName, AlbumTitle, ReleaseID FROM albums WHERE AlbumID=?',
                [self.id]).fetchone()
            if dbalbum['ReleaseID'] != self.id:
                data = lastfm.request_lastfm("album.getinfo", mbid=dbalbum['ReleaseID'],
                                             api_key=LASTFM_API_KEY)
                if not data:
                    data = lastfm.request_lastfm("album.getinfo", artist=dbalbum['ArtistName'],
                                                 album=dbalbum['AlbumTitle'],
                                                 api_key=LASTFM_API_KEY)
            else:
                data = lastfm.request_lastfm("album.getinfo", artist=dbalbum['ArtistName'],
                                             album=dbalbum['AlbumTitle'], api_key=LASTFM_API_KEY)

            if not data:
                return

            try:
                self.info_summary = data['album']['wiki']['summary']
            except KeyError:
                logger.debug('No album summary found')
                self.info_summary = None
            try:
                self.info_content = data['album']['wiki']['content']
            except KeyError:
                logger.debug('No album infomation found')
                self.info_content = None
            try:
                image_url = data['album']['image'][-1]['#text']
            except KeyError:
                logger.debug('No album image link found')
                image_url = None

            thumb_url = self._get_thumb_url(data)

            if not thumb_url:
                logger.debug('No album thumbnail image found')

        # Save the content & summary to the database no matter what if we've
        # opened up the url
        if self.id_type == 'artist':
            controlValueDict = {"ArtistID": self.id}
        else:
            controlValueDict = {"ReleaseGroupID": self.id}

        newValueDict = {"Summary": self.info_summary,
                        "Content": self.info_content,
                        "LastUpdated": helpers.today()}

        myDB.upsert("descriptions", newValueDict, controlValueDict)

        # Save the image URL to the database
        if image_url:
            if self.id_type == 'artist':
                myDB.action('UPDATE artists SET ArtworkURL=? WHERE ArtistID=?',
                            [image_url, self.id])
            else:
                myDB.action('UPDATE albums SET ArtworkURL=? WHERE AlbumID=?', [image_url, self.id])

        # Save the thumb URL to the database
        if thumb_url:
            if self.id_type == 'artist':
                myDB.action('UPDATE artists SET ThumbURL=? WHERE ArtistID=?', [thumb_url, self.id])
            else:
                myDB.action('UPDATE albums SET ThumbURL=? WHERE AlbumID=?', [thumb_url, self.id])

        # Should we grab the artwork here if we're just grabbing thumbs or
        # info? Probably not since the files can be quite big
        if image_url and self.query_type == 'artwork':
            artwork = request.request_content(image_url, timeout=20)

            if artwork:
                # Make sure the artwork dir exists:
                if not os.path.isdir(self.path_to_art_cache):
                    try:
                        os.makedirs(self.path_to_art_cache)
                        os.chmod(self.path_to_art_cache,
                                 int(headphones.CONFIG.FOLDER_PERMISSIONS, 8))
                    except OSError as e:
                        logger.error('Unable to create artwork cache dir. Error: %s', e)
                        self.artwork_errors = True
                        self.artwork_url = image_url

                # Delete the old stuff
                for artwork_file in self.artwork_files:
                    try:
                        os.remove(artwork_file)
                    except:
                        logger.error('Error deleting file from the cache: %s', artwork_file)

                ext = os.path.splitext(image_url)[1]

                artwork_path = os.path.join(self.path_to_art_cache,
                                            self.id + '.' + helpers.today() + ext)
                try:
                    with open(artwork_path, 'wb') as f:
                        f.write(artwork)

                    os.chmod(artwork_path, int(headphones.CONFIG.FILE_PERMISSIONS, 8))
                except (OSError, IOError) as e:
                    logger.error('Unable to write to the cache dir: %s', e)
                    self.artwork_errors = True
                    self.artwork_url = image_url

        # Grab the thumbnail as well if we're getting the full artwork (as long
        # as it's missing/outdated.
        if thumb_url and self.query_type in ['thumb', 'artwork'] and not (
            self.thumb_files and self._is_current(self.thumb_files[0])):
            artwork = request.request_content(thumb_url, timeout=20)

            if artwork:
                # Make sure the artwork dir exists:
                if not os.path.isdir(self.path_to_art_cache):
                    try:
                        os.makedirs(self.path_to_art_cache)
                        os.chmod(self.path_to_art_cache,
                                 int(headphones.CONFIG.FOLDER_PERMISSIONS, 8))
                    except OSError as e:
                        logger.error('Unable to create artwork cache dir. Error: %s' + e)
                        self.thumb_errors = True
                        self.thumb_url = thumb_url

                # Delete the old stuff
                for thumb_file in self.thumb_files:
                    try:
                        os.remove(thumb_file)
                    except OSError as e:
                        logger.error('Error deleting file from the cache: %s', thumb_file)

                ext = os.path.splitext(image_url)[1]

                thumb_path = os.path.join(self.path_to_art_cache,
                                          'T_' + self.id + '.' + helpers.today() + ext)
                try:
                    with open(thumb_path, 'wb') as f:
                        f.write(artwork)

                    os.chmod(thumb_path, int(headphones.CONFIG.FILE_PERMISSIONS, 8))
                except (OSError, IOError) as e:
                    logger.error('Unable to write to the cache dir: %s', e)
                    self.thumb_errors = True
                    self.thumb_url = image_url
Exemple #19
0
    def _update_cache(self):
        '''
        Since we call the same url for both info and artwork, we'll update both at the same time
        '''
        myDB = db.DBConnection()

        # Since lastfm uses release ids rather than release group ids for albums, we have to do a artist + album search for albums
        if self.id_type == 'artist':

            data = lastfm.request_lastfm("artist.getinfo", mbid=self.id, api_key=lastfm_apikey)

            if not data:
                return

            try:
                self.info_summary = data['artist']['bio']['summary']
            except Exception:
                logger.debug('No artist bio summary found')
                self.info_summary = None
            try:
                self.info_content = data['artist']['bio']['content']
            except Exception:
                logger.debug('No artist bio found')
                self.info_content = None
            try:
                image_url = data['artist']['image'][-1]['#text']
            except Exception:
                logger.debug('No artist image found')
                image_url = None

            thumb_url = self._get_thumb_url(data)
            if not thumb_url:
                logger.debug('No artist thumbnail image found')

        else:

            dbartist = myDB.action('SELECT ArtistName, AlbumTitle FROM albums WHERE AlbumID=?', [self.id]).fetchone()
            data = lastfm.request_lastfm("album.getinfo", artist=dbartist['ArtistName'], album=dbartist['AlbumTitle'], api_key=lastfm_apikey)

            if not data:
                return

            try:
                self.info_summary = data['album']['wiki']['summary']
            except Exception:
                logger.debug('No album summary found')
                self.info_summary = None
            try:
                self.info_content = data['album']['wiki']['content']
            except Exception:
                logger.debug('No album infomation found')
                self.info_content = None
            try:
                image_url = data['album']['image'][-1]['#text']
            except Exception:
                logger.debug('No album image link found')
                image_url = None

            thumb_url = self._get_thumb_url(data)

            if not thumb_url:
                logger.debug('No album thumbnail image found')

        #Save the content & summary to the database no matter what if we've opened up the url
        if self.id_type == 'artist':
            controlValueDict = {"ArtistID":     self.id}
        else:
            controlValueDict = {"ReleaseGroupID":     self.id}

        newValueDict = {"Summary":       self.info_summary,
                        "Content":       self.info_content,
                        "LastUpdated":   helpers.today()}

        myDB.upsert("descriptions", newValueDict, controlValueDict)

        # Save the image URL to the database
        if image_url:
            if self.id_type == 'artist':
                myDB.action('UPDATE artists SET ArtworkURL=? WHERE ArtistID=?', [image_url, self.id])
            else:
                myDB.action('UPDATE albums SET ArtworkURL=? WHERE AlbumID=?', [image_url, self.id])

        # Save the thumb URL to the database
        if thumb_url:
            if self.id_type == 'artist':
                myDB.action('UPDATE artists SET ThumbURL=? WHERE ArtistID=?', [thumb_url, self.id])
            else:
                myDB.action('UPDATE albums SET ThumbURL=? WHERE AlbumID=?', [thumb_url, self.id])

        # Should we grab the artwork here if we're just grabbing thumbs or info?? Probably not since the files can be quite big
        if image_url and self.query_type == 'artwork':
            artwork = request.request_content(image_url, timeout=20)

            if artwork:
                # Make sure the artwork dir exists:
                if not os.path.isdir(self.path_to_art_cache):
                    try:
                        os.makedirs(self.path_to_art_cache)
                    except Exception, e:
                        logger.error('Unable to create artwork cache dir. Error: %s', e)
                        self.artwork_errors = True
                        self.artwork_url = image_url

                #Delete the old stuff
                for artwork_file in self.artwork_files:
                    try:
                        os.remove(artwork_file)
                    except:
                        logger.error('Error deleting file from the cache: %s', artwork_file)

                ext = os.path.splitext(image_url)[1]

                artwork_path = os.path.join(self.path_to_art_cache, self.id + '.' + helpers.today() + ext)
                try:
                    f = open(artwork_path, 'wb')
                    f.write(artwork)
                    f.close()
                except Exception, e:
                    logger.error('Unable to write to the cache dir: %s', e)
                    self.artwork_errors = True
                    self.artwork_url = image_url
Exemple #20
0
 def _send(self, data):
     return request.request_content(
         'https://www.notifymyandroid.com/publicapi/notify', data=data)