2012-11-29 18:19:41 +01:00
|
|
|
#include "dropboxservice.h"
|
|
|
|
|
2012-11-29 20:18:08 +01:00
|
|
|
#include <QFileInfo>
|
|
|
|
|
2012-11-29 18:48:49 +01:00
|
|
|
#include <qjson/parser.h>
|
|
|
|
|
2012-11-29 20:18:08 +01:00
|
|
|
#include "core/application.h"
|
2012-11-29 18:43:56 +01:00
|
|
|
#include "core/logging.h"
|
|
|
|
#include "core/network.h"
|
2012-11-29 20:18:08 +01:00
|
|
|
#include "core/player.h"
|
2012-11-29 20:36:13 +01:00
|
|
|
#include "core/utilities.h"
|
2012-11-29 20:18:08 +01:00
|
|
|
#include "core/waitforsignal.h"
|
2012-11-29 18:19:41 +01:00
|
|
|
#include "internet/dropboxauthenticator.h"
|
2012-11-29 20:18:08 +01:00
|
|
|
#include "internet/dropboxurlhandler.h"
|
2012-11-29 20:36:13 +01:00
|
|
|
#include "library/librarybackend.h"
|
|
|
|
|
|
|
|
using Utilities::ParseRFC822DateTime;
|
2012-11-29 18:19:41 +01:00
|
|
|
|
|
|
|
const char* DropboxService::kServiceName = "Dropbox";
|
|
|
|
const char* DropboxService::kSettingsGroup = "Dropbox";
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
static const char* kServiceId = "dropbox";
|
|
|
|
|
2012-11-29 20:18:08 +01:00
|
|
|
static const char* kMediaEndpoint =
|
|
|
|
"https://api.dropbox.com/1/media/dropbox/";
|
2012-11-30 15:33:03 +01:00
|
|
|
static const char* kDeltaEndpoint =
|
|
|
|
"https://api.dropbox.com/1/delta";
|
2012-11-29 18:43:56 +01:00
|
|
|
|
2012-11-29 18:19:41 +01:00
|
|
|
} // namespace
|
|
|
|
|
|
|
|
DropboxService::DropboxService(Application* app, InternetModel* parent)
|
|
|
|
: CloudFileService(
|
|
|
|
app, parent,
|
|
|
|
kServiceName, kServiceId,
|
|
|
|
QIcon(":/providers/dropbox.png"),
|
2012-12-05 10:36:22 +01:00
|
|
|
SettingsDialog::Page_Dropbox),
|
2012-11-29 18:43:56 +01:00
|
|
|
network_(new NetworkAccessManager(this)) {
|
|
|
|
QSettings settings;
|
|
|
|
settings.beginGroup(kSettingsGroup);
|
|
|
|
access_token_ = settings.value("access_token").toString();
|
|
|
|
access_token_secret_ = settings.value("access_token_secret").toString();
|
2012-11-29 20:18:08 +01:00
|
|
|
app->player()->RegisterUrlHandler(new DropboxUrlHandler(this, this));
|
2012-11-29 18:19:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
bool DropboxService::has_credentials() const {
|
|
|
|
return !access_token_.isEmpty();
|
|
|
|
}
|
|
|
|
|
|
|
|
void DropboxService::Connect() {
|
2012-11-29 18:43:56 +01:00
|
|
|
if (has_credentials()) {
|
2012-11-30 15:33:03 +01:00
|
|
|
RequestFileList();
|
2012-11-29 18:19:41 +01:00
|
|
|
} else {
|
|
|
|
ShowSettingsDialog();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void DropboxService::AuthenticationFinished(DropboxAuthenticator* authenticator) {
|
|
|
|
authenticator->deleteLater();
|
|
|
|
|
2012-11-29 18:43:56 +01:00
|
|
|
access_token_ = authenticator->access_token();
|
|
|
|
access_token_secret_ = authenticator->access_token_secret();
|
|
|
|
|
2012-11-29 18:19:41 +01:00
|
|
|
QSettings settings;
|
|
|
|
settings.beginGroup(kSettingsGroup);
|
|
|
|
|
2012-11-29 18:43:56 +01:00
|
|
|
settings.setValue("access_token", access_token_);
|
|
|
|
settings.setValue("access_token_secret", access_token_secret_);
|
2012-11-29 18:19:41 +01:00
|
|
|
settings.setValue("name", authenticator->name());
|
|
|
|
|
|
|
|
emit Connected();
|
2012-11-29 18:43:56 +01:00
|
|
|
|
2012-11-30 15:33:03 +01:00
|
|
|
RequestFileList();
|
2012-11-29 18:43:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
QByteArray DropboxService::GenerateAuthorisationHeader() {
|
|
|
|
return DropboxAuthenticator::GenerateAuthorisationHeader(
|
|
|
|
access_token_,
|
|
|
|
access_token_secret_);
|
|
|
|
}
|
|
|
|
|
2012-11-30 15:33:03 +01:00
|
|
|
void DropboxService::RequestFileList() {
|
|
|
|
QSettings s;
|
|
|
|
s.beginGroup(kSettingsGroup);
|
|
|
|
|
|
|
|
QUrl url = QUrl(QString(kDeltaEndpoint));
|
|
|
|
if (s.contains("cursor")) {
|
|
|
|
url.addQueryItem("cursor", s.value("cursor").toString());
|
|
|
|
}
|
2012-11-29 18:43:56 +01:00
|
|
|
QNetworkRequest request(url);
|
|
|
|
request.setRawHeader("Authorization", GenerateAuthorisationHeader());
|
|
|
|
|
2012-11-30 15:33:03 +01:00
|
|
|
QNetworkReply* reply = network_->post(request, QByteArray());
|
2012-11-29 18:43:56 +01:00
|
|
|
NewClosure(reply, SIGNAL(finished()),
|
|
|
|
this, SLOT(RequestFileListFinished(QNetworkReply*)), reply);
|
|
|
|
}
|
|
|
|
|
|
|
|
void DropboxService::RequestFileListFinished(QNetworkReply* reply) {
|
|
|
|
reply->deleteLater();
|
2012-11-29 18:48:49 +01:00
|
|
|
|
|
|
|
QJson::Parser parser;
|
|
|
|
QVariantMap response = parser.parse(reply).toMap();
|
2012-11-30 15:33:03 +01:00
|
|
|
if (response.contains("reset") &&
|
|
|
|
response["reset"].toBool()) {
|
2012-11-30 15:40:09 +01:00
|
|
|
qLog(Debug) << "Resetting Dropbox DB";
|
|
|
|
library_backend_->DeleteAll();
|
2012-11-30 15:33:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
QSettings settings;
|
|
|
|
settings.beginGroup(kSettingsGroup);
|
|
|
|
settings.setValue("cursor", response["cursor"].toString());
|
|
|
|
|
|
|
|
QVariantList contents = response["entries"].toList();
|
|
|
|
qLog(Debug) << "Delta found:" << contents.size();
|
2012-11-29 18:48:49 +01:00
|
|
|
foreach (const QVariant& c, contents) {
|
2012-11-30 15:33:03 +01:00
|
|
|
QVariantList item = c.toList();
|
|
|
|
QString path = item[0].toString();
|
2012-11-30 15:40:09 +01:00
|
|
|
|
|
|
|
QUrl url;
|
|
|
|
url.setScheme("dropbox");
|
|
|
|
url.setPath(path);
|
|
|
|
|
|
|
|
if (item[1].isNull()) {
|
|
|
|
// Null metadata indicates path deleted.
|
|
|
|
qLog(Debug) << "Deleting:" << url;
|
|
|
|
Song song = library_backend_->GetSongByUrl(url);
|
|
|
|
if (song.is_valid()) {
|
|
|
|
library_backend_->DeleteSongs(SongList() << song);
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2012-11-30 15:33:03 +01:00
|
|
|
QVariantMap metadata = item[1].toMap();
|
|
|
|
if (metadata["is_dir"].toBool()) {
|
|
|
|
continue;
|
2012-11-29 18:48:49 +01:00
|
|
|
}
|
2012-12-06 14:23:27 +01:00
|
|
|
|
|
|
|
if (ShouldIndexFile(url, metadata["mime_type"].toString())) {
|
|
|
|
QNetworkReply* reply = FetchContentUrl(url);
|
|
|
|
NewClosure(reply, SIGNAL(finished()),
|
|
|
|
this, SLOT(FetchContentUrlFinished(QNetworkReply*, QVariantMap)),
|
|
|
|
reply, metadata);
|
|
|
|
}
|
2012-11-30 15:33:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (response.contains("has_more") && response["has_more"].toBool()) {
|
|
|
|
RequestFileList();
|
2012-11-29 18:48:49 +01:00
|
|
|
}
|
2012-11-29 18:19:41 +01:00
|
|
|
}
|
2012-11-29 20:18:08 +01:00
|
|
|
|
|
|
|
QNetworkReply* DropboxService::FetchContentUrl(const QUrl& url) {
|
2013-05-16 16:40:32 +02:00
|
|
|
QUrl request_url = QUrl((QString(kMediaEndpoint)));
|
|
|
|
request_url.setPath(request_url.path() + url.path().mid(1));
|
2012-11-29 20:18:08 +01:00
|
|
|
QNetworkRequest request(request_url);
|
|
|
|
request.setRawHeader("Authorization", GenerateAuthorisationHeader());
|
|
|
|
return network_->post(request, QByteArray());
|
|
|
|
}
|
|
|
|
|
|
|
|
void DropboxService::FetchContentUrlFinished(
|
|
|
|
QNetworkReply* reply, const QVariantMap& data) {
|
|
|
|
reply->deleteLater();
|
|
|
|
QJson::Parser parser;
|
|
|
|
QVariantMap response = parser.parse(reply).toMap();
|
|
|
|
QFileInfo info(data["path"].toString());
|
|
|
|
|
2012-11-29 20:36:13 +01:00
|
|
|
QUrl url;
|
|
|
|
url.setScheme("dropbox");
|
2012-12-06 14:23:27 +01:00
|
|
|
url.setPath(data["path"].toString());
|
2012-11-29 20:36:13 +01:00
|
|
|
|
2012-12-06 14:23:27 +01:00
|
|
|
Song song;
|
|
|
|
song.set_url(url);
|
|
|
|
song.set_etag(data["rev"].toString());
|
|
|
|
song.set_mtime(ParseRFC822DateTime(data["modified"].toString()).toTime_t());
|
|
|
|
song.set_title(info.fileName());
|
|
|
|
song.set_filesize(data["bytes"].toInt());
|
|
|
|
song.set_ctime(0);
|
|
|
|
|
|
|
|
MaybeAddFileToDatabase(
|
|
|
|
song,
|
|
|
|
data["mime_type"].toString(),
|
|
|
|
QUrl::fromEncoded(response["url"].toByteArray()),
|
|
|
|
QString::null);
|
2012-11-29 20:18:08 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
QUrl DropboxService::GetStreamingUrlFromSongId(const QUrl& url) {
|
|
|
|
QNetworkReply* reply = FetchContentUrl(url);
|
|
|
|
WaitForSignal(reply, SIGNAL(finished()));
|
|
|
|
|
|
|
|
QJson::Parser parser;
|
|
|
|
QVariantMap response = parser.parse(reply).toMap();
|
2013-02-18 11:09:35 +01:00
|
|
|
return QUrl::fromEncoded(response["url"].toByteArray());
|
2012-11-29 20:18:08 +01:00
|
|
|
}
|