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)
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)
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
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
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))
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
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
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
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
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
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
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
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
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
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
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