1
0
mirror of https://github.com/clementine-player/Clementine synced 2024-12-16 11:19:18 +01:00

Fix the Amazon covers script to work with PythonQt, and some minor style fixes

This commit is contained in:
David Sansome 2011-05-22 14:11:02 +00:00
parent fc97e4bb8c
commit e1620385d5
2 changed files with 33 additions and 35 deletions

View File

@ -1,25 +1,26 @@
import clementine import clementine
from PythonQt.QtCore import QUrl, QString from PythonQt.QtCore import QUrl
from PythonQt.QtNetwork import QNetworkRequest from PythonQt.QtNetwork import QNetworkRequest
from xml.etree.ElementTree import fromstring
import urllib
import time
import hashlib
import base64 import base64
import hashlib
import hmac import hmac
import logging
import time
import urllib
import xml.etree.ElementTree
LOGGER = logging.getLogger("amazon_covers")
class AmazonCoversScript(): class AmazonCoversScript():
def __init__(self): def __init__(self):
# create and register our factory # create and register our factory
self.factory = AmazonCoverProviderFactory() self.factory = AmazonCoverProviderFactory()
class AmazonCoverProviderFactory(clementine.CoverProviderFactory): class AmazonCoverProviderFactory(clementine.CoverProviderFactory):
def __init__(self): def __init__(self):
clementine.CoverProviderFactory.__init__(self) clementine.CoverProviderFactory.__init__(self)
# register in the repository of factories # register in the repository of factories
@ -35,13 +36,12 @@ class AmazonCoverProvider(clementine.CoverProvider):
an open source application called Cardapio. an open source application called Cardapio.
""" """
def __init__(self): API_URL = 'http://ecs.amazonaws.com/onca/xml?{0}'
clementine.CoverProvider.__init__(self, "Amazon") AWS_ACCESS_KEY = 'AKIAJ4QO3GQTSM3A43BQ'
AWS_SECRET_ACCESS_KEY = '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'
self.api_url = 'http://ecs.amazonaws.com/onca/xml?{0}' def __init__(self, parent):
clementine.CoverProvider.__init__(self, "Amazon", parent)
self.aws_access_key = 'AKIAJ4QO3GQTSM3A43BQ'
self.aws_secret_access_key = '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'
# basic API's arguments (search in all categories) # basic API's arguments (search in all categories)
self.api_base_args = { self.api_base_args = {
@ -50,15 +50,14 @@ class AmazonCoverProvider(clementine.CoverProvider):
'Operation' : 'ItemSearch', 'Operation' : 'ItemSearch',
'SearchIndex' : 'All', 'SearchIndex' : 'All',
'ResponseGroup' : 'Images', 'ResponseGroup' : 'Images',
'AWSAccessKeyId': self.aws_access_key 'AWSAccessKeyId': self.AWS_ACCESS_KEY
} }
self.network = clementine.NetworkAccessManager(self) self.network = clementine.NetworkAccessManager(self)
# register in the repository of cover providers
clementine.cover_providers.AddCoverProvider(self)
def SendRequest(self, query): def SendRequest(self, query):
url = QUrl.fromEncoded(self.api_url.format(self.PrepareAmazonRESTUrl(query))) url = QUrl.fromEncoded(self.API_URL.format(self.PrepareAmazonRESTUrl(query)))
LOGGER.info("Sending request to '%s'", url)
return self.network.get(QNetworkRequest(url)) return self.network.get(QNetworkRequest(url))
def ParseReply(self, reply): def ParseReply(self, reply):
@ -72,7 +71,7 @@ class AmazonCoverProvider(clementine.CoverProvider):
if len(xml_body) == 0: if len(xml_body) == 0:
return parsed return parsed
root = fromstring(xml_body) root = xml.etree.ElementTree.fromstring(xml_body)
# strip the namespaces from all of the parsed items # strip the namespaces from all of the parsed items
for el in root.getiterator(): for el in root.getiterator():
@ -81,7 +80,7 @@ class AmazonCoverProvider(clementine.CoverProvider):
el.tag = el.tag[(ns_pos + 1):] el.tag = el.tag[(ns_pos + 1):]
except Exception as ex: except Exception as ex:
print 'error while preparing reply for parsing', ex LOGGER.exception(ex)
return parsed return parsed
# decode the result # decode the result
@ -92,28 +91,29 @@ class AmazonCoverProvider(clementine.CoverProvider):
total_results = root.find('Items/TotalResults') total_results = root.find('Items/TotalResults')
# if we have a valid response with any results... # if we have a valid response with any results...
if (not is_valid is None) and is_valid != 'False' and (not total_results is None) and total_results != '0': if is_valid is not None and is_valid != 'False' and \
total_results is not None and total_results != '0':
query = root.find('Items/Request/ItemSearchRequest/Keywords').text query = root.find('Items/Request/ItemSearchRequest/Keywords').text
# remember them all # remember them all
for i, item in enumerate(root.findall('Items/Item')): for item in root.findall('Items/Item'):
final_url = None final_url = None
current_url = item.find('LargeImage/URL') current_url = item.find('LargeImage/URL')
if current_url == None: if current_url is None:
current_url = item.find('MediumImage/URL') current_url = item.find('MediumImage/URL')
if current_url == None: if current_url is None:
continue continue
current = clementine.CoverSearchResult() current = clementine.CoverSearchResult()
current.description = QString(query) current.description = str(query)
current.image_url = QString(current_url.text) current.image_url = str(current_url.text)
parsed.append(current) parsed.append(current)
except KeyError as ex: except KeyError as ex:
print 'incorrect response structure', ex LOGGER.exception(ex)
return parsed return parsed
@ -129,10 +129,8 @@ class AmazonCoverProvider(clementine.CoverProvider):
copy_args['Timestamp'] = time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime()) copy_args['Timestamp'] = time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime())
# turn the argument map into a list of encoded request parameter strings # turn the argument map into a list of encoded request parameter strings
query_list = map( query_list = ["%s=%s" % (k, urllib.quote(v))
lambda (k, v): (k + "=" + urllib.quote(v)), for k, v in copy_args.items()]
copy_args.items()
)
# sort the list (by parameter name) # sort the list (by parameter name)
query_list.sort() query_list.sort()
@ -147,7 +145,7 @@ class AmazonCoverProvider(clementine.CoverProvider):
{1}""".format('ecs.amazonaws.com', query_string) {1}""".format('ecs.amazonaws.com', query_string)
# create HMAC for the string (using SHA-256 and our secret API key) # create HMAC for the string (using SHA-256 and our secret API key)
hm = hmac.new(key = self.aws_secret_access_key, hm = hmac.new(key = self.AWS_SECRET_ACCESS_KEY,
msg = string_to_sign, msg = string_to_sign,
digestmod = hashlib.sha256) digestmod = hashlib.sha256)
# final step... convert the HMAC to base64, then encode it # final step... convert the HMAC to base64, then encode it
@ -156,4 +154,4 @@ class AmazonCoverProvider(clementine.CoverProvider):
return query_string + '&Signature=' + signature return query_string + '&Signature=' + signature
script = AmazonCoversScript() amazon_script = AmazonCoversScript()

View File

@ -40,7 +40,7 @@ public:
// Given a search request from Clementine, provider has to create and invoke // Given a search request from Clementine, provider has to create and invoke
// a NetworkRequest. It then has to return a corresponding NetworkReply, // a NetworkRequest. It then has to return a corresponding NetworkReply,
// without connecting to it's finished() signal! // without connecting to its finished() signal!
// Responsibilities of provider: // Responsibilities of provider:
// - maps the given query to a NetworkRequest that a service this provider // - maps the given query to a NetworkRequest that a service this provider
// uses will understand // uses will understand