Example #1
0
    def _sendjson(self, host, method, params={}):
        data = [{
            'id': 0,
            'jsonrpc': '2.0',
            'method': method,
            'params': params
        }]
        headers = {'Content-Type': 'application/json'}
        url = host + '/jsonrpc'

        if self.password:
            response = request.request_json(url,
                                            method="post",
                                            data=json.dumps(data),
                                            headers=headers,
                                            auth=(self.username,
                                                  self.password))
        else:
            response = request.request_json(url,
                                            method="post",
                                            data=json.dumps(data),
                                            headers=headers)

        if response:
            return response[0]['result']
Example #2
0
    def _sendjson(self, host, method, params={}):
        data = [{'id': 0, 'jsonrpc': '2.0', 'method': method, 'params': params}]
        headers = {'Content-Type': 'application/json'}
        url = host + '/jsonrpc'

        if self.password:
            response = request.request_json(url, method="POST", data=simplejson.dumps(data), headers=headers, auth=(self.username, self.password))
        else:
            response = request.request_json(url, method="POST", data=simplejson.dumps(data), headers=headers)

        if response:
            return response[0]['result']
Example #3
0
def checkGithub():
    headphones.COMMITS_BEHIND = 0

    # Get the latest version available from github
    logger.info("Retrieving latest version information from GitHub")
    url = "https://api.github.com/repos/%s/headphones/commits/%s" % (
        headphones.CONFIG.GIT_USER,
        headphones.CONFIG.GIT_BRANCH,
    )
    version = request.request_json(url, timeout=20, validator=lambda x: type(x) == dict)

    if version is None:
        logger.warn("Could not get the latest version from GitHub. Are you running a local development version?")
        return headphones.CURRENT_VERSION

    headphones.LATEST_VERSION = version["sha"]
    logger.debug("Latest version is %s", headphones.LATEST_VERSION)

    # See how many commits behind we are
    if not headphones.CURRENT_VERSION:
        logger.info("You are running an unknown version of Headphones. Run the updater to identify your version")
        return headphones.LATEST_VERSION

    if headphones.LATEST_VERSION == headphones.CURRENT_VERSION:
        logger.info("Headphones is up to date")
        return headphones.LATEST_VERSION

    logger.info("Comparing currently installed version with latest GitHub version")
    url = "https://api.github.com/repos/%s/headphones/compare/%s...%s" % (
        headphones.CONFIG.GIT_USER,
        headphones.LATEST_VERSION,
        headphones.CURRENT_VERSION,
    )
    commits = request.request_json(url, timeout=20, whitelist_status_code=404, validator=lambda x: type(x) == dict)

    if commits is None:
        logger.warn("Could not get commits behind from GitHub.")
        return headphones.LATEST_VERSION

    try:
        headphones.COMMITS_BEHIND = int(commits["behind_by"])
        logger.debug("In total, %d commits behind", headphones.COMMITS_BEHIND)
    except KeyError:
        logger.info("Cannot compare versions. Are you running a local development version?")
        headphones.COMMITS_BEHIND = 0

    if headphones.COMMITS_BEHIND > 0:
        logger.info("New version is available. You are %s commits behind" % headphones.COMMITS_BEHIND)
    elif headphones.COMMITS_BEHIND == 0:
        logger.info("Headphones is up to date")

    return headphones.LATEST_VERSION
Example #4
0
def checkGithub():
    headphones.COMMITS_BEHIND = 0

    # Get the latest version available from github
    logger.info('Retrieving latest version information from GitHub')
    url = 'https://api.github.com/repos/%s/headphones/commits/%s' % (
    headphones.CONFIG.GIT_USER, headphones.CONFIG.GIT_BRANCH)
    version = request.request_json(url, timeout=20, validator=lambda x: type(x) == dict)

    if version is None:
        logger.warn(
            'Could not get the latest version from GitHub. Are you running a local development version?')
        return headphones.CURRENT_VERSION

    headphones.LATEST_VERSION = version['sha']
    logger.debug("Latest version is %s", headphones.LATEST_VERSION)

    # See how many commits behind we are
    if not headphones.CURRENT_VERSION:
        logger.info(
            'You are running an unknown version of Headphones. Run the updater to identify your version')
        return headphones.LATEST_VERSION

    if headphones.LATEST_VERSION == headphones.CURRENT_VERSION:
        logger.info('Headphones is up to date')
        return headphones.LATEST_VERSION

    logger.info('Comparing currently installed version with latest GitHub version')
    url = 'https://api.github.com/repos/%s/headphones/compare/%s...%s' % (
    headphones.CONFIG.GIT_USER, headphones.LATEST_VERSION, headphones.CURRENT_VERSION)
    commits = request.request_json(url, timeout=20, whitelist_status_code=404,
                                   validator=lambda x: type(x) == dict)

    if commits is None:
        logger.warn('Could not get commits behind from GitHub.')
        return headphones.LATEST_VERSION

    try:
        headphones.COMMITS_BEHIND = int(commits['behind_by'])
        logger.debug("In total, %d commits behind", headphones.COMMITS_BEHIND)
    except KeyError:
        logger.info('Cannot compare versions. Are you running a local development version?')
        headphones.COMMITS_BEHIND = 0

    if headphones.COMMITS_BEHIND > 0:
        logger.info(
            'New version is available. You are %s commits behind' % headphones.COMMITS_BEHIND)
    elif headphones.COMMITS_BEHIND == 0:
        logger.info('Headphones is up to date')

    return headphones.LATEST_VERSION
Example #5
0
    def _sendjson(self, host, method, params={}):
        data = [{"id": 0, "jsonrpc": "2.0", "method": method, "params": params}]
        headers = {"Content-Type": "application/json"}
        url = host + "/jsonrpc"

        if self.password:
            response = request.request_json(
                url, method="post", data=json.dumps(data), headers=headers, auth=(self.username, self.password)
            )
        else:
            response = request.request_json(url, method="post", data=json.dumps(data), headers=headers)

        if response:
            return response[0]["result"]
Example #6
0
    def notify(self, message, status):
        if not headphones.CONFIG.PUSHBULLET_ENABLED:
            return

        url = "https://api.pushbullet.com/v2/pushes"

        data = {'type': "note",
                'title': "Headphones",
                'body': message + ': ' + status}

        if self.deviceid:
            data['device_iden'] = self.deviceid

        headers = {'Content-type': "application/json",
                   'Authorization': 'Bearer ' +
                                    headphones.CONFIG.PUSHBULLET_APIKEY}

        response = request.request_json(url, method="post", headers=headers,
                                        data=json.dumps(data))

        if response:
            logger.info(u"PushBullet notifications sent.")
            return True
        else:
            logger.info(u"PushBullet notification failed.")
            return False
Example #7
0
    def notify(self, message, status):
        if not headphones.CONFIG.PUSHBULLET_ENABLED:
            return

        url = "https://api.pushbullet.com/v2/pushes"

        data = {
            'type': "note",
            'title': "Headphones",
            'body': message + ': ' + status
        }

        if self.deviceid:
            data['device_iden'] = self.deviceid

        headers = {
            'Content-type': "application/json",
            'Authorization': 'Bearer ' + headphones.CONFIG.PUSHBULLET_APIKEY
        }

        response = request.request_json(url,
                                        method="post",
                                        headers=headers,
                                        data=json.dumps(data))

        if response:
            logger.info(u"PushBullet notifications sent.")
            return True
        else:
            logger.info(u"PushBullet notification failed.")
            return False
Example #8
0
def request_lastfm(method, **kwargs):
    """
    Call a Last.FM API method. Automatically sets the method and API key. Method
    will return the result if no error occured.

    By default, this method will request the JSON format, since it is more
    lightweight than XML.
    """

    # Prepare request
    kwargs["method"] = method
    kwargs.setdefault("api_key", API_KEY)
    kwargs.setdefault("format", "json")

    # Send request
    logger.debug("Calling Last.FM method: %s", method)
    logger.debug("Last.FM call parameters: %s", kwargs)

    data = request.request_json(ENTRY_POINT, timeout=TIMEOUT, params=kwargs,
        rate_limit=(lock, REQUEST_LIMIT))

    # Parse response and check for errors.
    if not data:
        logger.error("Error calling Last.FM method: %s", method)
        return

    if "error" in data:
        logger.error("Last.FM returned an error: %s", data["message"])
        return

    return data
Example #9
0
def request_lastfm(method, **kwargs):
    """
    Call a Last.FM API method. Automatically sets the method and API key. Method
    will return the result if no error occured.

    By default, this method will request the JSON format, since it is more
    lightweight than XML.
    """

    # Prepare request
    kwargs["method"] = method
    kwargs.setdefault("api_key", API_KEY)
    kwargs.setdefault("format", "json")

    # Send request
    logger.debug("Calling Last.FM method: %s", method)
    logger.debug("Last.FM call parameters: %s", kwargs)

    data = request.request_json(ENTRY_POINT,
                                timeout=TIMEOUT,
                                params=kwargs,
                                lock=lastfm_lock)

    # Parse response and check for errors.
    if not data:
        logger.error("Error calling Last.FM method: %s", method)
        return

    if "error" in data:
        logger.error("Last.FM returned an error: %s", data["message"])
        return

    return data
Example #10
0
def torrentAction(method, arguments):

    host = headphones.CONFIG.TRANSMISSION_HOST
    username = headphones.CONFIG.TRANSMISSION_USERNAME
    password = headphones.CONFIG.TRANSMISSION_PASSWORD

    if not host.startswith("http"):
        host = "http://" + host

    if host.endswith("/"):
        host = host[:-1]

    # Fix the URL. We assume that the user does not point to the RPC endpoint,
    # so add it if it is missing.
    parts = list(urlparse.urlparse(host))

    if not parts[0] in ("http", "https"):
        parts[0] = "http"

    if not parts[2].endswith("/rpc"):
        parts[2] += "/transmission/rpc"

    host = urlparse.urlunparse(parts)

    # Retrieve session id
    auth = (username, password) if username and password else None
    response = request.request_response(host, auth=auth, whitelist_status_code=[401, 409])

    if response is None:
        logger.error("Error gettings Transmission session ID")
        return

    # Parse response
    if response.status_code == 401:
        if auth:
            logger.error("Username and/or password not accepted by " "Transmission")
        else:
            logger.error("Transmission authorization required")

        return
    elif response.status_code == 409:
        session_id = response.headers["x-transmission-session-id"]

        if not session_id:
            logger.error("Expected a Session ID from Transmission")
            return

    # Prepare next request
    headers = {"x-transmission-session-id": session_id}
    data = {"method": method, "arguments": arguments}

    response = request.request_json(host, method="POST", data=json.dumps(data), headers=headers, auth=auth)

    print response

    if not response:
        logger.error("Error sending torrent to Transmission")
        return

    return response
Example #11
0
def sab_api_call(request_type=None, params={}, **kwargs):
    if not headphones.CONFIG.SAB_HOST.startswith('http'):
        headphones.CONFIG.SAB_HOST = 'http://' + headphones.CONFIG.SAB_HOST

    if headphones.CONFIG.SAB_HOST.endswith('/'):
        headphones.CONFIG.SAB_HOST = headphones.CONFIG.SAB_HOST[
                                     0:len(headphones.CONFIG.SAB_HOST) - 1]

    url = headphones.CONFIG.SAB_HOST + "/" + "api?"

    if headphones.CONFIG.SAB_USERNAME:
        params['ma_username'] = headphones.CONFIG.SAB_USERNAME
    if headphones.CONFIG.SAB_PASSWORD:
        params['ma_password'] = headphones.CONFIG.SAB_PASSWORD
    if headphones.CONFIG.SAB_APIKEY:
        params['apikey'] = headphones.CONFIG.SAB_APIKEY

    if request_type == 'send_nzb' and headphones.CONFIG.SAB_CATEGORY:
        params['cat'] = headphones.CONFIG.SAB_CATEGORY

    params['output'] = 'json'

    response = request.request_json(url, params=params, **kwargs)

    if not response:
        logger.error("Error connecting to SABnzbd on url: %s" % headphones.CONFIG.SAB_HOST)
        return False
    else:
        logger.debug("Successfully connected to SABnzbd on url: %s" % headphones.CONFIG.SAB_HOST)
        return response
Example #12
0
def sab_api_call(request_type=None, params={}, **kwargs):
    if not headphones.CONFIG.SAB_HOST.startswith('http'):
        headphones.CONFIG.SAB_HOST = 'http://' + headphones.CONFIG.SAB_HOST

    if headphones.CONFIG.SAB_HOST.endswith('/'):
        headphones.CONFIG.SAB_HOST = headphones.CONFIG.SAB_HOST[
            0:len(headphones.CONFIG.SAB_HOST) - 1]

    url = headphones.CONFIG.SAB_HOST + "/" + "api?"

    if headphones.CONFIG.SAB_USERNAME:
        params['ma_username'] = headphones.CONFIG.SAB_USERNAME
    if headphones.CONFIG.SAB_PASSWORD:
        params['ma_password'] = headphones.CONFIG.SAB_PASSWORD
    if headphones.CONFIG.SAB_APIKEY:
        params['apikey'] = headphones.CONFIG.SAB_APIKEY

    if request_type == 'send_nzb' and headphones.CONFIG.SAB_CATEGORY:
        params['cat'] = headphones.CONFIG.SAB_CATEGORY

    params['output'] = 'json'

    response = request.request_json(url, params=params, **kwargs)

    if not response:
        logger.error("Error connecting to SABnzbd on url: %s" %
                     headphones.CONFIG.SAB_HOST)
        return False
    else:
        logger.debug("Successfully connected to SABnzbd on url: %s" %
                     headphones.CONFIG.SAB_HOST)
        return response
Example #13
0
def request_lastfm(method, **kwargs):
    """
    Call a Last.FM API method. Automatically sets the method and API key. Method
    will return the result if no error occured.

    By default, this method will request the JSON format, since it is more
    lightweight than XML.
    """
    
    if headphones.CONFIG.LASTFM_PERSONAL_KEY:
        API_KEY = headphones.CONFIG.LASTFM_PERSONAL_KEY
    else:
        API_KEY = "395e6ec6bb557382fc41fde867bce66f"
    
    # Prepare request
    kwargs["method"] = method
    kwargs.setdefault("api_key", API_KEY)
    kwargs.setdefault("format", "json")

    # Send request
    logger.debug("Calling Last.FM method: %s", method)
    logger.debug("Last.FM API Key is: %s" % API_KEY)
    logger.debug("Last.FM call parameters: %s", kwargs)

    data = request.request_json(ENTRY_POINT, timeout=TIMEOUT, params=kwargs, lock=lastfm_lock)

    # Parse response and check for errors.
    if not data:
        logger.error("Error calling Last.FM method: %s", method)
        # when there is a last.fm api fail, this return prevents artist artwork from loading
        # return

    if "error" in data:
        logger.debug("Last.FM returned an error: %s", data["message"])
        # when there is a last.fm api fail, this return prevents artist artwork from loading
        # return

    return data
Example #14
0
    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'

            # 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 + ArtistID,
                                        whitelist_status_code=404,
                                        headers={
                                            'api-key': FANART_PROJECT_KEY,
                                            'client-key': FANART_CLIENT_KEY
                                        })

            if not data:
                return

            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

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

        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}
Example #15
0
def torrentAction(method, arguments):

    host = headphones.TRANSMISSION_HOST
    username = headphones.TRANSMISSION_USERNAME
    password = headphones.TRANSMISSION_PASSWORD
    sessionid = None

    if not host.startswith('http'):
        host = 'http://' + host

    if host.endswith('/'):
        host = host[:-1]

    # Either the host ends with a port, or some directory, or rpc
    # If it ends with /rpc we don't have to do anything
    # If it ends with a port we add /transmission/rpc
    # anything else we just add rpc
    if not host.endswith('/rpc'):
        # Check if it ends in a port number
        i = host.rfind(':')
        if i >= 0:
            possible_port = host[i + 1:]
            try:
                port = int(possible_port)
                host = host + "/transmission/rpc"
            except ValueError:
                host = host + "/rpc"
        else:
            logger.error('Transmission port missing')
            return

    # Retrieve session id
    auth = (username, password) if username and password else None

    response = request.request_response(host,
                                        auth=auth,
                                        whitelist_status_code=[401, 409])

    if response is None:
        logger.error("Error gettings Transmission session ID")
        return

    # Parse response
    if response.status_code == 401:
        if auth:
            logger.error(
                "Username and/or password not accepted by Transmission")
        else:
            logger.error("Transmission authorization required")

        return
    elif response.status_code == 409:
        sessionid = response.headers['x-transmission-session-id']

    if not sessionid:
        logger.error("Error getting Session ID from Transmission")
        return

    # Prepare next request
    headers = {'x-transmission-session-id': sessionid}
    data = {'method': method, 'arguments': arguments}

    response = request.request_json(host,
                                    method="post",
                                    data=json.dumps(data),
                                    headers=headers,
                                    auth=auth)

    if not response:
        logger.error("Error sending torrent to Transmission")
        return

    return response
Example #16
0
def torrentAction(method, arguments):

    host = headphones.TRANSMISSION_HOST
    username = headphones.TRANSMISSION_USERNAME
    password = headphones.TRANSMISSION_PASSWORD
    sessionid = None

    if not host.startswith('http'):
        host = 'http://' + host

    if host.endswith('/'):
        host = host[:-1]

    # Either the host ends with a port, or some directory, or rpc
    # If it ends with /rpc we don't have to do anything
    # If it ends with a port we add /transmission/rpc
    # anything else we just add rpc
    if not host.endswith('/rpc'):
        # Check if it ends in a port number
        i = host.rfind(':')
        if i >= 0:
            possible_port = host[i+1:]
            try:
                port = int(possible_port)
                host = host + "/transmission/rpc"
            except ValueError:
                host = host + "/rpc"
        else:
            logger.error('Transmission port missing')
            return

    # Retrieve session id
    auth = (username, password) if username and password else None

    response = request.request_response(host, auth=auth, whitelist_status_code=[401, 409])

    if response is None:
        logger.error("Error gettings Transmission session ID")
        return

    # Parse response
    if response.status_code == 401:
        if auth:
            logger.error("Username and/or password not accepted by Transmission")
        else:
            logger.error("Transmission authorization required")

        return
    elif response.status_code == 409:
        sessionid = response.headers['x-transmission-session-id']

    if not sessionid:
        logger.error("Error getting Session ID from Transmission")
        return

    # Prepare next request
    headers = { 'x-transmission-session-id': sessionid }
    data = { 'method': method, 'arguments': arguments }

    response = request.request_json(host, method="post", data=json.dumps(data), headers=headers, auth=auth)

    if not response:
        logger.error("Error sending torrent to Transmission")
        return

    return response
Example #17
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
Example #18
0
def torrentAction(method, arguments):

    host = headphones.CONFIG.TRANSMISSION_HOST
    username = headphones.CONFIG.TRANSMISSION_USERNAME
    password = headphones.CONFIG.TRANSMISSION_PASSWORD

    if not host.startswith('http'):
        host = 'http://' + host

    if host.endswith('/'):
        host = host[:-1]

    # Fix the URL. We assume that the user does not point to the RPC endpoint,
    # so add it if it is missing.
    parts = list(urlparse.urlparse(host))

    if not parts[0] in ("http", "https"):
        parts[0] = "http"

    if not parts[2].endswith("/rpc"):
        parts[2] += "/transmission/rpc"

    host = urlparse.urlunparse(parts)

    # Retrieve session id
    auth = (username, password) if username and password else None
    response = request.request_response(host,
                                        auth=auth,
                                        whitelist_status_code=[401, 409])

    if response is None:
        logger.error("Error gettings Transmission session ID")
        return

    # Parse response
    if response.status_code == 401:
        if auth:
            logger.error("Username and/or password not accepted by " \
                "Transmission")
        else:
            logger.error("Transmission authorization required")

        return
    elif response.status_code == 409:
        session_id = response.headers['x-transmission-session-id']

        if not session_id:
            logger.error("Expected a Session ID from Transmission")
            return

    # Prepare next request
    headers = {'x-transmission-session-id': session_id}
    data = {'method': method, 'arguments': arguments}

    response = request.request_json(host,
                                    method="POST",
                                    data=json.dumps(data),
                                    headers=headers,
                                    auth=auth)

    print response

    if not response:
        logger.error("Error sending torrent to Transmission")
        return

    return response
Example #19
0
def addTorrent(link):

    host = headphones.UTORRENT_HOST
    username = headphones.UTORRENT_USERNAME
    password = headphones.UTORRENT_PASSWORD
    label = headphones.UTORRENT_LABEL
    token = ''

    if not host.startswith('http'):
        host = 'http://' + host

    if host.endswith('/'):
    	host = host[:-1]

    if host.endswith('/gui'):
    	host = host + '/'
    else:
    	host = host + '/gui/'

    # Retrieve session id
    auth = (username, password) if username and password else None
    token_request = request.request_response(host + 'token.html', auth=auth)

    token = re.findall('<div.*?>(.*?)</', token_request.content)[0]
    guid = token_request.cookies['GUID']

    cookies = dict(GUID = guid)

    if link.startswith("magnet") or link.startswith("http") or link.endswith(".torrent"):
        params = {'action':'add-url', 's':link, 'token':token}
        response = request.request_json(host, params=params, auth=auth, cookies=cookies)
    else:    
        params = {'action':'add-file', 'token':token}
        files = {'torrent_file':{'music.torrent' : link}}
        response = request.request_json(host, method="post", params=params, files=files, auth=auth, cookies=cookies)
    if not response:
        logger.error("Error sending torrent to uTorrent")
        return

    if link.startswith('magnet'):
        tor_hash = re.findall('urn:btih:([\w]{32,40})', link)[0]
        if len(tor_hash) == 32:
            tor_hash = b16encode(b32decode(tor_hash)).lower()
    else:
        info = bdecode(link.content)["info"]
        tor_hash = sha1(bencode(info)).hexdigest()
	    
    params = {'action':'setprops', 'hash':tor_hash,'s':'label', 'v':label, 'token':token}
    response = request.request_json(host, params=params, auth=auth, cookies=cookies)
    if not response:
        logger.error("Error setting torrent label in uTorrent")
        return

	# folder info can probably be cleaned up with getprops
	folder = None    

    params = {'list':'1', 'token':token}
    response = request.request_json(host, params=params, auth=auth, cookies=cookies)
    if not response:
        logger.error("Error getting torrent information from uTorrent")
        return

        for torrent in response['torrents']:
			folder = os.path.basename(torrent[26])

    return folder