예제 #1
0
    def update(self):

        # From what I read you can't update the music library on a per directory or per path basis
        # so need to update the whole thing

        hosts = [x.strip() for x in self.server_hosts.split(',')]

        for host in hosts:
            logger.info('Sending library update command to Plex Media Server@ ' + host)
            url = "%s/library/sections" % host
            if self.token:
                params = {'X-Plex-Token': self.token}
            else:
                params = False

            r = request.request_minidom(url, params=params)

            sections = r.getElementsByTagName('Directory')

            if not sections:
                logger.info(u"Plex Media Server not running on: " + host)
                return False

            for s in sections:
                if s.getAttribute('type') == "artist":
                    url = "%s/library/sections/%s/refresh" % (host, s.getAttribute('key'))
                    request.request_response(url, params=params)
예제 #2
0
    def update(self):

        # From what I read you can't update the music library on a per directory or per path basis
        # so need to update the whole thing

        hosts = [x.strip() for x in self.server_hosts.split(',')]

        for host in hosts:
            logger.info(
                'Sending library update command to Plex Media Server@ ' + host)
            url = "%s/library/sections" % host
            if self.token:
                params = {'X-Plex-Token': self.token}
            else:
                params = False

            r = request.request_minidom(url, params=params)

            sections = r.getElementsByTagName('Directory')

            if not sections:
                logger.info(u"Plex Media Server not running on: " + host)
                return False

            for s in sections:
                if s.getAttribute('type') == "artist":
                    url = "%s/library/sections/%s/refresh" % (
                        host, s.getAttribute('key'))
                    request.request_response(url, params=params)
예제 #3
0
def torrentAction(method, arguments):
    global _session_id
    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)
    data = {'method': method, 'arguments': arguments}
    data_json = json.dumps(data)
    auth = (username, password) if username and password else None
    for retry in range(2):
        if _session_id is not None:
            headers = {'x-transmission-session-id': _session_id}
            response = request.request_response(
                host,
                method="POST",
                data=data_json,
                headers=headers,
                auth=auth,
                whitelist_status_code=[200, 401, 409])
        else:
            response = request.request_response(
                host, auth=auth, whitelist_status_code=[401, 409])
        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 _session_id is None:
                logger.error(
                    "Expected a Session ID from Transmission, got None")
                return
            # retry request with new session id
            logger.debug("Retrying Transmission request with new session id")
            continue

        resp_json = response.json()
        print resp_json
        return resp_json
예제 #4
0
    def _sendhttp(self, host, command):

        url = host + '/xbmcCmds/xbmcHttp/?' + command

        if self.password:
            response = request.request_response(url, auth=(self.username, self.password))
        else:
            response = request.request_response(url)

        return response
예제 #5
0
    def notify(self, albumpaths):
        # Correct URL
        if not self.host.lower().startswith("http"):
            self.host = "http://" + self.host

        if not self.host.lower().endswith("/"):
            self.host = self.host + "/"

        # Invoke request
        request.request_response(self.host + "musicFolderSettings.view?scanNow", auth=(self.username, self.password))
예제 #6
0
    def _sendhttp(self, host, command):

        url = host + '/xbmcCmds/xbmcHttp/?' + command

        if self.password:
            response = request.request_response(url, auth=(self.username, self.password))
        else:
            response = request.request_response(url)

        return response
예제 #7
0
    def notify(self, albumpaths):
        # Correct URL
        if not self.host.lower().startswith("http"):
            self.host = "http://" + self.host

        if not self.host.lower().endswith("/"):
            self.host = self.host + "/"

        # Invoke request
        request.request_response(self.host + "musicFolderSettings.view?scanNow",
            auth=(self.username, self.password))
예제 #8
0
def torrentAction(method, arguments):
    global _session_id
    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)
    data = {'method': method, 'arguments': arguments}
    data_json = json.dumps(data)
    auth = (username, password) if username and password else None
    for retry in range(2):
        if _session_id is not None:
            headers = {'x-transmission-session-id': _session_id}
            response = request.request_response(host, method="POST",
                data=data_json, headers=headers, auth=auth,
                whitelist_status_code=[200, 401, 409])
        else:
            response = request.request_response(host, auth=auth,
                                            whitelist_status_code=[401, 409])
        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 _session_id is None:
                logger.error("Expected a Session ID from Transmission, got None")
                return
            # retry request with new session id
            logger.debug("Retrying Transmission request with new session id")
            continue

        resp_json = response.json()
        print resp_json
        return resp_json
예제 #9
0
def getartwork(artwork_path):
    artwork = bytes()
    minwidth = 0
    maxwidth = 0
    if headphones.CONFIG.ALBUM_ART_MIN_WIDTH:
        minwidth = int(headphones.CONFIG.ALBUM_ART_MIN_WIDTH)
    if headphones.CONFIG.ALBUM_ART_MAX_WIDTH:
        maxwidth = int(headphones.CONFIG.ALBUM_ART_MAX_WIDTH)

    resp = request.request_response(artwork_path,
                                    timeout=20,
                                    stream=True,
                                    whitelist_status_code=404)

    if resp:
        img_width = None
        for chunk in resp.iter_content(chunk_size=1024):
            artwork += chunk
            if not img_width and (minwidth or maxwidth):
                img_type, img_width, img_height = get_image_data(artwork)
            # Check min/max
            if img_width and (minwidth or maxwidth):
                if minwidth and img_width < minwidth:
                    logger.info(
                        "Artwork is too small. Type: %s. Width: %s. Height: %s",
                        img_type, img_width, img_height)
                    artwork = None
                    break
                elif maxwidth and img_width > maxwidth:
                    # Downsize using proxy service to max width
                    artwork_path = '{0}?{1}'.format(
                        'http://images.weserv.nl/',
                        urlencode({
                            'url': artwork_path.replace('http://', ''),
                            'w': maxwidth,
                        }))
                    artwork = bytes()
                    r = request.request_response(artwork_path,
                                                 timeout=20,
                                                 stream=True,
                                                 whitelist_status_code=404)
                    if r:
                        for chunk in r.iter_content(chunk_size=1024):
                            artwork += chunk
                        r.close()
                        logger.info(
                            "Artwork is greater than the maximum width, downsized using proxy service"
                        )
                    break
        resp.close()

    return artwork
예제 #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
예제 #11
0
    def notify(self, message, event):
        if not headphones.CONFIG.PUSHOVER_ENABLED:
            return

        url = "https://api.pushover.net/1/messages.json"

        data = {
            'token': self.application_token,
            'user': headphones.CONFIG.PUSHOVER_KEYS,
            'title': event,
            'message': message.encode("utf-8"),
            'priority': headphones.CONFIG.PUSHOVER_PRIORITY
        }

        headers = {'Content-type': "application/x-www-form-urlencoded"}

        response = request.request_response(url,
                                            method="POST",
                                            headers=headers,
                                            data=data)

        if response:
            logger.info(u"Pushover notifications sent.")
            return True
        else:
            logger.error(u"Pushover notification failed.")
            return False
예제 #12
0
def getartwork(artwork_path):
    artwork = bytes()
    minwidth = 0
    maxwidth = 0
    if headphones.CONFIG.ALBUM_ART_MIN_WIDTH:
        minwidth = int(headphones.CONFIG.ALBUM_ART_MIN_WIDTH)
    if headphones.CONFIG.ALBUM_ART_MAX_WIDTH:
        maxwidth = int(headphones.CONFIG.ALBUM_ART_MAX_WIDTH)

    resp = request.request_response(artwork_path, timeout=20, stream=True, whitelist_status_code=404)

    if resp:
        img_width = None
        for chunk in resp.iter_content(chunk_size=1024):
            artwork += chunk
            if not img_width and (minwidth or maxwidth):
                img_type, img_width, img_height = get_image_data(artwork)
            # Check min/max
            if img_width and (minwidth or maxwidth):
                if minwidth and img_width < minwidth:
                    logger.info("Artwork is too small. Type: %s. Width: %s. Height: %s",
                                img_type, img_width, img_height)
                    artwork = None
                    break
                elif maxwidth and img_width > maxwidth:
                    # Downsize using proxy service to max width
                    artwork_path = '{0}?{1}'.format('http://images.weserv.nl/', urlencode({
                        'url': artwork_path.replace('http://', ''),
                        'w': maxwidth,
                    }))
                    artwork = bytes()
                    r = request.request_response(artwork_path, timeout=20, stream=True, whitelist_status_code=404)
                    if r:
                        for chunk in r.iter_content(chunk_size=1024):
                            artwork += chunk
                        r.close()
                        logger.info("Artwork is greater than the maximum width, downsized using proxy service")
                    break
        resp.close()

    return artwork
예제 #13
0
    def notify(self, message, event):
        if not headphones.CONFIG.PUSHOVER_ENABLED:
            return

        url = "https://api.pushover.net/1/messages.json"

        data = {'token': self.application_token,
                'user': headphones.CONFIG.PUSHOVER_KEYS,
                'title': event,
                'message': message.encode("utf-8"),
                'priority': headphones.CONFIG.PUSHOVER_PRIORITY}

        headers = {'Content-type': "application/x-www-form-urlencoded"}

        response = request.request_response(url, method="POST", headers=headers, data=data)

        if response:
            logger.info(u"Pushover notifications sent.")
            return True
        else:
            logger.error(u"Pushover notification failed.")
            return False
예제 #14
0
    def update(self):

        # Get token from user credentials
        if not self.token:
            loginpage = 'https://plex.tv/users/sign_in.json'
            post_params = {
                'user[login]': self.username,
                'user[password]': self.password
            }
            headers = {
                'X-Plex-Device-Name': 'Headphones',
                'X-Plex-Product': 'Headphones',
                'X-Plex-Client-Identifier': common.USER_AGENT,
                'X-Plex-Version': ''
            }

            logger.info("Getting plex.tv credentials for user %s", self.username)

            try:
                r = requests.post(loginpage, data=post_params, headers=headers)
                r.raise_for_status()
            except requests.RequestException as e:
                logger.error("Error getting plex.tv credentials, check settings: %s", e)
                return False

            try:
                data = r.json()
            except ValueError as e:
                logger.error("Error getting plex.tv credentials: %s", e)
                return False

            try:
                self.token = data['user']['authentication_token']
            except KeyError as e:
                logger.error("Error getting plex.tv credentials: %s", e)
                return False

        # From what I read you can't update the music library on a per
        # directory or per path basis so need to update the whole thing

        hosts = [x.strip() for x in self.server_hosts.split(',')]

        for host in hosts:
            logger.info(
                'Sending library update command to Plex Media Server@ ' + host)
            url = "%s/library/sections" % host
            if self.token:
                params = {'X-Plex-Token': self.token}
            else:
                params = False

            try:
                r = request.request_minidom(url, params=params)
                if not r:
                    logger.warn("Error getting Plex Media Server details, check settings (possibly incorrect token)")
                    return False

                sections = r.getElementsByTagName('Directory')

                if not sections:
                    logger.info(u"Plex Media Server not running on: " + host)
                    return False

                for s in sections:
                    if s.getAttribute('type') == "artist":
                        url = "%s/library/sections/%s/refresh" % (
                            host, s.getAttribute('key'))
                        request.request_response(url, params=params)

            except Exception as e:
                logger.error("Error getting Plex Media Server details: %s" % e)
                return False
예제 #15
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
예제 #16
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
예제 #17
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
예제 #18
0
    def update(self):

        # Get token from user credentials
        if not self.token:
            loginpage = 'https://plex.tv/users/sign_in.json'
            post_params = {
                'user[login]': self.username,
                'user[password]': self.password
            }
            headers = {
                'X-Plex-Device-Name': 'Headphones',
                'X-Plex-Product': 'Headphones',
                'X-Plex-Client-Identifier': common.USER_AGENT,
                'X-Plex-Version': ''
            }

            logger.info("Getting plex.tv credentials for user %s", self.username)

            try:
                r = requests.post(loginpage, data=post_params, headers=headers)
                r.raise_for_status()
            except requests.RequestException as e:
                logger.error("Error getting plex.tv credentials, check settings: %s", e)
                return False

            try:
                data = r.json()
            except ValueError as e:
                logger.error("Error getting plex.tv credentials: %s", e)
                return False

            try:
                self.token = data['user']['authentication_token']
            except KeyError as e:
                logger.error("Error getting plex.tv credentials: %s", e)
                return False

        # From what I read you can't update the music library on a per
        # directory or per path basis so need to update the whole thing

        hosts = [x.strip() for x in self.server_hosts.split(',')]

        for host in hosts:
            logger.info(
                'Sending library update command to Plex Media Server@ ' + host)
            url = "%s/library/sections" % host
            if self.token:
                params = {'X-Plex-Token': self.token}
            else:
                params = False

            try:
                r = request.request_minidom(url, params=params)
                if not r:
                    logger.warn("Error getting Plex Media Server details, check settings (possibly incorrect token)")
                    return False

                sections = r.getElementsByTagName('Directory')

                if not sections:
                    logger.info(u"Plex Media Server not running on: " + host)
                    return False

                for s in sections:
                    if s.getAttribute('type') == "artist":
                        url = "%s/library/sections/%s/refresh" % (
                            host, s.getAttribute('key'))
                        request.request_response(url, params=params)

            except Exception as e:
                logger.error("Error getting Plex Media Server details: %s" % e)
                return False
예제 #19
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