Refactor cloud tagging into base class.
This commit is contained in:
parent
951cac2ad6
commit
941aaca87c
|
@ -47,6 +47,7 @@ message SongMetadata {
|
|||
optional bool suspicious_tags = 27;
|
||||
optional string art_automatic = 28;
|
||||
optional Type type = 29;
|
||||
optional string etag = 30;
|
||||
}
|
||||
|
||||
message ReadFileRequest {
|
||||
|
|
|
@ -15,23 +15,10 @@
|
|||
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "mpris_common.h"
|
||||
#include "song.h"
|
||||
#include "timeconstants.h"
|
||||
#include "core/logging.h"
|
||||
#include "core/messagehandler.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#ifdef HAVE_LIBLASTFM
|
||||
#include "internet/fixlastfm.h"
|
||||
#ifdef HAVE_LIBLASTFM1
|
||||
#include <lastfm/Track.h>
|
||||
#else
|
||||
#include <lastfm/Track>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QLatin1Literal>
|
||||
|
@ -42,6 +29,15 @@
|
|||
#include <QVariant>
|
||||
#include <QtConcurrentRun>
|
||||
|
||||
#ifdef HAVE_LIBLASTFM
|
||||
#include "internet/fixlastfm.h"
|
||||
#ifdef HAVE_LIBLASTFM1
|
||||
#include <lastfm/Track.h>
|
||||
#else
|
||||
#include <lastfm/Track>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <id3v1genres.h>
|
||||
|
||||
#ifdef Q_OS_WIN32
|
||||
|
@ -57,14 +53,15 @@
|
|||
# include <libmtp.h>
|
||||
#endif
|
||||
|
||||
#include <boost/scoped_array.hpp>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
using boost::scoped_ptr;
|
||||
|
||||
#include "utilities.h"
|
||||
#include "core/logging.h"
|
||||
#include "core/messagehandler.h"
|
||||
#include "core/mpris_common.h"
|
||||
#include "core/timeconstants.h"
|
||||
#include "core/utilities.h"
|
||||
#include "covers/albumcoverloader.h"
|
||||
#include "engines/enginebase.h"
|
||||
#include "library/sqlrow.h"
|
||||
#include "tagreadermessages.pb.h"
|
||||
#include "widgets/trackslider.h"
|
||||
|
||||
|
||||
|
@ -409,6 +406,7 @@ void Song::InitFromProtobuf(const pb::tagreader::SongMetadata& pb) {
|
|||
d->filesize_ = pb.filesize();
|
||||
d->suspicious_tags_ = pb.suspicious_tags();
|
||||
d->filetype_ = static_cast<FileType>(pb.type());
|
||||
d->etag_ = QStringFromStdString(pb.etag());
|
||||
|
||||
if (pb.has_art_automatic()) {
|
||||
d->art_automatic_ = QStringFromStdString(pb.art_automatic());
|
||||
|
|
|
@ -25,9 +25,14 @@
|
|||
#include <QVariantMap>
|
||||
|
||||
#include "config.h"
|
||||
#include "tagreadermessages.pb.h"
|
||||
#include "engines/engine_fwd.h"
|
||||
|
||||
namespace pb {
|
||||
namespace tagreader {
|
||||
class SongMetadata;
|
||||
} // namespace tagreader
|
||||
} // namespace pb
|
||||
|
||||
class QSqlQuery;
|
||||
class QUrl;
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "core/mergedproxymodel.h"
|
||||
#include "core/network.h"
|
||||
#include "core/player.h"
|
||||
#include "core/taskmanager.h"
|
||||
#include "globalsearch/globalsearch.h"
|
||||
#include "globalsearch/librarysearchprovider.h"
|
||||
#include "internet/internetmodel.h"
|
||||
|
@ -28,6 +29,7 @@ CloudFileService::CloudFileService(
|
|||
network_(new NetworkAccessManager(this)),
|
||||
library_sort_model_(new QSortFilterProxyModel(this)),
|
||||
playlist_manager_(app->playlist_manager()),
|
||||
task_manager_(app->task_manager()),
|
||||
icon_(icon),
|
||||
settings_page_(settings_page) {
|
||||
library_backend_ = new LibraryBackend;
|
||||
|
@ -107,3 +109,73 @@ void CloudFileService::AddToPlaylist(QMimeData* mime) {
|
|||
void CloudFileService::ShowSettingsDialog() {
|
||||
app_->OpenSettingsDialogAtPage(settings_page_);
|
||||
}
|
||||
|
||||
bool CloudFileService::ShouldIndexFile(const QUrl& url, const QString& mime_type) const {
|
||||
if (!IsSupportedMimeType(mime_type)) {
|
||||
return false;
|
||||
}
|
||||
Song library_song = library_backend_->GetSongByUrl(url);
|
||||
if (library_song.is_valid()) {
|
||||
qLog(Debug) << "Already have:" << url;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CloudFileService::MaybeAddFileToDatabase(
|
||||
const Song& metadata,
|
||||
const QString& mime_type,
|
||||
const QUrl& download_url,
|
||||
const QString& authorisation) {
|
||||
if (!ShouldIndexFile(metadata.url(), mime_type)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const int task_id = task_manager_->StartTask(
|
||||
tr("Indexing %1").arg(metadata.title()));
|
||||
|
||||
TagReaderClient::ReplyType* reply = app_->tag_reader_client()->ReadCloudFile(
|
||||
download_url,
|
||||
metadata.title(),
|
||||
metadata.filesize(),
|
||||
mime_type,
|
||||
authorisation);
|
||||
NewClosure(reply, SIGNAL(Finished(bool)),
|
||||
this, SLOT(ReadTagsFinished(TagReaderClient::ReplyType*,Song,int)),
|
||||
reply, metadata, task_id);
|
||||
}
|
||||
|
||||
void CloudFileService::ReadTagsFinished(
|
||||
TagReaderClient::ReplyType* reply,
|
||||
const Song& metadata,
|
||||
const int task_id) {
|
||||
reply->deleteLater();
|
||||
TaskManager::ScopedTask(task_id, task_manager_);
|
||||
|
||||
const pb::tagreader::ReadCloudFileResponse& message =
|
||||
reply->message().read_cloud_file_response();
|
||||
if (!message.has_metadata() || !message.metadata().filesize()) {
|
||||
qLog(Debug) << "Failed to tag:" << metadata.url();
|
||||
return;
|
||||
}
|
||||
|
||||
pb::tagreader::SongMetadata metadata_pb;
|
||||
metadata.ToProtobuf(&metadata_pb);
|
||||
metadata_pb.MergeFrom(message.metadata());
|
||||
|
||||
Song song;
|
||||
song.InitFromProtobuf(metadata_pb);
|
||||
song.set_directory_id(0);
|
||||
|
||||
qLog(Debug) << "Adding song to db:" << song.title();
|
||||
library_backend_->AddOrUpdateSongs(SongList() << song);
|
||||
}
|
||||
|
||||
bool CloudFileService::IsSupportedMimeType(const QString& mime_type) const {
|
||||
return mime_type == "audio/ogg" ||
|
||||
mime_type == "audio/mpeg" ||
|
||||
mime_type == "audio/mp4" ||
|
||||
mime_type == "audio/flac" ||
|
||||
mime_type == "application/ogg" ||
|
||||
mime_type == "application/x-flac";
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include <QMenu>
|
||||
|
||||
#include "core/tagreaderclient.h"
|
||||
#include "ui/albumcovermanager.h"
|
||||
|
||||
class UrlHandler;
|
||||
|
@ -33,11 +34,23 @@ class CloudFileService : public InternetService {
|
|||
protected:
|
||||
virtual bool has_credentials() const = 0;
|
||||
virtual void Connect() = 0;
|
||||
virtual bool ShouldIndexFile(const QUrl& url, const QString& mime_type) const;
|
||||
virtual void MaybeAddFileToDatabase(
|
||||
const Song& metadata,
|
||||
const QString& mime_type,
|
||||
const QUrl& download_url,
|
||||
const QString& authorisation);
|
||||
virtual bool IsSupportedMimeType(const QString& mime_type) const;
|
||||
|
||||
|
||||
protected slots:
|
||||
void ShowCoverManager();
|
||||
void AddToPlaylist(QMimeData* mime);
|
||||
void ShowSettingsDialog();
|
||||
void ReadTagsFinished(
|
||||
TagReaderClient::ReplyType* reply,
|
||||
const Song& metadata,
|
||||
const int task_id);
|
||||
|
||||
protected:
|
||||
QStandardItem* root_;
|
||||
|
@ -50,6 +63,7 @@ class CloudFileService : public InternetService {
|
|||
boost::scoped_ptr<QMenu> context_menu_;
|
||||
boost::scoped_ptr<AlbumCoverManager> cover_manager_;
|
||||
PlaylistManager* playlist_manager_;
|
||||
TaskManager* task_manager_;
|
||||
|
||||
private:
|
||||
QIcon icon_;
|
||||
|
|
|
@ -96,17 +96,6 @@ void DropboxService::RequestFileList() {
|
|||
this, SLOT(RequestFileListFinished(QNetworkReply*)), reply);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
bool IsSupportedMimeType(const QString& mime_type) {
|
||||
return mime_type == "audio/ogg" ||
|
||||
mime_type == "audio/mpeg" ||
|
||||
mime_type == "audio/mp4" ||
|
||||
mime_type == "audio/flac";
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void DropboxService::RequestFileListFinished(QNetworkReply* reply) {
|
||||
reply->deleteLater();
|
||||
|
||||
|
@ -146,7 +135,13 @@ void DropboxService::RequestFileListFinished(QNetworkReply* reply) {
|
|||
if (metadata["is_dir"].toBool()) {
|
||||
continue;
|
||||
}
|
||||
MaybeAddFileToDatabase(url, metadata);
|
||||
|
||||
if (ShouldIndexFile(url, metadata["mime_type"].toString())) {
|
||||
QNetworkReply* reply = FetchContentUrl(url);
|
||||
NewClosure(reply, SIGNAL(finished()),
|
||||
this, SLOT(FetchContentUrlFinished(QNetworkReply*, QVariantMap)),
|
||||
reply, metadata);
|
||||
}
|
||||
}
|
||||
|
||||
if (response.contains("has_more") && response["has_more"].toBool()) {
|
||||
|
@ -154,22 +149,6 @@ void DropboxService::RequestFileListFinished(QNetworkReply* reply) {
|
|||
}
|
||||
}
|
||||
|
||||
void DropboxService::MaybeAddFileToDatabase(
|
||||
const QUrl& url, const QVariantMap& file) {
|
||||
if (!IsSupportedMimeType(file["mime_type"].toString())) {
|
||||
return;
|
||||
}
|
||||
Song song = library_backend_->GetSongByUrl(url);
|
||||
if (song.is_valid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QNetworkReply* reply = FetchContentUrl(url);
|
||||
NewClosure(reply, SIGNAL(finished()),
|
||||
this, SLOT(FetchContentUrlFinished(QNetworkReply*, QVariantMap)),
|
||||
reply, file);
|
||||
}
|
||||
|
||||
QNetworkReply* DropboxService::FetchContentUrl(const QUrl& url) {
|
||||
QUrl request_url(QString(kMediaEndpoint) + url.path());
|
||||
QNetworkRequest request(request_url);
|
||||
|
@ -183,44 +162,24 @@ void DropboxService::FetchContentUrlFinished(
|
|||
QJson::Parser parser;
|
||||
QVariantMap response = parser.parse(reply).toMap();
|
||||
QFileInfo info(data["path"].toString());
|
||||
TagReaderClient::ReplyType* tag_reply = app_->tag_reader_client()->ReadCloudFile(
|
||||
QUrl::fromEncoded(response["url"].toByteArray()),
|
||||
info.fileName(),
|
||||
data["bytes"].toInt(),
|
||||
data["mime_type"].toString(),
|
||||
QString::null);
|
||||
NewClosure(tag_reply, SIGNAL(Finished(bool)),
|
||||
this, SLOT(ReadTagsFinished(TagReaderClient::ReplyType*,QVariantMap)),
|
||||
tag_reply, data);
|
||||
}
|
||||
|
||||
void DropboxService::ReadTagsFinished(
|
||||
TagReaderClient::ReplyType* reply, const QVariantMap& file) {
|
||||
qLog(Debug) << reply->message().DebugString().c_str();
|
||||
|
||||
const auto& message = reply->message().read_cloud_file_response();
|
||||
if (!message.has_metadata() ||
|
||||
!message.metadata().filesize()) {
|
||||
qLog(Debug) << "Failed to tag:" << file["path"].toString();
|
||||
return;
|
||||
}
|
||||
|
||||
Song song;
|
||||
song.InitFromProtobuf(message.metadata());
|
||||
song.set_directory_id(0);
|
||||
song.set_etag(file["rev"].toString());
|
||||
song.set_mtime(ParseRFC822DateTime(file["modified"].toString()).toTime_t());
|
||||
QUrl url;
|
||||
url.setScheme("dropbox");
|
||||
url.setPath(file["path"].toString());
|
||||
song.set_url(url);
|
||||
if (song.title().isEmpty()) {
|
||||
QFileInfo info(file["path"].toString());
|
||||
song.set_title(info.fileName());
|
||||
}
|
||||
url.setPath(data["path"].toString());
|
||||
|
||||
qLog(Debug) << "Adding song to db:" << song.title();
|
||||
library_backend_->AddOrUpdateSongs(SongList() << song);
|
||||
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);
|
||||
}
|
||||
|
||||
QUrl DropboxService::GetStreamingUrlFromSongId(const QUrl& url) {
|
||||
|
|
|
@ -31,15 +31,11 @@ class DropboxService : public CloudFileService {
|
|||
private slots:
|
||||
void RequestFileListFinished(QNetworkReply* reply);
|
||||
void FetchContentUrlFinished(QNetworkReply* reply, const QVariantMap& file);
|
||||
void ReadTagsFinished(
|
||||
TagReaderClient::ReplyType* reply,
|
||||
const QVariantMap& file);
|
||||
|
||||
private:
|
||||
void RequestFileList();
|
||||
QByteArray GenerateAuthorisationHeader();
|
||||
QNetworkReply* FetchContentUrl(const QUrl& url);
|
||||
void MaybeAddFileToDatabase(const QUrl& url, const QVariantMap& file);
|
||||
|
||||
private:
|
||||
QString access_token_;
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
#include "core/database.h"
|
||||
#include "core/mergedproxymodel.h"
|
||||
#include "core/player.h"
|
||||
#include "core/taskmanager.h"
|
||||
#include "core/timeconstants.h"
|
||||
#include "ui/albumcovermanager.h"
|
||||
#include "globalsearch/globalsearch.h"
|
||||
|
@ -41,8 +40,7 @@ GoogleDriveService::GoogleDriveService(Application* app, InternetModel* parent)
|
|||
kServiceName, kServiceId,
|
||||
QIcon(":/providers/googledrive.png"),
|
||||
SettingsDialog::Page_GoogleDrive),
|
||||
client_(new google_drive::Client(this)),
|
||||
task_manager_(app->task_manager()) {
|
||||
client_(new google_drive::Client(this)) {
|
||||
app->player()->RegisterUrlHandler(new GoogleDriveUrlHandler(this, this));
|
||||
}
|
||||
|
||||
|
@ -124,7 +122,34 @@ void GoogleDriveService::EnsureConnected() {
|
|||
|
||||
void GoogleDriveService::FilesFound(const QList<google_drive::File>& files) {
|
||||
foreach (const google_drive::File& file, files) {
|
||||
MaybeAddFileToDatabase(file);
|
||||
if (!IsSupportedMimeType(file.mime_type())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
QUrl url;
|
||||
url.setScheme("googledrive");
|
||||
url.setPath(file.id());
|
||||
|
||||
Song song;
|
||||
// Add some extra tags from the Google Drive metadata.
|
||||
song.set_etag(file.etag().remove('"'));
|
||||
song.set_mtime(file.modified_date().toTime_t());
|
||||
song.set_ctime(file.created_date().toTime_t());
|
||||
song.set_comment(file.description());
|
||||
song.set_directory_id(0);
|
||||
song.set_url(QUrl(url));
|
||||
song.set_filesize(file.size());
|
||||
|
||||
// Use the Google Drive title if we couldn't read tags from the file.
|
||||
if (song.title().isEmpty()) {
|
||||
song.set_title(file.title());
|
||||
}
|
||||
|
||||
MaybeAddFileToDatabase(
|
||||
song,
|
||||
file.mime_type(),
|
||||
file.download_url(),
|
||||
QString("Bearer %1").arg(client_->access_token()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -138,84 +163,6 @@ void GoogleDriveService::FilesDeleted(const QList<QUrl>& files) {
|
|||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
bool IsSupportedMimeType(const QString& mime_type) {
|
||||
return mime_type == "audio/mpeg" ||
|
||||
mime_type == "application/ogg" ||
|
||||
mime_type == "application/x-flac";
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void GoogleDriveService::MaybeAddFileToDatabase(const google_drive::File& file) {
|
||||
QString url = QString("googledrive:%1").arg(file.id());
|
||||
Song song = library_backend_->GetSongByUrl(QUrl(url));
|
||||
// Song already in index.
|
||||
// TODO: Check etag and maybe update.
|
||||
if (song.is_valid()) {
|
||||
qLog(Debug) << "Already have:" << url;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsSupportedMimeType(file.mime_type())) {
|
||||
return;
|
||||
}
|
||||
|
||||
const int task_id = task_manager_->StartTask(
|
||||
tr("Indexing %1").arg(file.title()));
|
||||
|
||||
// Song not in index; tag and add.
|
||||
QString authorisation_header = QString("Bearer %1").arg(client_->access_token());
|
||||
TagReaderClient::ReplyType* reply = app_->tag_reader_client()->ReadCloudFile(
|
||||
file.download_url(),
|
||||
file.title(),
|
||||
file.size(),
|
||||
file.mime_type(),
|
||||
authorisation_header);
|
||||
|
||||
NewClosure(reply, SIGNAL(Finished(bool)),
|
||||
this, SLOT(ReadTagsFinished(TagReaderClient::ReplyType*,google_drive::File,QString,int)),
|
||||
reply, file, url, task_id);
|
||||
}
|
||||
|
||||
void GoogleDriveService::ReadTagsFinished(TagReaderClient::ReplyType* reply,
|
||||
const google_drive::File& metadata,
|
||||
const QString& url,
|
||||
const int task_id) {
|
||||
reply->deleteLater();
|
||||
|
||||
TaskManager::ScopedTask(task_id, task_manager_);
|
||||
|
||||
const pb::tagreader::ReadCloudFileResponse& msg =
|
||||
reply->message().read_cloud_file_response();
|
||||
if (!msg.has_metadata() || !msg.metadata().filesize()) {
|
||||
qLog(Debug) << "Failed to tag:" << metadata.title();
|
||||
return;
|
||||
}
|
||||
|
||||
// Read the Song metadata from the message.
|
||||
Song song;
|
||||
song.InitFromProtobuf(msg.metadata());
|
||||
|
||||
// Add some extra tags from the Google Drive metadata.
|
||||
song.set_etag(metadata.etag().remove('"'));
|
||||
song.set_mtime(metadata.modified_date().toTime_t());
|
||||
song.set_ctime(metadata.created_date().toTime_t());
|
||||
song.set_comment(metadata.description());
|
||||
song.set_directory_id(0);
|
||||
song.set_url(QUrl(url));
|
||||
|
||||
// Use the Google Drive title if we couldn't read tags from the file.
|
||||
if (song.title().isEmpty()) {
|
||||
song.set_title(metadata.title());
|
||||
}
|
||||
|
||||
// Add the song to the database
|
||||
qLog(Debug) << "Adding song to db:" << song.title();
|
||||
library_backend_->AddOrUpdateSongs(SongList() << song);
|
||||
}
|
||||
|
||||
QUrl GoogleDriveService::GetStreamingUrlFromSongId(const QString& id) {
|
||||
EnsureConnected();
|
||||
QScopedPointer<google_drive::GetFileResponse> response(client_->GetFile(id));
|
||||
|
|
|
@ -41,25 +41,16 @@ class GoogleDriveService : public CloudFileService {
|
|||
void FilesFound(const QList<google_drive::File>& files);
|
||||
void FilesDeleted(const QList<QUrl>& files);
|
||||
void ListChangesFinished(google_drive::ListChangesResponse* response);
|
||||
void ReadTagsFinished(TagReaderClient::ReplyType* reply,
|
||||
const google_drive::File& metadata,
|
||||
const QString& url,
|
||||
const int task_id);
|
||||
|
||||
void OpenWithDrive();
|
||||
|
||||
private:
|
||||
void EnsureConnected();
|
||||
void RefreshAuthorisation(const QString& refresh_token);
|
||||
void MaybeAddFileToDatabase(const google_drive::File& file);
|
||||
void ListChanges(const QString& cursor);
|
||||
|
||||
google_drive::Client* client_;
|
||||
|
||||
TaskManager* task_manager_;
|
||||
|
||||
int indexing_task_id_;
|
||||
|
||||
QAction* open_in_drive_action_;
|
||||
};
|
||||
|
||||
|
|
|
@ -128,22 +128,6 @@ void UbuntuOneService::RequestFileList(const QString& path) {
|
|||
this, SLOT(FileListRequestFinished(QNetworkReply*)), files_reply);
|
||||
}
|
||||
|
||||
void UbuntuOneService::FileListRequestFinished(QNetworkReply* reply) {
|
||||
reply->deleteLater();
|
||||
QJson::Parser parser;
|
||||
QVariantMap result = parser.parse(reply).toMap();
|
||||
|
||||
QVariantList children = result["children"].toList();
|
||||
foreach (const QVariant& c, children) {
|
||||
QVariantMap child = c.toMap();
|
||||
if (child["kind"].toString() == "file") {
|
||||
MaybeAddFileToDatabase(child);
|
||||
} else {
|
||||
RequestFileList(child["resource_path"].toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
QString GuessMimeTypeForFile(const QString& filename) {
|
||||
|
@ -161,69 +145,40 @@ QString GuessMimeTypeForFile(const QString& filename) {
|
|||
|
||||
} // namespace
|
||||
|
||||
void UbuntuOneService::MaybeAddFileToDatabase(const QVariantMap& file) {
|
||||
const QString content_path = file["content_path"].toString();
|
||||
const QString filename = file["path"].toString().mid(1);
|
||||
const QString mime_type = GuessMimeTypeForFile(filename);
|
||||
if (mime_type.isNull()) {
|
||||
// Unknown file type.
|
||||
// Potentially, we could do a HEAD request to see what Ubuntu One thinks
|
||||
// the Content-Type is, probably not worth it though.
|
||||
return;
|
||||
void UbuntuOneService::FileListRequestFinished(QNetworkReply* reply) {
|
||||
reply->deleteLater();
|
||||
QJson::Parser parser;
|
||||
QVariantMap result = parser.parse(reply).toMap();
|
||||
|
||||
QVariantList children = result["children"].toList();
|
||||
foreach (const QVariant& c, children) {
|
||||
QVariantMap child = c.toMap();
|
||||
if (child["kind"].toString() == "file") {
|
||||
QString content_path = child["content_path"].toString();
|
||||
QUrl content_url(kContentRoot);
|
||||
content_url.setPath(content_path);
|
||||
QUrl service_url;
|
||||
service_url.setScheme("ubuntuonefile");
|
||||
service_url.setPath(content_path);
|
||||
|
||||
Song metadata;
|
||||
metadata.set_url(service_url);
|
||||
metadata.set_etag(child["hash"].toString());
|
||||
metadata.set_mtime(QDateTime::fromString(
|
||||
child["when_changed"].toString(), Qt::ISODate).toTime_t());
|
||||
metadata.set_ctime(QDateTime::fromString(
|
||||
child["when_created"].toString(), Qt::ISODate).toTime_t());
|
||||
metadata.set_filesize(child["size"].toInt());
|
||||
metadata.set_title(child["path"].toString().mid(1));
|
||||
MaybeAddFileToDatabase(
|
||||
metadata,
|
||||
GuessMimeTypeForFile(child["path"].toString().mid(1)),
|
||||
content_url,
|
||||
GenerateAuthorisationHeader());
|
||||
} else {
|
||||
RequestFileList(child["resource_path"].toString());
|
||||
}
|
||||
}
|
||||
|
||||
QUrl service_url;
|
||||
service_url.setScheme("ubuntuonefile");
|
||||
service_url.setPath(content_path);
|
||||
Song song = library_backend_->GetSongByUrl(service_url);
|
||||
if (song.is_valid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QUrl content_url(kContentRoot);
|
||||
content_url.setPath(content_path);
|
||||
|
||||
TagReaderClient::ReplyType* reply = app_->tag_reader_client()->ReadCloudFile(
|
||||
content_url,
|
||||
filename,
|
||||
file["size"].toInt(),
|
||||
mime_type,
|
||||
GenerateAuthorisationHeader());
|
||||
NewClosure(
|
||||
reply, SIGNAL(Finished(bool)),
|
||||
this, SLOT(ReadTagsFinished(TagReaderClient::ReplyType*,QVariantMap, QUrl)),
|
||||
reply, file, service_url);
|
||||
}
|
||||
|
||||
void UbuntuOneService::ReadTagsFinished(
|
||||
TagReaderClient::ReplyType* reply, const QVariantMap& file, const QUrl& url) {
|
||||
qLog(Debug) << reply->message().DebugString().c_str();
|
||||
|
||||
const auto& message = reply->message().read_cloud_file_response();
|
||||
|
||||
if (!message.has_metadata() ||
|
||||
!message.metadata().filesize()) {
|
||||
qLog(Debug) << "Failed to tag:" << url;
|
||||
return;
|
||||
}
|
||||
|
||||
Song song;
|
||||
song.InitFromProtobuf(reply->message().read_cloud_file_response().metadata());
|
||||
song.set_directory_id(0);
|
||||
song.set_etag(file["hash"].toString());
|
||||
song.set_mtime(
|
||||
QDateTime::fromString(file["when_changed"].toString(), Qt::ISODate).toTime_t());
|
||||
song.set_ctime(
|
||||
QDateTime::fromString(file["when_created"].toString(), Qt::ISODate).toTime_t());
|
||||
|
||||
song.set_url(url);
|
||||
|
||||
if (song.title().isEmpty()) {
|
||||
song.set_title(file["path"].toString().mid(1));
|
||||
}
|
||||
|
||||
qLog(Debug) << "Adding song to db:" << song.title();
|
||||
library_backend_->AddOrUpdateSongs(SongList() << song);
|
||||
}
|
||||
|
||||
QUrl UbuntuOneService::GetStreamingUrlFromSongId(const QString& song_id) {
|
||||
|
|
|
@ -21,8 +21,6 @@ class UbuntuOneService : public CloudFileService {
|
|||
private slots:
|
||||
void AuthenticationFinished(UbuntuOneAuthenticator* authenticator);
|
||||
void FileListRequestFinished(QNetworkReply* reply);
|
||||
void ReadTagsFinished(
|
||||
TagReaderClient::ReplyType* reply, const QVariantMap& file, const QUrl& url);
|
||||
void ShowCoverManager();
|
||||
void AddToPlaylist(QMimeData* mime);
|
||||
void VolumeListRequestFinished(QNetworkReply* reply);
|
||||
|
@ -32,7 +30,6 @@ class UbuntuOneService : public CloudFileService {
|
|||
QNetworkReply* SendRequest(const QUrl& url);
|
||||
void RequestVolumeList();
|
||||
void RequestFileList(const QString& path);
|
||||
void MaybeAddFileToDatabase(const QVariantMap& file);
|
||||
bool has_credentials() const;
|
||||
|
||||
private:
|
||||
|
|
Loading…
Reference in New Issue