[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    KDE/kdemultimedia/juk
From:       Martin Tobias Holmedahl Sandsmark <sandsmark () iskrembilen ! com>
Date:       2012-02-25 0:46:06
Message-ID: 20120225004606.80AB7AC896 () svn ! kde ! org
[Download RAW message or body]

SVN commit 1282145 by sandsmark:

Redo cover fetching.

Yahoo has discontinued their image search API, so cover downloading has been
broken for a while now. Google has also deprecated their own image search API,
so now we instead get all covers directly from last.fm.



 M  +0 -1      CMakeLists.txt  
 M  +1 -1      playlist.cpp  
 M  +86 -122   webimagefetcher.cpp  
 M  +6 -30     webimagefetcher.h  
 D             webimagefetcherdialog.cpp  
 D             webimagefetcherdialog.h  


--- trunk/KDE/kdemultimedia/juk/CMakeLists.txt #1282144:1282145
@@ -57,7 +57,6 @@
    filerenameroptions.cpp
    filerenamerconfigdlg.cpp
    webimagefetcher.cpp
-   webimagefetcherdialog.cpp
    historyplaylist.cpp
    juk.cpp
    k3bexporter.cpp
--- trunk/KDE/kdemultimedia/juk/playlist.cpp #1282144:1282145
@@ -844,7 +844,7 @@
 
     if(!retrieveLocal) {
         m_fetcher->setFile((*items.begin())->file());
-        m_fetcher->chooseCover();
+        m_fetcher->searchCover();
         return;
     }
 
--- trunk/KDE/kdemultimedia/juk/webimagefetcher.cpp #1282144:1282145
@@ -1,6 +1,7 @@
 /***************************************************************************
     copyright            : (C) 2004 Nathan Toone <nathan@toonetown.com>
     copyright            : (C) 2007 Michael Pyne <michael.pyne@kdemail.com>
+    copyright            : (C) 2012 Martin Sandsmark <martin.sandsmark@kde.org>
 ***************************************************************************/
 
 /***************************************************************************
@@ -14,17 +15,18 @@
 
 #include "webimagefetcher.h"
 
-#include <kapplication.h>
-#include <kstatusbar.h>
-#include <kxmlguiwindow.h>
-#include <klocale.h>
-#include <kinputdialog.h>
-#include <kurl.h>
-#include <kdebug.h>
-#include <kio/job.h>
+#include <KApplication>
+#include <KStatusBar>
+#include <KXmlGuiWindow>
+#include <KLocale>
+#include <KInputDialog>
+#include <KUrl>
+#include <KDebug>
+#include <KIO/Job>
+#include <KPushButton>
+#include <KDialog>
 
 #include "covermanager.h"
-#include "webimagefetcherdialog.h"
 #include "filehandle.h"
 #include "tag.h"
 #include "juk.h"
@@ -33,34 +35,25 @@
 #include <QDomDocument>
 #include <QDomElement>
 #include <QPointer>
+#include <QLayout>
+#include <QLabel>
+#include <QPainter>
 
-WebImage::WebImage()
-{
-}
 
-WebImage::WebImage(const QString &imageURL, const QString &thumbURL,
-                         int width, int height) :
-    m_imageURL(imageURL),
-    m_thumbURL(thumbURL),
-    m_size(QString("\n%1 x %2").arg(width).arg(height))
-{
-}
-
 class WebImageFetcher::Private
 {
     friend class WebImageFetcher;
 
-    Private() : selectedIndex(0), connection(0), dialog(0)
+    Private() : connection(0), dialog(0)
     {
     }
 
     FileHandle file;
-    QString searchString;
-    QString loadedQuery;
-    WebImageList imageList;
-    uint selectedIndex;
+    QString artist;
+    QString albumName;
     QPointer<KIO::StoredTransferJob> connection;
-    WebImageFetcherDialog *dialog;
+    KDialog *dialog;
+    KUrl url;
 };
 
 WebImageFetcher::WebImageFetcher(QObject *parent)
@@ -70,17 +63,14 @@
 
 WebImageFetcher::~WebImageFetcher()
 {
-    delete d->dialog;
     delete d;
 }
 
 void WebImageFetcher::setFile(const FileHandle &file)
 {
     d->file = file;
-    d->searchString = QString(file.tag()->artist() + ' ' + file.tag()->album());
-
-    if(d->dialog)
-	d->dialog->setFile(file);
+    d->artist = file.tag()->artist();
+    d->albumName = file.tag()->album();
 }
 
 void WebImageFetcher::abortSearch()
@@ -88,20 +78,17 @@
     if(d->connection)
         d->connection->kill();
 }
-
-void WebImageFetcher::chooseCover()
+void WebImageFetcher::searchCover()
 {
-    slotLoadImageURLs();
-}
+    KStatusBar *statusBar = JuK::JuKInstance()->statusBar();
+    statusBar->showMessage(i18n("Searching for cover. Please Wait..."));
 
-void WebImageFetcher::slotLoadImageURLs()
-{
-    d->imageList.clear();
 
-    KUrl url("http://search.yahooapis.com/ImageSearchService/V1/imageSearch");
-    url.addQueryItem("appid", "org.kde.juk/kde4");
-    url.addQueryItem("query", d->searchString);
-    url.addQueryItem("results", "25");
+    KUrl url("http://ws.audioscrobbler.com/2.0/");
+    url.addQueryItem("method", "album.getInfo");
+    url.addQueryItem("api_key", "3e6ecbd7284883089e8f2b5b53b0aecd");
+    url.addQueryItem("artist", d->artist);
+    url.addQueryItem("album", d->albumName);
 
     kDebug() << "Using request " << url.encodedPathAndQuery();
 
@@ -119,14 +106,14 @@
         return;
 
     if(!job || job->error()) {
-	kError() << "Error reading image results from Yahoo!\n";
+        kError() << "Error reading image results from last.fm!\n";
 	kError() << d->connection->errorString() << endl;
 	return;
     }
 
     kDebug() << "Checking for data!!\n";
     if(d->connection->data().isEmpty()) {
-        kError() << "Yahoo image search returned an empty result!\n";
+        kError() << "last.fm returned an empty result!\n";
         return;
     }
 
@@ -135,7 +122,7 @@
     QString errorStr;
     int errorCol, errorLine;
     if(!results.setContent(d->connection->data(), &errorStr, &errorLine, &errorCol)) {
-	kError() << "Unable to create XML document from Yahoo results.\n";
+        kError() << "Unable to create XML document from results.\n";
 	kError() << "Line " << errorLine << ", " << errorStr << endl;
 
 	return;
@@ -143,112 +130,89 @@
 
     QDomNode n = results.documentElement();
 
-    bool hasNoResults = false;
-
     if(n.isNull()) {
 	kDebug() << "No document root in XML results??\n";
-	hasNoResults = true;
+        return;
     }
-    else {
-	QDomElement result = n.toElement();
-	if(result.attribute("totalResultsReturned").toInt() == 0)
-	    kDebug() << "Search returned " << result.attribute("totalResultsAvailable") << " results.\n";
+    n = n.firstChildElement("album");
 
-	if(result.isNull() || !result.hasAttribute("totalResultsReturned") ||
-	    result.attribute("totalResultsReturned").toInt() == 0)
-	{
-	    hasNoResults = true;
+    d->url = n.lastChildElement("image").text(); //FIXME: We assume they have a sane sorting (smallest -> largest)
+    //TODO: size attribute can have the values mega, extralarge, large, medium and small
+    
+    kDebug() << "Got cover:" << d->url;
+
+    KStatusBar *statusBar = JuK::JuKInstance()->statusBar();
+    statusBar->showMessage(i18n("Downloading cover. Please Wait..."));
+    
+    KIO::StoredTransferJob *newJob = KIO::storedGet(d->url, KIO::Reload /* reload always */, KIO::HideProgressInfo);
+    connect(newJob, SIGNAL(result(KJob*)), SLOT(slotImageFetched(KJob*)));
 	}
-    }
 
-    if(hasNoResults)
+void WebImageFetcher::slotImageFetched(KJob* j)
     {
-	kDebug() << "Search returned no results.\n";
-	requestNewSearchTerms(true /* no results */);
-        return;
-    }
+    KStatusBar *statusBar = JuK::JuKInstance()->statusBar();
+    statusBar->clearMessage();
 
-    // Go through each of the top (result) nodes
+    KIO::StoredTransferJob *job = qobject_cast<KIO::StoredTransferJob*>(j);
 
-    n = n.firstChild();
-    while(!n.isNull()) {
-	QDomNode resultUrl = n.namedItem("Url");
-	QDomNode thumbnail = n.namedItem("Thumbnail");
-	QDomNode height = n.namedItem("Height");
-	QDomNode width = n.namedItem("Width");
+    if (d->dialog) return;
+    d->dialog = new KDialog();
+    d->dialog->setCaption("Cover found");
+    d->dialog->setButtons(KDialog::Apply | KDialog::Cancel);
+    d->dialog->button(KDialog::Apply)->setText(i18n("Store"));
+    QWidget *mainWidget = new QWidget();
+    d->dialog->setMainWidget(mainWidget);
+    mainWidget->setLayout(new QVBoxLayout);
 
-	// We have the necessary info, move to next node before we forget.
-	n = n.nextSibling();
-
-	if(resultUrl.isNull() || thumbnail.isNull() || height.isNull() || width.isNull()) {
-	    kError() << "Invalid result returned, skipping.\n";
-	    continue;
+    if(job->error()) {
+        kError() << "Unable to grab image\n";
+        d->dialog->setWindowIcon(DesktopIcon("dialog-error"));
+        return;
 	}
 
-	d->imageList.append(
-	    WebImage(
-	        resultUrl.toElement().text(),
-		thumbnail.namedItem("Url").toElement().text(),
-		width.toElement().text().toInt(),
-		height.toElement().text().toInt()
-	    )
-	);
+    QPixmap iconImage, realImage(150, 150);
+    iconImage.loadFromData(job->data());
+    realImage.fill(Qt::transparent);
+
+    if(iconImage.isNull()) {
+        kError() << "Thumbnail image is not of a supported format\n";
+        return;
     }
 
-    // Have results, show them and pick one.
+    // Scale down if necesssary
+    if(iconImage.width() > 150 || iconImage.height() > 150)
+        iconImage = iconImage.scaled(150, 150, Qt::KeepAspectRatio, Qt::SmoothTransformation);
 
-    if(!d->dialog) {
-        d->dialog = new WebImageFetcherDialog(d->imageList, d->file, 0);
-	d->dialog->setModal(true);
+    QLabel *cover = new QLabel();
+    cover->setPixmap(iconImage);
+    mainWidget->layout()->addWidget(cover);
+    QLabel *infoLabel = new QLabel(i18n("Cover fetched from <a href='http://last.fm/'>last.fm</a>."));
+    infoLabel->setOpenExternalLinks(true);
+    infoLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
+    mainWidget->layout()->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Expanding));
+    mainWidget->layout()->addWidget(infoLabel);
 
-	connect(d->dialog, SIGNAL(coverSelected(KUrl)), SLOT(slotCoverChosen(KUrl)));
-	connect(d->dialog, SIGNAL(newSearchRequested()), SLOT(slotNewSearch()));
-    }
-
-    d->dialog->refreshScreen(d->imageList);
+    d->dialog->setWindowIcon(realImage);
     d->dialog->show();
+    connect(d->dialog, SIGNAL(applyClicked()), SLOT(slotCoverChosen()));
 }
 
-void WebImageFetcher::slotCoverChosen(const KUrl &path)
+
+void WebImageFetcher::slotCoverChosen()
 {
     kDebug() << "Adding new cover for " << d->file.tag()->fileName()
-                  << "from URL" << path;
+    << "from URL" << d->url;
 
-    coverKey newId = CoverManager::addCover(path, d->file.tag()->artist(), d->file.tag()->album());
+    coverKey newId = CoverManager::addCover(d->url, d->file.tag()->artist(), d->file.tag()->album());
 
     if(newId != CoverManager::NoMatch) {
         emit signalCoverChanged(newId);
         d->dialog->close();
+        d->dialog->deleteLater();
+        d->dialog = 0;
     }
 }
 
-void WebImageFetcher::slotNewSearch()
-{
-    requestNewSearchTerms();
-}
-
-void WebImageFetcher::displayWaitMessage()
-{
-    KStatusBar *statusBar = JuK::JuKInstance()->statusBar();
-    statusBar->showMessage(i18n("Searching for Images. Please Wait..."));
-    slotLoadImageURLs();
-    statusBar->clearMessage();
-}
-
-void WebImageFetcher::requestNewSearchTerms(bool noResults)
-{
-    bool ok;
-    QString search = KInputDialog::getText(i18n("Cover Downloader"),
-                                           noResults ?
-                                             i18n("No matching images found, please enter new search terms:") :
-                                             i18n("Enter new search terms:"),
-                                           d->searchString, &ok);
-    if(ok && !search.isEmpty()) {
-        d->searchString = search;
-        displayWaitMessage(); // This kicks off the new search
-    }
-}
-
 #include "webimagefetcher.moc"
 
 // vim: set et sw=4 tw=0 sta:
--- trunk/KDE/kdemultimedia/juk/webimagefetcher.h #1282144:1282145
@@ -3,6 +3,8 @@
     email                : nathan@toonetown.com
     copyright            : (C) 2007 Michael Pyne
     email                : michael.pyne@kdemail.net
+    copyright            : (C) 2012 Martin Sandsmark
+    email                : martin.sandsmark@kde.org
 ***************************************************************************/
 
 /***************************************************************************
@@ -18,7 +20,6 @@
 #define WEBIMAGEFETCHER_H
 
 #include <QObject>
-#include <QString>
 
 // Predeclare some classes.
 
@@ -31,27 +32,7 @@
 
 class FileHandle;
 
-class WebImage
-{
-public:
-    WebImage();
 
-    WebImage(const QString &imageURL,
-                const QString &thumbURL,
-                int width, int height);
-
-    QString imageURL() const { return m_imageURL; }
-    QString thumbURL() const { return m_thumbURL; }
-    QString size() const { return m_size; }
-
-private:
-    QString m_imageURL;
-    QString m_thumbURL;
-    QString m_size;
-};
-
-typedef QList<WebImage> WebImageList;
-
 class WebImageFetcher : public QObject
 {
     Q_OBJECT
@@ -61,24 +42,19 @@
     ~WebImageFetcher();
 
     void setFile(const FileHandle &file);
-    void chooseCover();
 
 public slots:
     void abortSearch();
+    void searchCover();
 
+
 signals:
-    void signalNewSearch(WebImageList &images);
     void signalCoverChanged(int coverId);
 
-private:
-    void displayWaitMessage();
-    void requestNewSearchTerms(bool noResults = false);
-
 private slots:
-    void slotLoadImageURLs();
     void slotWebRequestFinished(KJob *job);
-    void slotCoverChosen(const KUrl &);
-    void slotNewSearch();
+    void slotImageFetched(KJob *job);
+    void slotCoverChosen();
 
 private:
     class Private;
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic