Remove amazon cover fetching - required API key that Cantata never really had.

This commit is contained in:
craig.p.drummond
2013-06-08 07:43:00 +00:00
parent bbb976866a
commit 4f27849df1
9 changed files with 5 additions and 1496 deletions

View File

@@ -1,3 +0,0 @@
cmake_minimum_required(VERSION 2.6)
add_library(sha2 STATIC sha2.c)

1068
3rdparty/sha2/sha2.c vendored

File diff suppressed because it is too large Load Diff

197
3rdparty/sha2/sha2.h vendored
View File

@@ -1,197 +0,0 @@
/*
* FILE: sha2.h
* AUTHOR: Aaron D. Gifford - http://www.aarongifford.com/
*
* Copyright (c) 2000-2001, Aaron D. Gifford
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: sha2.h,v 1.1 2001/11/08 00:02:01 adg Exp adg $
*/
#ifndef __SHA2_H__
#define __SHA2_H__
#ifdef __cplusplus
extern "C" {
#endif
/*
* Import u_intXX_t size_t type definitions from system headers. You
* may need to change this, or define these things yourself in this
* file.
*/
#include <sys/types.h>
#ifdef SHA2_USE_INTTYPES_H
#include <inttypes.h>
#endif /* SHA2_USE_INTTYPES_H */
/*** SHA-256/384/512 Various Length Definitions ***********************/
#define SHA256_BLOCK_LENGTH 64
#define SHA256_DIGEST_LENGTH 32
#define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1)
#define SHA384_BLOCK_LENGTH 128
#define SHA384_DIGEST_LENGTH 48
#define SHA384_DIGEST_STRING_LENGTH (SHA384_DIGEST_LENGTH * 2 + 1)
#define SHA512_BLOCK_LENGTH 128
#define SHA512_DIGEST_LENGTH 64
#define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1)
/*** SHA-256/384/512 Context Structures *******************************/
/* NOTE: If your architecture does not define either u_intXX_t types or
* uintXX_t (from inttypes.h), you may need to define things by hand
* for your system:
*/
#ifdef __MINGW32__
typedef unsigned char u_int8_t; /* 1-byte (8-bits) */
typedef unsigned int u_int32_t; /* 4-bytes (32-bits) */
typedef unsigned long long u_int64_t; /* 8-bytes (64-bits) */
#endif
/*
* Most BSD systems already define u_intXX_t types, as does Linux.
* Some systems, however, like Compaq's Tru64 Unix instead can use
* uintXX_t types defined by very recent ANSI C standards and included
* in the file:
*
* #include <inttypes.h>
*
* If you choose to use <inttypes.h> then please define:
*
* #define SHA2_USE_INTTYPES_H
*
* Or on the command line during compile:
*
* cc -DSHA2_USE_INTTYPES_H ...
*/
#ifdef SHA2_USE_INTTYPES_H
typedef struct _SHA256_CTX {
uint32_t state[8];
uint64_t bitcount;
uint8_t buffer[SHA256_BLOCK_LENGTH];
} SHA256_CTX;
typedef struct _SHA512_CTX {
uint64_t state[8];
uint64_t bitcount[2];
uint8_t buffer[SHA512_BLOCK_LENGTH];
} SHA512_CTX;
#else /* SHA2_USE_INTTYPES_H */
typedef struct _SHA256_CTX {
u_int32_t state[8];
u_int64_t bitcount;
u_int8_t buffer[SHA256_BLOCK_LENGTH];
} SHA256_CTX;
typedef struct _SHA512_CTX {
u_int64_t state[8];
u_int64_t bitcount[2];
u_int8_t buffer[SHA512_BLOCK_LENGTH];
} SHA512_CTX;
#endif /* SHA2_USE_INTTYPES_H */
typedef SHA512_CTX SHA384_CTX;
/*** SHA-256/384/512 Function Prototypes ******************************/
#ifndef NOPROTO
#ifdef SHA2_USE_INTTYPES_H
void SHA256_Init(SHA256_CTX *);
void SHA256_Update(SHA256_CTX*, const uint8_t*, size_t);
void SHA256_Final(uint8_t[SHA256_DIGEST_LENGTH], SHA256_CTX*);
char* SHA256_End(SHA256_CTX*, char[SHA256_DIGEST_STRING_LENGTH]);
char* SHA256_Data(const uint8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH]);
void SHA384_Init(SHA384_CTX*);
void SHA384_Update(SHA384_CTX*, const uint8_t*, size_t);
void SHA384_Final(uint8_t[SHA384_DIGEST_LENGTH], SHA384_CTX*);
char* SHA384_End(SHA384_CTX*, char[SHA384_DIGEST_STRING_LENGTH]);
char* SHA384_Data(const uint8_t*, size_t, char[SHA384_DIGEST_STRING_LENGTH]);
void SHA512_Init(SHA512_CTX*);
void SHA512_Update(SHA512_CTX*, const uint8_t*, size_t);
void SHA512_Final(uint8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*);
char* SHA512_End(SHA512_CTX*, char[SHA512_DIGEST_STRING_LENGTH]);
char* SHA512_Data(const uint8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH]);
#else /* SHA2_USE_INTTYPES_H */
void SHA256_Init(SHA256_CTX *);
void SHA256_Update(SHA256_CTX*, const u_int8_t*, size_t);
void SHA256_Final(u_int8_t[SHA256_DIGEST_LENGTH], SHA256_CTX*);
char* SHA256_End(SHA256_CTX*, char[SHA256_DIGEST_STRING_LENGTH]);
char* SHA256_Data(const u_int8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH]);
void SHA384_Init(SHA384_CTX*);
void SHA384_Update(SHA384_CTX*, const u_int8_t*, size_t);
void SHA384_Final(u_int8_t[SHA384_DIGEST_LENGTH], SHA384_CTX*);
char* SHA384_End(SHA384_CTX*, char[SHA384_DIGEST_STRING_LENGTH]);
char* SHA384_Data(const u_int8_t*, size_t, char[SHA384_DIGEST_STRING_LENGTH]);
void SHA512_Init(SHA512_CTX*);
void SHA512_Update(SHA512_CTX*, const u_int8_t*, size_t);
void SHA512_Final(u_int8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*);
char* SHA512_End(SHA512_CTX*, char[SHA512_DIGEST_STRING_LENGTH]);
char* SHA512_Data(const u_int8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH]);
#endif /* SHA2_USE_INTTYPES_H */
#else /* NOPROTO */
void SHA256_Init();
void SHA256_Update();
void SHA256_Final();
char* SHA256_End();
char* SHA256_Data();
void SHA384_Init();
void SHA384_Update();
void SHA384_Final();
char* SHA384_End();
char* SHA384_Data();
void SHA512_Init();
void SHA512_Update();
void SHA512_Final();
char* SHA512_End();
char* SHA512_Data();
#endif /* NOPROTO */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __SHA2_H__ */

View File

@@ -405,7 +405,6 @@ endif (MSVC)
add_subdirectory(po)
add_subdirectory(support)
add_subdirectory(3rdparty/sha2)
add_subdirectory(streams/icons)
IF( ENABLE_KDE_SUPPORT )
@@ -498,8 +497,6 @@ if (NOT WIN32)
endif (CDDB_FOUND OR MUSICBRAINZ5_FOUND)
endif (NOT WIN32)
add_subdirectory(3rdparty/qtiocompressor)
if (QJSON_FOUND)
include_directories(${QJSON_INCLUDE_DIR})
TARGET_LINK_LIBRARIES(cantata ${QJSON_LIBRARIES})
@@ -508,11 +505,10 @@ else (QJSON_FOUND)
TARGET_LINK_LIBRARIES(cantata qjson)
endif (QJSON_FOUND)
TARGET_LINK_LIBRARIES(cantata qtiocompressor)
add_subdirectory(3rdparty/qtiocompressor)
add_subdirectory(icons)
ADD_SUBDIRECTORY( icons )
target_link_libraries(cantata support sha2 ${QTLIBS} ${ZLIB_LIBRARIES})
target_link_libraries(cantata support qtiocompressor ${QTLIBS} ${ZLIB_LIBRARIES})
include_directories(${QTINCLUDES} ${ZLIB_INCLUDE_DIRS})
if (TAGLIB_FOUND)

View File

@@ -56,6 +56,8 @@
without categories. The intention is to be able to import these into
MPDroid.
37. For Qt4 linux builds, use system QJson if found.
38. Remove amazon cover fetching - required API key that Cantata never really
had.
1.0.3
-----

View File

@@ -31,7 +31,6 @@
#include "utils.h"
#include "spinner.h"
#include "icon.h"
#include "sha2/sha2.h"
#include "qjson/parser.h"
#include <QVBoxLayout>
#include <QLabel>
@@ -78,33 +77,6 @@ static QImage cropImage(QImage img, bool isArtist)
return img;
}
static QByteArray sha256(const QByteArray &data)
{
SHA256_CTX context;
SHA256_Init(&context);
SHA256_Update(&context, reinterpret_cast<const u_int8_t*>(data.constData()),
data.length());
QByteArray ret(SHA256_DIGEST_LENGTH, '\0');
SHA256_Final(reinterpret_cast<u_int8_t*>(ret.data()), &context);
return ret;
}
static QByteArray hmacSha256(const QByteArray &key, const QByteArray &data)
{
static const int constBlockSize = 64; // bytes
Q_ASSERT(key.length() <= constBlockSize);
QByteArray innerPadding(constBlockSize, char(0x36));
QByteArray outerPadding(constBlockSize, char(0x5c));
for (int i=0 ; i<key.length() ; ++i) {
innerPadding[i] = innerPadding[i] ^ key[i];
outerPadding[i] = outerPadding[i] ^ key[i];
}
return sha256(outerPadding + sha256(innerPadding + data));
}
int CoverDialog::instanceCount()
{
return iCount;
@@ -125,7 +97,6 @@ public:
Type_LastFm,
Type_Google,
Type_Discogs,
Type_Amazon,
Type_CoverArtArchive
};
@@ -237,25 +208,6 @@ private:
int height;
};
class AmazonCover : public CoverItem
{
public:
AmazonCover(const QString &u, const QString &tu, const QImage &img, int w, int h, QListWidget *parent)
: CoverItem(u, tu, parent)
, width(w)
, height(h) {
setImage(img);
setText(i18nc("Amazon\nwidth x height", "Amazon\n%1 x %2").arg(width).arg(height));
}
quint32 key() const { return width*height; }
Type type() const { return Type_Amazon; }
private:
int width;
int height;
};
class CoverArtArchiveCover : public CoverItem
{
public:
@@ -458,8 +410,6 @@ CoverDialog::CoverDialog(QWidget *parent)
cancelButton->setAutoRaise(true);
addFileButton->setAutoRaise(true);
setAcceptDrops(true);
amazonAccessKey=Settings::self()->amazonAccessKey();
amazonSecretAccessKey=Settings::self()->amazonSecretAccessKey();
}
CoverDialog::~CoverDialog()
@@ -509,9 +459,6 @@ static const char * constLastFmHost="ws.audioscrobbler.com";
static const char * constGoogleHost="images.google.com";
static const char * constDiscogsHost="api.discogs.com";
static const char * constCoverArtArchiveHost="coverartarchive.org";
static const char * constAmazonHost="ecs.amazonaws.com";
static const char * constAmazonUrl="http://ecs.amazonaws.com/onca/xml";
static const char * constAmazonAssociateTag="cantata";
static const int constMaxRedirects=5;
@@ -541,8 +488,6 @@ void CoverDialog::queryJobFinished()
parseDiscogsQueryResponse(resp);
} else if (constCoverArtArchiveHost==host) {
parseCoverArtArchiveQueryResponse(resp);
} else if (constAmazonHost==host) {
parseAmazonQueryResponse(resp);
}
}
}
@@ -690,9 +635,6 @@ void CoverDialog::downloadJobFinished()
}
} else if (constCoverArtArchiveHost==host) {
item=new CoverArtArchiveCover(reply->property(constLargeProperty).toString(), url, img, list);
} else if (constAmazonHost==host) {
item=new AmazonCover(reply->property(constLargeProperty).toString(), url, img,
reply->property(constWidthProperty).toInt(), reply->property(constHeightProperty).toInt(), list);
}
if (item) {
insertItem(item);
@@ -796,7 +738,6 @@ void CoverDialog::sendQuery()
sendGoogleQuery(fixedQuery, page);
if (!isArtist) {
sendDiscoGsQuery(fixedQuery, page);
sendAmazonQuery(fixedQuery, page);
}
}
@@ -865,65 +806,6 @@ void CoverDialog::sendDiscoGsQuery(const QString &fixedQuery, int page)
sendQueryRequest(url);
}
void CoverDialog::sendAmazonQuery(const QString &fixedQuery, int page)
{
#if QT_VERSION < 0x050000
if (0!=page || amazonAccessKey.isEmpty()) {
return;
}
// Taken from Clementine!!!
typedef QPair<QString, QString> Arg;
typedef QList<Arg> ArgList;
typedef QPair<QByteArray, QByteArray> EncodedArg;
typedef QList<EncodedArg> EncodedArgList;
ArgList args = ArgList()
<< Arg("AWSAccessKeyId", amazonAccessKey)
<< Arg("AssociateTag", constAmazonAssociateTag)
<< Arg("Keywords", fixedQuery)
<< Arg("Operation", "ItemSearch")
<< Arg("ResponseGroup", "Images")
<< Arg("SearchIndex", "All")
<< Arg("Service", "AWSECommerceService")
<< Arg("Timestamp", QDateTime::currentDateTime().toString("yyyy-MM-ddThh:mm:ss.zzzZ"))
<< Arg("Version", "2009-11-01");
EncodedArgList encodedArgs;
QStringList queryItems;
// Encode the arguments
foreach (const Arg& arg, args) {
EncodedArg encodedArg(QUrl::toPercentEncoding(arg.first), QUrl::toPercentEncoding(arg.second));
encodedArgs << encodedArg;
queryItems << encodedArg.first+"="+encodedArg.second;
}
// Sign the request
QUrl url(constAmazonUrl);
#if QT_VERSION < 0x050000
QUrl &query=url;
#else
QUrlQuery query;
#endif
const QByteArray dataToSign = QString("GET\n%1\n%2\n%3").arg(url.host()).arg(url.path()).arg(queryItems.join("&")).toAscii();
const QByteArray signature(hmacSha256(amazonSecretAccessKey.toLatin1(), dataToSign));
// Add the signature to the request
encodedArgs << EncodedArg("Signature", QUrl::toPercentEncoding(signature.toBase64()));
query.setEncodedQueryItems(encodedArgs);
#if QT_VERSION >= 0x050000
url.setQuery(query);
#endif
sendQueryRequest(url);
#else
// Qt5 has no non-deprecated version of 'setEncodedQueryItems', so for the moment Amazon searches are disabled for Qt5 builds...
Q_UNUSED(fixedQuery)
Q_UNUSED(page)
#endif
}
void CoverDialog::checkStatus()
{
QList<QListWidgetItem*> items=list->selectedItems();
@@ -1298,93 +1180,6 @@ void CoverDialog::parseCoverArtArchiveQueryResponse(const QByteArray &resp)
}
}
struct AmazonImage
{
AmazonImage() : w(-1), h(-1) { }
bool isNull() { return w<0 || h<0 || url.isEmpty(); }
QString url;
int w;
int h;
};
struct AmazonEntry
{
AmazonImage small;
AmazonImage large;
};
static AmazonImage readImage(QXmlStreamReader &doc)
{
AmazonImage image;
QString tag=doc.name().toString();
while (!doc.atEnd()) {
doc.readNext();
if (QXmlStreamReader::StartElement==doc.tokenType()) {
if (QLatin1String("URL")==doc.name()) {
image.url= doc.readElementText();
} else if (QLatin1String("Width")==doc.name()) {
image.w=doc.readElementText().toInt();
} else if (QLatin1String("Height")==doc.name()) {
image.h=doc.readElementText().toInt();
} else {
doc.skipCurrentElement();
}
} else if (QXmlStreamReader::EndElement==doc.tokenType() && tag==doc.name()) {
break;
}
}
return image;
}
static AmazonEntry readItem(QXmlStreamReader &doc)
{
AmazonEntry entry;
QString tag=doc.name().toString();
while (!doc.atEnd()) {
doc.readNext();
if (QXmlStreamReader::StartElement==doc.tokenType()) {
if (QLatin1String("LargeImage")==doc.name()) {
entry.large=readImage(doc);
} else if (QLatin1String("SmallImage")==doc.name()) {
entry.small=readImage(doc);
} else if (entry.small.h<0 && QLatin1String("MediumImage")==doc.name()) {
entry.small=readImage(doc);
} else {
doc.skipCurrentElement();
}
} else if (QXmlStreamReader::EndElement==doc.tokenType() && tag==doc.name()) {
break;
}
}
return entry;
}
void CoverDialog::parseAmazonQueryResponse(const QByteArray &resp)
{
QXmlStreamReader doc(resp);
while (!doc.atEnd()) {
doc.readNext();
if (QXmlStreamReader::StartElement==doc.tokenType()) {
if (QLatin1String("Item")==doc.name()) {
AmazonEntry entry=readItem(doc);
if (!entry.small.isNull() && !entry.large.isNull()) {
QNetworkReply *j=downloadImage(entry.small.url, DL_Thumbnail);
if (j) {
j->setProperty(constHostProperty, constAmazonHost);
j->setProperty(constLargeProperty, entry.large.url);
j->setProperty(constThumbProperty, entry.small.url);
j->setProperty(constWidthProperty, entry.large.w);
j->setProperty(constHeightProperty, entry.large.h);
}
}
}
}
}
}
void CoverDialog::slotButtonClicked(int button)
{
switch (button) {

View File

@@ -120,7 +120,6 @@ private:
void sendLastFmQuery(const QString &fixedQuery, int page);
void sendGoogleQuery(const QString &fixedQuery, int page);
void sendDiscoGsQuery(const QString &fixedQuery, int page);
void sendAmazonQuery(const QString &fixedQuery, int page);
CoverPreview *previewDialog();
void insertItem(CoverItem *item);
QNetworkReply * downloadImage(const QString &url, DownloadType dlType);
@@ -130,7 +129,6 @@ private:
void parseGoogleQueryResponse(const QByteArray &resp);
void parseDiscogsQueryResponse(const QByteArray &resp);
void parseCoverArtArchiveQueryResponse(const QByteArray &resp);
void parseAmazonQueryResponse(const QByteArray &resp);
void slotButtonClicked(int button);
bool saveCover(const QString &src, const QImage &img);
void dragEnterEvent(QDragEnterEvent *event);
@@ -153,8 +151,6 @@ private:
QMenu *menu;
QAction *showAction;
QAction *removeAction;
QString amazonAccessKey;
QString amazonSecretAccessKey;
};
#endif

View File

@@ -654,16 +654,6 @@ bool Settings::monoSidebarIcons()
#endif
}
QString Settings::amazonAccessKey()
{
return GET_STRING("amazonAccessKey", QString());
}
QString Settings::amazonSecretAccessKey()
{
return GET_STRING("amazonSecretAccessKey", QString());
}
void Settings::removeConnectionDetails(const QString &v)
{
if (v==currentConnection()) {

View File

@@ -172,8 +172,6 @@ public:
bool forceSingleClick();
bool startHidden();
bool monoSidebarIcons();
QString amazonAccessKey();
QString amazonSecretAccessKey();
void removeConnectionDetails(const QString &v);
void saveConnectionDetails(const MPDConnectionDetails &v);