From ecf7998f1cc170bfad42ab3d1dcd0cf2b6dacbcc Mon Sep 17 00:00:00 2001 From: John Maguire Date: Thu, 26 Jul 2012 16:35:57 +0200 Subject: [PATCH] Add URL handler for googledrive URLs and fetch a new temporary download URL for every play. --- src/CMakeLists.txt | 2 ++ src/internet/googledriveservice.cpp | 28 +++++++++++++++++++++++++- src/internet/googledriveservice.h | 2 ++ src/internet/googledriveurlhandler.cpp | 16 +++++++++++++++ src/internet/googledriveurlhandler.h | 21 +++++++++++++++++++ 5 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 src/internet/googledriveurlhandler.cpp create mode 100644 src/internet/googledriveurlhandler.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1bc7399b1..bb03e76e7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -161,6 +161,7 @@ set(SOURCES internet/digitallyimportedurlhandler.cpp internet/geolocator.cpp internet/googledriveservice.cpp + internet/googledriveurlhandler.cpp internet/groovesharkradio.cpp internet/groovesharkservice.cpp internet/groovesharksettingspage.cpp @@ -433,6 +434,7 @@ set(HEADERS internet/digitallyimportedsettingspage.h internet/geolocator.h internet/googledriveservice.h + internet/googledriveurlhandler.h internet/groovesharkservice.h internet/groovesharksettingspage.h internet/groovesharkurlhandler.h diff --git a/src/internet/googledriveservice.cpp b/src/internet/googledriveservice.cpp index c2f5d0e1e..854a912fd 100644 --- a/src/internet/googledriveservice.cpp +++ b/src/internet/googledriveservice.cpp @@ -11,13 +11,17 @@ #include using TagLib::ByteVector; +#include "core/application.h" #include "core/closure.h" +#include "core/player.h" +#include "googledriveurlhandler.h" #include "internetmodel.h" #include "oauthenticator.h" namespace { static const char* kGoogleDriveFiles = "https://www.googleapis.com/drive/v2/files"; +static const char* kGoogleDriveFile = "https://www.googleapis.com/drive/v2/files/%1"; } @@ -186,6 +190,8 @@ GoogleDriveService::GoogleDriveService(Application* app, InternetModel* parent) root_(NULL), oauth_(new OAuthenticator(this)) { connect(oauth_, SIGNAL(AccessTokenAvailable(QString)), SLOT(AccessTokenAvailable(QString))); + + app->player()->RegisterUrlHandler(new GoogleDriveUrlHandler(this, this)); } QStandardItem* GoogleDriveService::CreateRootItem() { @@ -253,8 +259,11 @@ void GoogleDriveService::ListFilesFinished(QNetworkReply* reply) { song.set_title(tag.tag()->title().toCString(true)); song.set_artist(tag.tag()->artist().toCString(true)); song.set_album(tag.tag()->album().toCString(true)); - QString url = file["downloadUrl"].toString() + "#" + access_token_; + + QString url = QString("googledrive:%1").arg(file["id"].toString()); song.set_url(url); + qLog(Debug) << "Set url to:" << url; + song.set_filesize(file["fileSize"].toInt()); root_->appendRow(CreateSongItem(song)); } else { @@ -262,3 +271,20 @@ void GoogleDriveService::ListFilesFinished(QNetworkReply* reply) { } } } + +QUrl GoogleDriveService::GetStreamingUrlFromSongId(const QString& id) { + QString url = QString(kGoogleDriveFile).arg(id); + QNetworkRequest request = QNetworkRequest(url); + request.setRawHeader( + "Authorization", QString("Bearer %1").arg(access_token_).toUtf8()); + QNetworkReply* reply = network_.get(request); + QEventLoop loop; + connect(reply, SIGNAL(finished()), &loop, SLOT(quit())); + loop.exec(); + + QJson::Parser parser; + bool ok = false; + QVariantMap result = parser.parse(reply, &ok).toMap(); + QString download_url = result["downloadUrl"].toString() + "#" + access_token_; + return QUrl(download_url); +} diff --git a/src/internet/googledriveservice.h b/src/internet/googledriveservice.h index 79ee1b68d..f27624650 100644 --- a/src/internet/googledriveservice.h +++ b/src/internet/googledriveservice.h @@ -17,6 +17,8 @@ class GoogleDriveService : public InternetService { QStandardItem* CreateRootItem(); void LazyPopulate(QStandardItem* item); + QUrl GetStreamingUrlFromSongId(const QString& file_id); + private slots: void AccessTokenAvailable(const QString& token); void ListFilesFinished(QNetworkReply* reply); diff --git a/src/internet/googledriveurlhandler.cpp b/src/internet/googledriveurlhandler.cpp new file mode 100644 index 000000000..3c74e72dc --- /dev/null +++ b/src/internet/googledriveurlhandler.cpp @@ -0,0 +1,16 @@ +#include "googledriveurlhandler.h" + +#include "googledriveservice.h" + +GoogleDriveUrlHandler::GoogleDriveUrlHandler( + GoogleDriveService* service, + QObject* parent) + : UrlHandler(parent), + service_(service) { +} + +UrlHandler::LoadResult GoogleDriveUrlHandler::StartLoading(const QUrl& url) { + QString file_id = url.path(); + QUrl real_url = service_->GetStreamingUrlFromSongId(file_id); + return LoadResult(url, LoadResult::TrackAvailable, real_url); +} diff --git a/src/internet/googledriveurlhandler.h b/src/internet/googledriveurlhandler.h new file mode 100644 index 000000000..46b1bebea --- /dev/null +++ b/src/internet/googledriveurlhandler.h @@ -0,0 +1,21 @@ +#ifndef GOOGLEDRIVEURLHANDLER_H +#define GOOGLEDRIVEURLHANDLER_H + +#include "core/urlhandler.h" + +class GoogleDriveService; + +class GoogleDriveUrlHandler : public UrlHandler { + Q_OBJECT + public: + GoogleDriveUrlHandler(GoogleDriveService* service, QObject* parent = 0); + + QString scheme() const { return "googledrive"; } + QIcon icon() const { return QIcon(":providers/googledrive.png"); } + LoadResult StartLoading(const QUrl& url); + + private: + GoogleDriveService* service_; +}; + +#endif