Support indexing files from Skydrive.

This commit is contained in:
John Maguire 2012-12-13 14:27:21 +01:00
parent c4db401597
commit 919e9215c4
9 changed files with 165 additions and 24 deletions

View File

@ -336,6 +336,7 @@
<file>schema/schema-3.sql</file>
<file>schema/schema-40.sql</file>
<file>schema/schema-41.sql</file>
<file>schema/schema-42.sql</file>
<file>schema/schema-4.sql</file>
<file>schema/schema-5.sql</file>
<file>schema/schema-6.sql</file>

48
data/schema/schema-42.sql Normal file
View File

@ -0,0 +1,48 @@
CREATE TABLE skydrive_songs(
title TEXT,
album TEXT,
artist TEXT,
albumartist TEXT,
composer TEXT,
track INTEGER,
disc INTEGER,
bpm REAL,
year INTEGER,
genre TEXT,
comment TEXT,
compilation INTEGER,
length INTEGER,
bitrate INTEGER,
samplerate INTEGER,
directory INTEGER NOT NULL,
filename TEXT NOT NULL,
mtime INTEGER NOT NULL,
ctime INTEGER NOT NULL,
filesize INTEGER NOT NULL,
sampler INTEGER NOT NULL DEFAULT 0,
art_automatic TEXT,
art_manual TEXT,
filetype INTEGER NOT NULL DEFAULT 0,
playcount INTEGER NOT NULL DEFAULT 0,
lastplayed INTEGER,
rating INTEGER,
forced_compilation_on INTEGER NOT NULL DEFAULT 0,
forced_compilation_off INTEGER NOT NULL DEFAULT 0,
effective_compilation NOT NULL DEFAULT 0,
skipcount INTEGER NOT NULL DEFAULT 0,
score INTEGER NOT NULL DEFAULT 0,
beginning INTEGER NOT NULL DEFAULT 0,
cue_path TEXT,
unavailable INTEGER DEFAULT 0,
effective_albumartist TEXT,
etag TEXT
);
CREATE VIRTUAL TABLE skydrive_songs_fts USING fts3 (
ftstitle, ftsalbum, ftsartist, ftsalbumartist, ftscomposer, ftsgenre, ftscomment,
tokenize=unicode
);
UPDATE schema_version SET version=42;

View File

@ -110,7 +110,7 @@ TagLib::ByteVector CloudStream::readBlock(ulong length) {
}
QNetworkRequest request = QNetworkRequest(url_);
if (!auth_.isNull()) {
if (!auth_.isEmpty()) {
request.setRawHeader("Authorization", auth_.toUtf8());
}
request.setRawHeader(

View File

@ -37,7 +37,7 @@
#include <QVariant>
const char* Database::kDatabaseFilename = "clementine.db";
const int Database::kSchemaVersion = 41;
const int Database::kSchemaVersion = 42;
const char* Database::kMagicAllSongsTables = "%allsongstables";
int Database::sNextConnectionId = 1;

View File

@ -180,3 +180,18 @@ bool CloudFileService::IsSupportedMimeType(const QString& mime_type) const {
mime_type == "application/x-flac" ||
mime_type == "audio/x-ms-wma";
}
QString CloudFileService::GuessMimeTypeForFile(const QString& filename) const {
if (filename.endsWith(".mp3")) {
return "audio/mpeg";
} else if (filename.endsWith(".m4a")) {
return "audio/mpeg";
} else if (filename.endsWith(".ogg")) {
return "application/ogg";
} else if (filename.endsWith(".flac")) {
return "application/x-flac";
} else if (filename.endsWith(".wma")) {
return "audio/x-ms-wma";
}
return QString::null;
}

View File

@ -41,6 +41,7 @@ class CloudFileService : public InternetService {
const QUrl& download_url,
const QString& authorisation);
virtual bool IsSupportedMimeType(const QString& mime_type) const;
QString GuessMimeTypeForFile(const QString& filename) const;
protected slots:

View File

@ -1,5 +1,7 @@
#include "skydriveservice.h"
#include <qjson/parser.h>
#include "oauthenticator.h"
namespace {
@ -17,6 +19,9 @@ static const char* kOAuthTokenEndpoint =
"https://login.live.com/oauth20_token.srf";
static const char* kOAuthScope = "wl.basic wl.skydrive wl.offline_access";
static const char* kLiveUserInfo = "https://apis.live.net/v5.0/me";
static const char* kSkydriveBase = "https://apis.live.net/v5.0/";
} // namespace
SkydriveService::SkydriveService(
@ -51,11 +56,89 @@ void SkydriveService::Connect() {
}
void SkydriveService::ConnectFinished(OAuthenticator* oauth) {
qLog(Debug) << oauth->access_token()
<< oauth->refresh_token();
oauth->deleteLater();
QSettings s;
s.beginGroup(kSettingsGroup);
s.setValue("refresh_token", oauth->refresh_token());
access_token_ = oauth->access_token();
expiry_time_ = oauth->expiry_time();
QUrl url(kLiveUserInfo);
QNetworkRequest request(url);
AddAuthorizationHeader(&request);
QNetworkReply* reply = network_->get(request);
NewClosure(reply, SIGNAL(finished()),
this, SLOT(FetchUserInfoFinished(QNetworkReply*)), reply);
}
void SkydriveService::AddAuthorizationHeader(QNetworkRequest* request) {
request->setRawHeader(
"Authorization", QString("Bearer %1").arg(access_token_).toUtf8());
}
void SkydriveService::FetchUserInfoFinished(QNetworkReply* reply) {
reply->deleteLater();
QJson::Parser parser;
QVariantMap response = parser.parse(reply).toMap();
qLog(Debug) << response;
QString name = response["name"].toString();
if (!name.isEmpty()) {
QSettings s;
s.beginGroup(kSettingsGroup);
s.setValue("name", name);
}
ListFiles("me/skydrive");
}
void SkydriveService::ListFiles(const QString& folder) {
QUrl url(QString(kSkydriveBase) + folder + "/files");
url.addQueryItem("filter", "audio,folders");
QNetworkRequest request(url);
AddAuthorizationHeader(&request);
QNetworkReply* reply = network_->get(request);
NewClosure(reply, SIGNAL(finished()),
this, SLOT(ListFilesFinished(QNetworkReply*)), reply);
}
void SkydriveService::ListFilesFinished(QNetworkReply* reply) {
reply->deleteLater();
QJson::Parser parser;
QVariantMap response = parser.parse(reply).toMap();
qLog(Debug) << response;
QVariantList files = response["data"].toList();
foreach (const QVariant& f, files) {
QVariantMap file = f.toMap();
if (file["type"].toString() == "audio") {
QString mime_type = GuessMimeTypeForFile(file["name"].toString());
QUrl url;
url.setScheme("skydrive");
url.setPath(file["id"].toString());
Song song;
song.set_url(url);
song.set_ctime(file["created_time"].toDateTime().toTime_t());
song.set_mtime(file["updated_time"].toDateTime().toTime_t());
song.set_comment(file["description"].toString());
song.set_filesize(file["size"].toInt());
song.set_title(file["name"].toString());
QUrl download_url = file["source"].toUrl();
// HTTPS appears to be broken somehow between Qt & Skydrive downloads.
// Fortunately, just changing the scheme to HTTP works.
download_url.setScheme("http");
MaybeAddFileToDatabase(
song,
mime_type,
download_url,
QString::null);
}
}
}

View File

@ -3,7 +3,11 @@
#include "cloudfileservice.h"
#include <QDateTime>
class OAuthenticator;
class QNetworkRequest;
class QNetworkReply;
class SkydriveService : public CloudFileService {
Q_OBJECT
@ -20,7 +24,15 @@ class SkydriveService : public CloudFileService {
private slots:
void ConnectFinished(OAuthenticator* oauth);
void FetchUserInfoFinished(QNetworkReply* reply);
void ListFilesFinished(QNetworkReply* reply);
private:
void AddAuthorizationHeader(QNetworkRequest* request);
void ListFiles(const QString& folder);
QString access_token_;
QDateTime expiry_time_;
};
#endif // SKYDRIVESERVICE_H

View File

@ -128,25 +128,6 @@ void UbuntuOneService::RequestFileList(const QString& path) {
this, SLOT(FileListRequestFinished(QNetworkReply*)), files_reply);
}
namespace {
QString GuessMimeTypeForFile(const QString& filename) {
if (filename.endsWith(".mp3")) {
return "audio/mpeg";
} else if (filename.endsWith(".m4a")) {
return "audio/mpeg";
} else if (filename.endsWith(".ogg")) {
return "application/ogg";
} else if (filename.endsWith(".flac")) {
return "application/x-flac";
} else if (filename.endsWith(".wma")) {
return "audio/x-ms-wma";
}
return QString::null;
}
} // namespace
void UbuntuOneService::FileListRequestFinished(QNetworkReply* reply) {
reply->deleteLater();
QJson::Parser parser;