diff --git a/data/schema/schema-45.sql b/data/schema/schema-45.sql index 7761d541a..8890f7e1f 100644 --- a/data/schema/schema-45.sql +++ b/data/schema/schema-45.sql @@ -1,48 +1,23 @@ -CREATE TABLE seafile_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 seafile_songs_fts USING fts3 ( +CREATE VIRTUAL TABLE playlist_items_fts USING fts3( ftstitle, ftsalbum, ftsartist, ftsalbumartist, ftscomposer, ftsgenre, ftscomment, tokenize=unicode ); +DELETE FROM %allsongstables_fts; + +DROP TABLE %allsongstables_fts; + +ALTER TABLE %allsongstables ADD COLUMN performer TEXT; + +ALTER TABLE %allsongstables ADD COLUMN grouping TEXT; + +CREATE VIRTUAL TABLE %allsongstables_fts USING fts3( + ftstitle, ftsalbum, ftsartist, ftsalbumartist, ftscomposer, ftsperformer, ftsgrouping, ftsgenre, ftscomment, + tokenize=unicode +); + +INSERT INTO %allsongstables_fts (ROWID, ftstitle, ftsalbum, ftsartist, ftsalbumartist, ftscomposer, ftsperformer, ftsgrouping, ftsgenre, ftscomment) + SELECT ROWID, title, album, artist, albumartist, composer, performer, grouping, genre, comment + FROM %allsongstables; + UPDATE schema_version SET version=45; diff --git a/data/schema/schema-46.sql b/data/schema/schema-46.sql index 9e2438e97..2f43e6c7f 100644 --- a/data/schema/schema-46.sql +++ b/data/schema/schema-46.sql @@ -1,24 +1,3 @@ -CREATE VIRTUAL TABLE playlist_items_fts USING fts3( - ftstitle, ftsalbum, ftsartist, ftsalbumartist, ftscomposer, ftsgenre, ftscomment, - tokenize=unicode -); - -DELETE FROM %allsongstables_fts; - -DROP TABLE %allsongstables_fts; - -ALTER TABLE %allsongstables ADD COLUMN performer TEXT; - -ALTER TABLE %allsongstables ADD COLUMN grouping TEXT; - -CREATE VIRTUAL TABLE %allsongstables_fts USING fts3( - ftstitle, ftsalbum, ftsartist, ftsalbumartist, ftscomposer, ftsperformer, ftsgrouping, ftsgenre, ftscomment, - tokenize=unicode -); - -INSERT INTO %allsongstables_fts (ROWID, ftstitle, ftsalbum, ftsartist, ftsalbumartist, ftscomposer, ftsperformer, ftsgrouping, ftsgenre, ftscomment) - SELECT ROWID, title, album, artist, albumartist, composer, performer, grouping, genre, comment - FROM %allsongstables; +ALTER TABLE playlists ADD COLUMN is_favorite INTEGER NOT NULL DEFAULT 0; UPDATE schema_version SET version=46; - diff --git a/data/schema/schema-47.sql b/data/schema/schema-47.sql index bef6399f8..ba8bb8d07 100644 --- a/data/schema/schema-47.sql +++ b/data/schema/schema-47.sql @@ -1,3 +1,50 @@ -ALTER TABLE playlists ADD COLUMN is_favorite INTEGER NOT NULL DEFAULT 0; +CREATE TABLE seafile_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, + performer TEXT, + grouping TEXT +); + +CREATE VIRTUAL TABLE seafile_songs_fts USING fts3 ( + ftstitle, ftsalbum, ftsartist, ftsalbumartist, ftscomposer, ftsperformer, ftsgrouping, ftsgenre, ftscomment, + tokenize=unicode +); UPDATE schema_version SET version=47; diff --git a/src/config.h.in b/src/config.h.in index 53758a319..5a4767762 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -36,11 +36,11 @@ #cmakedefine HAVE_LIBPULSE #cmakedefine HAVE_MOODBAR #cmakedefine HAVE_QCA +#cmakedefine HAVE_SEAFILE #cmakedefine HAVE_SKYDRIVE #cmakedefine HAVE_SPARKLE #cmakedefine HAVE_SPOTIFY_DOWNLOADER #cmakedefine HAVE_VK -#cmakedefine HAVE_SEAFILE #cmakedefine HAVE_WIIMOTEDEV #cmakedefine TAGLIB_HAS_OPUS #cmakedefine USE_INSTALL_PREFIX diff --git a/src/internet/internetmodel.cpp b/src/internet/internetmodel.cpp index 89befe529..64adb07c2 100644 --- a/src/internet/internetmodel.cpp +++ b/src/internet/internetmodel.cpp @@ -57,7 +57,6 @@ #include "seafileservice.h" #endif - using smart_playlists::Generator; using smart_playlists::GeneratorMimeData; using smart_playlists::GeneratorPtr; @@ -99,15 +98,15 @@ InternetModel::InternetModel(Application* app, QObject* parent) #ifdef HAVE_GOOGLE_DRIVE AddService(new GoogleDriveService(app, this)); #endif +#ifdef HAVE_SEAFILE + AddService(new SeafileService(app, this)); +#endif #ifdef HAVE_SKYDRIVE AddService(new SkydriveService(app, this)); #endif #ifdef HAVE_VK AddService(new VkService(app, this)); #endif -#ifdef HAVE_SEAFILE - AddService(new SeafileService(app, this)); -#endif invisibleRootItem()->sortChildren(0, Qt::AscendingOrder); } @@ -230,8 +229,9 @@ QStringList InternetModel::mimeTypes() const { QMimeData* InternetModel::mimeData(const QModelIndexList& indexes) const { // Special case for when the user double clicked on a special item. - if (indexes.count() == 1 && indexes[0].data(Role_PlayBehaviour).toInt() == - PlayBehaviour_DoubleClickAction) { + if (indexes.count() == 1 && + indexes[0].data(Role_PlayBehaviour).toInt() == + PlayBehaviour_DoubleClickAction) { InternetModel::ServiceForIndex(indexes[0]) ->ItemDoubleClicked(itemFromIndex(indexes[0])); return nullptr; diff --git a/src/internet/seafileservice.cpp b/src/internet/seafileservice.cpp index fa8c306e1..29dcdbd3c 100644 --- a/src/internet/seafileservice.cpp +++ b/src/internet/seafileservice.cpp @@ -10,25 +10,24 @@ #include "library/librarybackend.h" #include "internet/oauthenticator.h" - const char* SeafileService::kServiceName = "Seafile"; const char* SeafileService::kSettingsGroup = "Seafile"; namespace { -static const char* kAuthToken = "/api2/auth-token/"; +static const char* kAuthTokenUrl = "/api2/auth-token/"; -static const char* kFolderItems = "/api2/repos/%1/dir/"; -static const char* kListRepos = "/api2/repos/"; +static const char* kFolderItemsUrl = "/api2/repos/%1/dir/"; +static const char* kListReposUrl = "/api2/repos/"; static const char* kFileUrl = "/api2/repos/%1/file/"; -static const char* kFileContent = "/api2/repos/%1/file/detail/"; +static const char* kFileContentUrl = "/api2/repos/%1/file/detail/"; } SeafileService::SeafileService(Application* app, InternetModel* parent) - : CloudFileService(app, parent, kServiceName, kSettingsGroup, - QIcon(":/providers/seafile.png"), SettingsDialog::Page_Seafile) { - + : CloudFileService(app, parent, kServiceName, kSettingsGroup, + QIcon(":/providers/seafile.png"), + SettingsDialog::Page_Seafile) { QSettings s; s.beginGroup(kSettingsGroup); access_token_ = s.value("access_token").toString(); @@ -36,19 +35,19 @@ SeafileService::SeafileService(Application* app, InternetModel* parent) QByteArray tree_bytes = s.value("tree").toByteArray(); - if(!tree_bytes.isEmpty()) { + if (!tree_bytes.isEmpty()) { QDataStream stream(&tree_bytes, QIODevice::ReadOnly); stream >> tree_; } app->player()->RegisterUrlHandler(new SeafileUrlHandler(this, this)); - connect(&tree_, SIGNAL(ToAdd(QString, QString, SeafileTree::Entry)), this, SLOT(AddEntry(QString, QString, SeafileTree::Entry))); - connect(&tree_, SIGNAL(ToDelete(QString, QString, SeafileTree::Entry)), this, SLOT(DeleteEntry(QString, QString, SeafileTree::Entry))); - connect(&tree_, SIGNAL(ToUpdate(QString, QString, SeafileTree::Entry)), this, SLOT(UpdateEntry(QString, QString, SeafileTree::Entry))); - - library_updated_ = QString::null; - + connect(&tree_, SIGNAL(ToAdd(QString, QString, SeafileTree::Entry)), this, + SLOT(AddEntry(QString, QString, SeafileTree::Entry))); + connect(&tree_, SIGNAL(ToDelete(QString, QString, SeafileTree::Entry)), this, + SLOT(DeleteEntry(QString, QString, SeafileTree::Entry))); + connect(&tree_, SIGNAL(ToUpdate(QString, QString, SeafileTree::Entry)), this, + SLOT(UpdateEntry(QString, QString, SeafileTree::Entry))); } bool SeafileService::has_credentials() const { @@ -67,7 +66,8 @@ QString SeafileService::access_token() const { } void SeafileService::AddAuthorizationHeader(QNetworkRequest* request) const { - request->setRawHeader("Authorization", QString(QString("Token ") + QString(access_token_)).toAscii()); + request->setRawHeader("Authorization", + QString("Token %1").arg(access_token_).toAscii()); } void SeafileService::ForgetCredentials() { @@ -82,8 +82,9 @@ void SeafileService::ForgetCredentials() { server_.clear(); } -bool SeafileService::GetToken(const QString &mail, const QString &password, const QString &server) { - QUrl url(server + kAuthToken); +bool SeafileService::GetToken(const QString& mail, const QString& password, + const QString& server) { + QUrl url(server + kAuthTokenUrl); QNetworkRequest request(url); AddAuthorizationHeader(&request); @@ -91,10 +92,9 @@ bool SeafileService::GetToken(const QString &mail, const QString &password, cons url.addQueryItem("password", password); QNetworkReply* reply = network_->post(request, url.encodedQuery()); - reply->ignoreSslErrors(); WaitForSignal(reply, SIGNAL(finished())); - if(!CheckReply(&reply)) { + if (!CheckReply(&reply)) { qLog(Warning) << "Something wrong with the reply... (GetToken)"; return false; } @@ -107,7 +107,7 @@ bool SeafileService::GetToken(const QString &mail, const QString &password, cons // Because the server responds "token" access_token_ = response["token"].toString().replace("\"", ""); - if(access_token_.isEmpty()) { + if (access_token_.isEmpty()) { return false; } @@ -122,19 +122,18 @@ bool SeafileService::GetToken(const QString &mail, const QString &password, cons return true; } - void SeafileService::GetLibraries() { - QUrl url(server_ + kListRepos); + QUrl url(server_ + kListReposUrl); QNetworkRequest request(url); AddAuthorizationHeader(&request); - QNetworkReply *reply = network_->get(request); - reply->ignoreSslErrors(); + QNetworkReply* reply = network_->get(request); - NewClosure(reply, SIGNAL(finished()), this, SLOT(GetLibrariesFinished(QNetworkReply*)), reply); + NewClosure(reply, SIGNAL(finished()), this, + SLOT(GetLibrariesFinished(QNetworkReply*)), reply); } -void SeafileService::GetLibrariesFinished(QNetworkReply *reply) { - if(!CheckReply(&reply)) { +void SeafileService::GetLibrariesFinished(QNetworkReply* reply) { + if (!CheckReply(&reply)) { qLog(Warning) << "Something wrong with the reply... (GetLibraries)"; return; } @@ -147,13 +146,14 @@ void SeafileService::GetLibrariesFinished(QNetworkReply *reply) { QJson::Parser parser; QList repos = parser.parse(data).toList(); - for (int i=0; ientry().id()) { DeleteEntry(library->entry().id(), "/", library->entry()); } } } - UpdateLibraries(); } void SeafileService::Connect() { if (is_authenticated()) { UpdateLibraries(); - } - else { + } else { ShowSettingsDialog(); } } void SeafileService::UpdateLibraries() { - - connect(this, SIGNAL(GetLibrariesFinishedSignal(QMap)), this, - SLOT(UpdateLibrariesInProgress(QMap))); + connect(this, SIGNAL(GetLibrariesFinishedSignal(QMap)), + this, SLOT(UpdateLibrariesInProgress(QMap))); GetLibraries(); } -void SeafileService::UpdateLibrariesInProgress(const QMap &libraries) { - disconnect(this, SIGNAL(GetLibrariesFinishedSignal(QMap)), this, - SLOT(UpdateLibrariesInProgress(QMap))); +void SeafileService::UpdateLibrariesInProgress( + const QMap& libraries) { + disconnect(this, SIGNAL(GetLibrariesFinishedSignal(QMap)), + this, SLOT(UpdateLibrariesInProgress(QMap))); QSettings s; s.beginGroup(kSettingsGroup); @@ -210,7 +205,7 @@ void SeafileService::UpdateLibrariesInProgress(const QMap &lib library_updated_ = library_to_update; - if(library_to_update == "none") { + if (library_to_update == "none") { return; } @@ -220,43 +215,49 @@ void SeafileService::UpdateLibrariesInProgress(const QMap &lib // Need to check this library ? if (library_to_update == "all" || library.key() == library_to_update) { - FetchAndCheckFolderItems( - SeafileTree::Entry(library.value(), library.key(), SeafileTree::Entry::LIBRARY), "/"); + SeafileTree::Entry(library.value(), library.key(), + SeafileTree::Entry::LIBRARY), + "/"); } // If not, we can destroy the library from the tree else { - // If the library was not in the tree, it's not a problem because DeleteEntry won't do anything + // If the library was not in the tree, it's not a problem because + // DeleteEntry won't do anything DeleteEntry(library.key(), "/", - SeafileTree::Entry(library.value(), library.key(), SeafileTree::Entry::LIBRARY)); + SeafileTree::Entry(library.value(), library.key(), + SeafileTree::Entry::LIBRARY)); } } - } -QNetworkReply* SeafileService::PrepareFetchFolderItems(const QString &library, const QString &path) { - QUrl url(server_ + QString(kFolderItems).arg(library)); +QNetworkReply* SeafileService::PrepareFetchFolderItems(const QString& library, + const QString& path) { + QUrl url(server_ + QString(kFolderItemsUrl).arg(library)); url.addQueryItem("p", path); QNetworkRequest request(url); AddAuthorizationHeader(&request); QNetworkReply* reply = network_->get(request); - reply->ignoreSslErrors(); return reply; } -void SeafileService::FetchAndCheckFolderItems(const SeafileTree::Entry &library, const QString &path) { - QNetworkReply *reply = PrepareFetchFolderItems(library.id(), path); +void SeafileService::FetchAndCheckFolderItems(const SeafileTree::Entry& library, + const QString& path) { + QNetworkReply* reply = PrepareFetchFolderItems(library.id(), path); NewClosure(reply, SIGNAL(finished()), this, - SLOT(FetchAndCheckFolderItemsFinished(QNetworkReply*,SeafileTree::Entry,QString)), + SLOT(FetchAndCheckFolderItemsFinished( + QNetworkReply*, SeafileTree::Entry, QString)), reply, library, path); } void SeafileService::FetchAndCheckFolderItemsFinished( - QNetworkReply *reply, const SeafileTree::Entry &library, const QString &path) { - if(!CheckReply(&reply)) { - qLog(Warning) << "Something wrong with the reply... (FetchFolderItemsToList)"; + QNetworkReply* reply, const SeafileTree::Entry& library, + const QString& path) { + if (!CheckReply(&reply)) { + qLog(Warning) + << "Something wrong with the reply... (FetchFolderItemsToList)"; return; } @@ -268,33 +269,40 @@ void SeafileService::FetchAndCheckFolderItemsFinished( QList variant_entries = parser.parse(data).toList(); SeafileTree::Entries entries; - for (const QVariant & e: variant_entries) { + for (const QVariant& e : variant_entries) { QVariantMap entry = e.toMap(); - SeafileTree::Entry::Type entry_type = SeafileTree::Entry::StringToType(entry["type"].toString()); + SeafileTree::Entry::Type entry_type = + SeafileTree::Entry::StringToType(entry["type"].toString()); QString entry_name = entry["name"].toString(); // We just want libraries/directories and files which could be songs. if (entry_type == SeafileTree::Entry::NONE) { qLog(Warning) << "Type entry unknown for this entry"; - } - else if (entry_type == SeafileTree::Entry::FILE && GuessMimeTypeForFile(entry_name).isNull()) { + } else if (entry_type == SeafileTree::Entry::FILE && + GuessMimeTypeForFile(entry_name).isNull()) { continue; } - entries.append(SeafileTree::Entry(entry_name, entry["id"].toString(), entry_type)); + entries.append( + SeafileTree::Entry(entry_name, entry["id"].toString(), entry_type)); } tree_.CheckEntries(entries, library, path); } - -void SeafileService::AddRecursivelyFolderItems(const QString &library, const QString &path) { - QNetworkReply *reply = PrepareFetchFolderItems(library, path); - NewClosure(reply, SIGNAL(finished()), this, SLOT(AddRecursivelyFolderItemsFinished(QNetworkReply*,QString,QString)), reply, library, path); +void SeafileService::AddRecursivelyFolderItems(const QString& library, + const QString& path) { + QNetworkReply* reply = PrepareFetchFolderItems(library, path); + NewClosure( + reply, SIGNAL(finished()), this, + SLOT(AddRecursivelyFolderItemsFinished(QNetworkReply*, QString, QString)), + reply, library, path); } -void SeafileService::AddRecursivelyFolderItemsFinished(QNetworkReply* reply, const QString &library, const QString &path) { - if(!CheckReply(&reply)) { +void SeafileService::AddRecursivelyFolderItemsFinished(QNetworkReply* reply, + const QString& library, + const QString& path) { + if (!CheckReply(&reply)) { qLog(Warning) << "Something wrong with the reply... (FetchFolderItems)"; return; } @@ -307,36 +315,39 @@ void SeafileService::AddRecursivelyFolderItemsFinished(QNetworkReply* reply, con for (const QVariant& e : entries) { QVariantMap entry_map = e.toMap(); - SeafileTree::Entry::Type entry_type = SeafileTree::Entry::StringToType(entry_map["type"].toString()); + SeafileTree::Entry::Type entry_type = + SeafileTree::Entry::StringToType(entry_map["type"].toString()); QString entry_name = entry_map["name"].toString(); // We just want libraries/directories and files which could be songs. if (entry_type == SeafileTree::Entry::NONE) { qLog(Warning) << "Type entry unknown for this entry"; - } - else if (entry_type == SeafileTree::Entry::FILE && GuessMimeTypeForFile(entry_name).isNull()) { + } else if (entry_type == SeafileTree::Entry::FILE && + GuessMimeTypeForFile(entry_name).isNull()) { continue; } - SeafileTree::Entry entry(entry_name, entry_map["id"].toString(), entry_type); + SeafileTree::Entry entry(entry_name, entry_map["id"].toString(), + entry_type); // If AddEntry was not successful we stop - // It could happen when the user changes the library to update while an update was in progress - if(!tree_.AddEntry(library, path, entry)) { + // It could happen when the user changes the library to update while an + // update was in progress + if (!tree_.AddEntry(library, path, entry)) { return; } if (entry.is_dir()) { AddRecursivelyFolderItems(library, path + entry.name() + "/"); - } - else { + } else { MaybeAddFileEntry(entry.name(), library, path); } } } -QNetworkReply *SeafileService::PrepareFetchContentForFile(const QString &library, const QString &filepath) { - QUrl content_url(server_ + QString(kFileContent).arg(library)); +QNetworkReply* SeafileService::PrepareFetchContentForFile( + const QString& library, const QString& filepath) { + QUrl content_url(server_ + QString(kFileContentUrl).arg(library)); content_url.addQueryItem("p", filepath); QNetworkRequest request(content_url); @@ -346,24 +357,26 @@ QNetworkReply *SeafileService::PrepareFetchContentForFile(const QString &library return reply; } - -void SeafileService::MaybeAddFileEntry(const QString &entry_name, const QString &library, const QString &path) { +void SeafileService::MaybeAddFileEntry(const QString& entry_name, + const QString& library, + const QString& path) { QString mime_type = GuessMimeTypeForFile(entry_name); - if(mime_type.isNull()) - return; + if (mime_type.isNull()) return; // Get the details of the entry - QNetworkReply *reply = PrepareFetchContentForFile(library, path + entry_name); + QNetworkReply* reply = PrepareFetchContentForFile(library, path + entry_name); NewClosure(reply, SIGNAL(finished()), this, - SLOT(MaybeAddFileEntryInProgress(QNetworkReply*,QString,QString,QString)), + SLOT(MaybeAddFileEntryInProgress(QNetworkReply*, QString, QString, + QString)), reply, library, path, mime_type); } -void SeafileService::MaybeAddFileEntryInProgress( - QNetworkReply *reply, const QString &library, const QString &path, const QString &mime_type) { - - if(!CheckReply(&reply)) { +void SeafileService::MaybeAddFileEntryInProgress(QNetworkReply* reply, + const QString& library, + const QString& path, + const QString& mime_type) { + if (!CheckReply(&reply)) { qLog(Warning) << "Something wrong with the reply... (MaybeAddFileEntry)"; return; } @@ -387,12 +400,16 @@ void SeafileService::MaybeAddFileEntryInProgress( song.set_title(entry_detail_map["name"].toString()); // Get the download url of the entry - reply = PrepareFetchContentUrlForFile(library, path + entry_detail_map["name"].toString()); - NewClosure(reply, SIGNAL(finished()), this, SLOT(FetchContentUrlForFileFinished(QNetworkReply*, Song, QString)), reply, song, mime_type); + reply = PrepareFetchContentUrlForFile( + library, path + entry_detail_map["name"].toString()); + NewClosure( + reply, SIGNAL(finished()), this, + SLOT(FetchContentUrlForFileFinished(QNetworkReply*, Song, QString)), + reply, song, mime_type); } - -QNetworkReply* SeafileService::PrepareFetchContentUrlForFile(const QString &library, const QString &filepath) { +QNetworkReply* SeafileService::PrepareFetchContentUrlForFile( + const QString& library, const QString& filepath) { QUrl content_url(server_ + QString(kFileUrl).arg(library)); content_url.addQueryItem("p", filepath); @@ -403,10 +420,12 @@ QNetworkReply* SeafileService::PrepareFetchContentUrlForFile(const QString &libr return reply; } -void SeafileService::FetchContentUrlForFileFinished(QNetworkReply* reply, const Song &song, const QString &mime_type) { - - if(!CheckReply(&reply)) { - qLog(Warning) << "Something wrong with the reply... (FetchContentUrlForFile)"; +void SeafileService::FetchContentUrlForFileFinished(QNetworkReply* reply, + const Song& song, + const QString& mime_type) { + if (!CheckReply(&reply)) { + qLog(Warning) + << "Something wrong with the reply... (FetchContentUrlForFile)"; return; } @@ -415,17 +434,18 @@ void SeafileService::FetchContentUrlForFileFinished(QNetworkReply* reply, const // Because server response is "http://..." QString real_url = QString(reply->readAll()).replace("\"", ""); - MaybeAddFileToDatabase(song, mime_type, QUrl(real_url), QString("Token %1").arg(access_token_)); + MaybeAddFileToDatabase(song, mime_type, QUrl(real_url), + QString("Token %1").arg(access_token_)); } -QUrl SeafileService::GetStreamingUrlFromSongId(const QString &library, const QString &filepath) { - +QUrl SeafileService::GetStreamingUrlFromSongId(const QString& library, + const QString& filepath) { QNetworkReply* reply = PrepareFetchContentUrlForFile(library, filepath); - reply->ignoreSslErrors(); WaitForSignal(reply, SIGNAL(finished())); - if(!CheckReply(&reply)) { - qLog(Warning) << "Something wrong with the reply... (GetStreamingUrlFromSongId)"; + if (!CheckReply(&reply)) { + qLog(Warning) + << "Something wrong with the reply... (GetStreamingUrlFromSongId)"; return QUrl(""); } reply->deleteLater(); @@ -435,115 +455,120 @@ QUrl SeafileService::GetStreamingUrlFromSongId(const QString &library, const QSt return QUrl(response); } - -void SeafileService::AddEntry(const QString &library, const QString &path, const SeafileTree::Entry &entry) { - +void SeafileService::AddEntry(const QString& library, const QString& path, + const SeafileTree::Entry& entry) { if (entry.is_library()) { tree_.AddLibrary(entry.name(), entry.id()); AddRecursivelyFolderItems(library, "/"); - } - else { + } else { // If AddEntry was not successful we stop - // It could happen when the user changes the library to update while an update was in progress - if(!tree_.AddEntry(library, path, entry)) { + // It could happen when the user changes the library to update while an + // update was in progress + if (!tree_.AddEntry(library, path, entry)) { return; } if (entry.is_file()) { MaybeAddFileEntry(entry.name(), library, path); - } - else { - AddRecursivelyFolderItems(library, path + entry.name() + "/"); + } else { + AddRecursivelyFolderItems(library, path + entry.name() + "/"); } } } -void SeafileService::UpdateEntry(const QString & library, const QString &path, const SeafileTree::Entry &entry) { - +void SeafileService::UpdateEntry(const QString& library, const QString& path, + const SeafileTree::Entry& entry) { if (entry.is_file()) { DeleteEntry(library, path, entry); AddEntry(library, path, entry); - } - else { + } else { QString entry_path = path; - if(entry.is_dir()) { + if (entry.is_dir()) { entry_path += entry.name() + "/"; } - FetchAndCheckFolderItems(SeafileTree::Entry("", library, SeafileTree::Entry::LIBRARY), - entry_path); + FetchAndCheckFolderItems( + SeafileTree::Entry("", library, SeafileTree::Entry::LIBRARY), + entry_path); } } -void SeafileService::DeleteEntry(const QString &library, const QString &path, const SeafileTree::Entry &entry) { - +void SeafileService::DeleteEntry(const QString& library, const QString& path, + const SeafileTree::Entry& entry) { // For the QPair -> 1 : path, 2 : entry QList> files_to_delete; - if(entry.is_library()) { - SeafileTree::TreeItem *item = tree_.FindLibrary(library); + if (entry.is_library()) { + SeafileTree::TreeItem* item = tree_.FindLibrary(library); files_to_delete = tree_.GetRecursiveFilesOfDir("/", item); tree_.DeleteLibrary(library); - } - else { - if(entry.is_dir()) { - SeafileTree::TreeItem *item = tree_.FindFromAbsolutePath(library, path + entry.name() + "/"); - files_to_delete = tree_.GetRecursiveFilesOfDir(path + entry.name() + "/", item); - } - else { + } else { + if (entry.is_dir()) { + SeafileTree::TreeItem* item = + tree_.FindFromAbsolutePath(library, path + entry.name() + "/"); + files_to_delete = + tree_.GetRecursiveFilesOfDir(path + entry.name() + "/", item); + } else { files_to_delete.append(qMakePair(path, entry)); } - if(!tree_.DeleteEntry(library, path, entry)) { + if (!tree_.DeleteEntry(library, path, entry)) { return; } } // Delete songs from the library of Clementine - for (const QPair &file_to_delete : files_to_delete) { - if(!GuessMimeTypeForFile(file_to_delete.second.name()) - .isEmpty()) { - QUrl song_url("seafile:/" + library + file_to_delete.first + file_to_delete.second.name()); + for (const QPair& file_to_delete : + files_to_delete) { + if (!GuessMimeTypeForFile(file_to_delete.second.name()).isEmpty()) { + QUrl song_url("seafile:/" + library + file_to_delete.first + + file_to_delete.second.name()); Song song = library_backend_->GetSongByUrl(song_url); if (song.is_valid()) { library_backend_->DeleteSongs(SongList() << song); - } - else { - qLog(Warning) << "Can't delete song from the Clementine's library : " << song_url; + } else { + qLog(Warning) << "Can't delete song from the Clementine's library : " + << song_url; } } } } - -bool SeafileService::CheckReply(QNetworkReply **reply) { - if (!(*reply)) { +bool SeafileService::CheckReply(QNetworkReply** reply, int tries) { + if (!(*reply) || tries > 10) { return false; } - QVariant status_code_variant = (*reply)->attribute(QNetworkRequest::HttpStatusCodeAttribute); + QVariant status_code_variant = + (*reply)->attribute(QNetworkRequest::HttpStatusCodeAttribute); if (status_code_variant.isValid()) { int status_code = status_code_variant.toInt(); if (status_code == NO_ERROR) { return true; - } - else if (status_code == TOO_MANY_REQUESTS) { + } else if (status_code == TOO_MANY_REQUESTS) { qLog(Debug) << "Too many requests, wait..."; - // If there are too many requests, we just wait + int seconds_to_wait; + if ((*reply)->hasRawHeader("X-Throttle-Wait-Seconds")) { + seconds_to_wait = + ((*reply)->rawHeader("X-Throttle-Wait-Seconds").toInt() + 1) * 1000; + } else { + seconds_to_wait = pow(tries, 2) * 1000; + } + QTimer timer; - timer.start(10000); + timer.start(seconds_to_wait); WaitForSignal(&timer, SIGNAL(timeout())); (*reply)->deleteLater(); - // And we execute the reply again + // We execute the reply again *reply = network_->get((*reply)->request()); WaitForSignal(*reply, SIGNAL(finished())); - return CheckReply(reply); + return CheckReply(reply, ++tries); } } @@ -552,7 +577,6 @@ bool SeafileService::CheckReply(QNetworkReply **reply) { return false; } - SeafileService::~SeafileService() { // Save the tree ! QSettings s; @@ -563,6 +587,4 @@ SeafileService::~SeafileService() { stream << tree_; s.setValue("tree", tree_byte); - } - diff --git a/src/internet/seafileservice.h b/src/internet/seafileservice.h index a839b9fce..c2792a686 100644 --- a/src/internet/seafileservice.h +++ b/src/internet/seafileservice.h @@ -3,18 +3,23 @@ * * Help : * - The "path" variable has to end with "/". - * If we want to specify a filepath, the name of the variable has to be... filepath :) - * - Seafile stores files in libraries (or repositories) so variable with the name "library" corresponds to the + * If we want to specify a filepath, the name of the variable has to be... + *filepath :) + * - Seafile stores files in libraries (or repositories) so variable with the + *name "library" corresponds to the * Seafile library, not to the Clementine library * - The authentification of Seafile's API is simply a token (REST API) - * - Seafile stores a hash for each entry. This hash changes when the entry is modified. - * This is the reason why we just have to compare the local hash with the server + * - Seafile stores a hash for each entry. This hash changes when the entry is + *modified. + * This is the reason why we just have to compare the local hash with the + *server * hash of a directory (for example) to know if the directory was modified. * Libraries are an exception : Seafile stores a hash that never changes. * This hash is called "id". * * Todo : - * - Add ssl certificate exception (for people who generate their own certificate on their Seafile server + * - Add ssl certificate exception (for people who generate their own + *certificate on their Seafile server * - Stop Tagreader when user changes the library */ @@ -22,24 +27,20 @@ #define SEAFILESERVICE_H #include "cloudfileservice.h" -#include "seafiletree.h" #include #include +#include "seafiletree.h" + class QNetworkReply; class QNetworkRequest; // Interface between the seafile server and Clementine class SeafileService : public CloudFileService { - Q_OBJECT + Q_OBJECT public: - - enum ApiError { - NO_ERROR = 200, - NOT_FOUND = 404, - TOO_MANY_REQUESTS = 429 - }; + enum ApiError { NO_ERROR = 200, NOT_FOUND = 404, TOO_MANY_REQUESTS = 429 }; SeafileService(Application* app, InternetModel* parent); ~SeafileService(); @@ -48,12 +49,14 @@ class SeafileService : public CloudFileService { static const char* kSettingsGroup; virtual bool has_credentials() const; - QUrl GetStreamingUrlFromSongId(const QString &library, const QString &filepath); + QUrl GetStreamingUrlFromSongId(const QString& library, + const QString& filepath); // Get the token for an user (simple rest api) - bool GetToken(const QString &mail, const QString &password, const QString &server); + bool GetToken(const QString& mail, const QString& password, + const QString& server); // Get all the libraries available for the user. Will emit a signal void GetLibraries(); - void ChangeLibrary(const QString &new_library); + void ChangeLibrary(const QString& new_library); public slots: void Connect(); @@ -66,25 +69,35 @@ signals: private slots: // Will emit the signal - void GetLibrariesFinished(QNetworkReply *reply); + void GetLibrariesFinished(QNetworkReply* reply); - void FetchAndCheckFolderItemsFinished(QNetworkReply *reply, const SeafileTree::Entry &library, const QString &path); + void FetchAndCheckFolderItemsFinished(QNetworkReply* reply, + const SeafileTree::Entry& library, + const QString& path); // Add recursively the content of a folder from a library - void AddRecursivelyFolderItemsFinished(QNetworkReply *reply, const QString &library, const QString &path); + void AddRecursivelyFolderItemsFinished(QNetworkReply* reply, + const QString& library, + const QString& path); // Get the url and try to add the file to the database - void FetchContentUrlForFileFinished(QNetworkReply* reply, const Song &song, const QString &mime_type); + void FetchContentUrlForFileFinished(QNetworkReply* reply, const Song& song, + const QString& mime_type); // Add the entry to the tree and maybe add this entry to the database - void AddEntry(const QString &library, const QString &path, const SeafileTree::Entry &entry); + void AddEntry(const QString& library, const QString& path, + const SeafileTree::Entry& entry); // Update the entry or check recursively the directories - void UpdateEntry(const QString &library, const QString &path, const SeafileTree::Entry &entry); - // Delete the entry (eventually the files of its subdir) of the tree and the database - void DeleteEntry(const QString &library, const QString &path, const SeafileTree::Entry &entry); + void UpdateEntry(const QString& library, const QString& path, + const SeafileTree::Entry& entry); + // Delete the entry (eventually the files of its subdir) of the tree and the + // database + void DeleteEntry(const QString& library, const QString& path, + const SeafileTree::Entry& entry); - void UpdateLibrariesInProgress(const QMap &libraries); + void UpdateLibrariesInProgress(const QMap& libraries); - void MaybeAddFileEntryInProgress(QNetworkReply *reply, const QString &library, - const QString &path, const QString &mime_type); + void MaybeAddFileEntryInProgress(QNetworkReply* reply, const QString& library, + const QString& path, + const QString& mime_type); private: QString access_token() const; @@ -94,19 +107,24 @@ signals: void UpdateLibraries(); - void FetchAndCheckFolderItems(const SeafileTree::Entry &library, const QString &path); - void AddRecursivelyFolderItems(const QString &library, const QString &path); + void FetchAndCheckFolderItems(const SeafileTree::Entry& library, + const QString& path); + void AddRecursivelyFolderItems(const QString& library, const QString& path); - QNetworkReply* PrepareFetchFolderItems(const QString &library, const QString &path); - QNetworkReply* PrepareFetchContentForFile(const QString &library, const QString &filepath); - QNetworkReply* PrepareFetchContentUrlForFile(const QString &library, const QString &filepath); + QNetworkReply* PrepareFetchFolderItems(const QString& library, + const QString& path); + QNetworkReply* PrepareFetchContentForFile(const QString& library, + const QString& filepath); + QNetworkReply* PrepareFetchContentUrlForFile(const QString& library, + const QString& filepath); - void MaybeAddFileEntry(const QString &entry_name, const QString &library, const QString &path); + void MaybeAddFileEntry(const QString& entry_name, const QString& library, + const QString& path); // False if not 200 or 429 - // If 429 (too many requests), re execute the request and put the reply in the argument - bool CheckReply(QNetworkReply **reply); - + // If 429 (too many requests), re execute the request and put the reply in the + // argument + bool CheckReply(QNetworkReply** reply, int tries = 1); SeafileTree tree_; QString access_token_; diff --git a/src/internet/seafilesettingspage.cpp b/src/internet/seafilesettingspage.cpp index ca99168ca..fb4bd3508 100644 --- a/src/internet/seafilesettingspage.cpp +++ b/src/internet/seafilesettingspage.cpp @@ -15,13 +15,7 @@ along with Clementine. If not, see . */ -#include "seafileservice.h" #include "seafilesettingspage.h" -#include "internetmodel.h" -#include "core/logging.h" -#include "core/network.h" -#include "ui_seafilesettingspage.h" -#include "ui/iconloader.h" #include #include @@ -29,10 +23,17 @@ #include #include +#include "seafileservice.h" +#include "internetmodel.h" +#include "core/logging.h" +#include "core/network.h" +#include "ui_seafilesettingspage.h" +#include "ui/iconloader.h" + SeafileSettingsPage::SeafileSettingsPage(SettingsDialog* dialog) - : SettingsPage(dialog), - ui_(new Ui_SeafileSettingsPage), - service_(InternetModel::Service()) { + : SettingsPage(dialog), + ui_(new Ui_SeafileSettingsPage), + service_(InternetModel::Service()) { ui_->setupUi(this); setWindowIcon(QIcon(":/providers/seafile.png")); @@ -47,12 +48,11 @@ SeafileSettingsPage::SeafileSettingsPage(SettingsDialog* dialog) ui_->library_box->addItem("None", "none"); - connect(service_, SIGNAL(GetLibrariesFinishedSignal(QMap)), this, - SLOT(GetLibrariesFinished(QMap))); + connect(service_, SIGNAL(GetLibrariesFinishedSignal(QMap)), + this, SLOT(GetLibrariesFinished(QMap))); } -SeafileSettingsPage::~SeafileSettingsPage() { delete ui_; } - +SeafileSettingsPage::~SeafileSettingsPage() {} void SeafileSettingsPage::Load() { QSettings s; @@ -62,23 +62,26 @@ void SeafileSettingsPage::Load() { ui_->mail->setText(s.value("mail").toString()); if (!ui_->server->text().isEmpty() && !ui_->mail->text().isEmpty()) { - ui_->login_state->SetLoggedIn(LoginStateWidget::LoggedIn, ui_->mail->text()); + ui_->login_state->SetLoggedIn(LoginStateWidget::LoggedIn, + ui_->mail->text()); - // If there is more than "none" library, that means that we already got the libraries - if(ui_->library_box->count() <= 1) { - service_->GetLibraries(); + // If there is more than "none" library, that means that we already got the + // libraries + if (ui_->library_box->count() <= 1) { + service_->GetLibraries(); } } } -void SeafileSettingsPage::GetLibrariesFinished(QMap libraries) { +void SeafileSettingsPage::GetLibrariesFinished( + const QMap& libraries) { ui_->library_box->clear(); ui_->library_box->addItem("None", "none"); ui_->library_box->addItem("All (could be slow)", "all"); // key : library's id, value : library's name - QMapIterator library(libraries); - while(library.hasNext()) { + QMapIterator library(libraries); + while (library.hasNext()) { library.next(); ui_->library_box->addItem(library.value(), library.key()); } @@ -93,9 +96,9 @@ void SeafileSettingsPage::GetLibrariesFinished(QMap libraries) } } - void SeafileSettingsPage::Save() { - QString id = ui_->library_box->itemData(ui_->library_box->currentIndex()).toString(); + QString id = + ui_->library_box->itemData(ui_->library_box->currentIndex()).toString(); QSettings s; s.beginGroup(SeafileService::kSettingsGroup); @@ -108,21 +111,21 @@ void SeafileSettingsPage::Save() { service_->ChangeLibrary(id); } - void SeafileSettingsPage::Login() { - ui_->login_button->setEnabled(false); - if(service_->GetToken(ui_->mail->text(), ui_->password->text(), ui_->server->text())) { + if (service_->GetToken(ui_->mail->text(), ui_->password->text(), + ui_->server->text())) { Save(); - ui_->login_state->SetLoggedIn(LoginStateWidget::LoggedIn, ui_->mail->text()); + ui_->login_state->SetLoggedIn(LoginStateWidget::LoggedIn, + ui_->mail->text()); service_->GetLibraries(); - } - else { + } else { ui_->login_button->setEnabled(true); - QMessageBox::warning(this, tr("Unable to connect"), tr("Unable to connect")); + QMessageBox::warning(this, tr("Unable to connect"), + tr("Unable to connect")); } } @@ -145,6 +148,4 @@ void SeafileSettingsPage::Logout() { ui_->login_state->SetLoggedIn(LoginStateWidget::LoggedOut); ui_->login_button->setEnabled(true); - } - diff --git a/src/internet/seafilesettingspage.h b/src/internet/seafilesettingspage.h index be0801384..a0902498d 100644 --- a/src/internet/seafilesettingspage.h +++ b/src/internet/seafilesettingspage.h @@ -40,12 +40,11 @@ class SeafileSettingsPage : public SettingsPage { void Login(); void Logout(); // Map -> key : library's id, value : library's name - void GetLibrariesFinished(QMap libraries); + void GetLibrariesFinished(const QMap& libraries); private: - Ui_SeafileSettingsPage* ui_; + std::unique_ptr ui_; SeafileService* service_; - }; #endif // SEAFILESETTINGSPAGE_H diff --git a/src/internet/seafiletree.cpp b/src/internet/seafiletree.cpp index 251923453..b3bcaceb0 100644 --- a/src/internet/seafiletree.cpp +++ b/src/internet/seafiletree.cpp @@ -3,32 +3,32 @@ #include #include #include + #include "core/logging.h" -/* ############################## SeafileTree ############################## */ +SeafileTree::SeafileTree() {} -SeafileTree::SeafileTree() { } +SeafileTree::SeafileTree(const SeafileTree& copy) : SeafileTree() { + libraries_ = copy.libraries(); +} -SeafileTree::SeafileTree(const SeafileTree ©) : SeafileTree() - { libraries_ = copy.libraries(); } - -QList SeafileTree::libraries() const { return libraries_; } +QList SeafileTree::libraries() const { + return libraries_; +} void SeafileTree::Print() const { qLog(Debug) << "library count : " << libraries_.count(); - for (TreeItem *item : libraries_) { + for (TreeItem* item : libraries_) { qLog(Debug) << "library : " << item->ToString(1); } } -void SeafileTree::AddLibrary(const QString &name, const QString &id) { - libraries_.append( - new TreeItem( - Entry(name, id, Entry::Type::LIBRARY))); +void SeafileTree::AddLibrary(const QString& name, const QString& id) { + libraries_.append(new TreeItem(Entry(name, id, Entry::Type::LIBRARY))); } -void SeafileTree::DeleteLibrary(const QString &id) { +void SeafileTree::DeleteLibrary(const QString& id) { for (int i = 0; i < libraries_.size(); ++i) { if (libraries_.at(i)->entry().id() == id) { libraries_.removeAt(i); @@ -37,17 +37,17 @@ void SeafileTree::DeleteLibrary(const QString &id) { } } +bool SeafileTree::AddEntry(const QString& library, const QString& path, + const Entry& entry) { + TreeItem* dir_node = FindFromAbsolutePath(library, path); -bool SeafileTree::AddEntry(const QString& library, const QString &path, const Entry &entry) { - TreeItem *dir_node = FindFromAbsolutePath(library, path); - - if(!dir_node) { + if (!dir_node) { qLog(Warning) << "Can't find the path..."; return false; } // If it is not a dir or a library we can't add an entry... - if(!dir_node->entry().is_dir() && !dir_node->entry().is_library()) { + if (!dir_node->entry().is_dir() && !dir_node->entry().is_library()) { qLog(Warning) << "This is not a dir or a file..."; return false; } @@ -57,27 +57,28 @@ bool SeafileTree::AddEntry(const QString& library, const QString &path, const En return true; } - -void SeafileTree::CheckEntries(const Entries &server_entries, const Entry &library, const QString &path) { - TreeItem *local_item = FindFromAbsolutePath(library.id(), path); +void SeafileTree::CheckEntries(const Entries& server_entries, + const Entry& library, const QString& path) { + TreeItem* local_item = FindFromAbsolutePath(library.id(), path); // Don't know the path // Have to add all entries - if(!local_item) { + if (!local_item) { emit ToAdd(library.id(), path, library); return; } - Entries local_entries = local_item->childs_entry(); + Entries local_entries = local_item->children_entries(); - for (const Entry &server_entry : server_entries) { + for (const Entry& server_entry : server_entries) { bool is_in_tree = false; - for (int i=0; ientry().id() == library) - return item; +SeafileTree::TreeItem* SeafileTree::FindLibrary(const QString& library) { + for (TreeItem* item : libraries_) { + if (item->entry().id() == library) return item; } return nullptr; } -SeafileTree::TreeItem* SeafileTree::FindFromAbsolutePath(const QString &library, const QString &path) { - TreeItem *node_item = FindLibrary(library); +SeafileTree::TreeItem* SeafileTree::FindFromAbsolutePath(const QString& library, + const QString& path) { + TreeItem* node_item = FindLibrary(library); if (!node_item) { return nullptr; @@ -127,10 +128,10 @@ SeafileTree::TreeItem* SeafileTree::FindFromAbsolutePath(const QString &library, QStringList path_parts = path.split("/", QString::SkipEmptyParts); - for (const QString &part : path_parts) { + for (const QString& part : path_parts) { node_item = node_item->FindChild(part); - if(!node_item) { + if (!node_item) { break; } } @@ -138,25 +139,27 @@ SeafileTree::TreeItem* SeafileTree::FindFromAbsolutePath(const QString &library, return node_item; } -bool SeafileTree::DeleteEntry(const QString &library, const QString &path, const Entry &entry) { - TreeItem *item_parent = FindFromAbsolutePath(library, path); +bool SeafileTree::DeleteEntry(const QString& library, const QString& path, + const Entry& entry) { + TreeItem* item_parent = FindFromAbsolutePath(library, path); - if(!item_parent) { - qLog(Debug) << "Unable to delete " << library + path + entry.name() + if (!item_parent) { + qLog(Debug) << "Unable to delete " << library + path + entry.name() << " : path " << path << " not found"; return false; } - TreeItem *item_entry = item_parent->FindChild(entry.name()); + TreeItem* item_entry = item_parent->FindChild(entry.name()); - if(!item_entry) { - qLog(Debug) << "Unable to delete " << library + path + entry.name() + if (!item_entry) { + qLog(Debug) << "Unable to delete " << library + path + entry.name() << " : entry " << entry.name() << " from path not found"; return false; } - if(!item_parent->RemoveChild(item_entry)) { - qLog(Debug) << "Can't remove " << item_entry->entry().name() << " from parent"; + if (!item_parent->RemoveChild(item_entry)) { + qLog(Debug) << "Can't remove " << item_entry->entry().name() + << " from parent"; return false; } @@ -170,25 +173,24 @@ void SeafileTree::Clear() { libraries_.clear(); } - -QList> SeafileTree::GetRecursiveFilesOfDir(const QString &path, const TreeItem *item) { +QList> SeafileTree::GetRecursiveFilesOfDir( + const QString& path, const TreeItem* item) { // key = path, value = entry QList> files; - if(!item) { + if (!item) { return files; } - if(item->entry().is_file()) { + if (item->entry().is_file()) { files.append(qMakePair(path, item->entry())); } // Get files of the dir else { - for (TreeItem *child_item : item->childs()) { - if(child_item->entry().is_file()) { + for (TreeItem* child_item : item->children()) { + if (child_item->entry().is_file()) { files.append(qMakePair(path, child_item->entry())); - } - else { + } else { QString name = child_item->entry().name() + "/"; files.append(GetRecursiveFilesOfDir(path + name, child_item)); } @@ -200,38 +202,25 @@ QList> SeafileTree::GetRecursiveFilesOfDir(co SeafileTree::~SeafileTree() {} - - /* ################################# Entry ################################# */ -SeafileTree::Entry::Entry() - : Entry("", "", Type::FILE) {} - -SeafileTree::Entry::Entry(const SeafileTree::Entry &entry) - : Entry(entry.name(), entry.id(), entry.type()) {} - -SeafileTree::Entry::Entry(const QString& name, const QString& id, const Type& type) { - name_ = name; - id_ = id; - type_ = type; -} - QString SeafileTree::Entry::name() const { return name_; } QString SeafileTree::Entry::id() const { return id_; } SeafileTree::Entry::Type SeafileTree::Entry::type() const { return type_; } bool SeafileTree::Entry::is_dir() const { return (type_ == Entry::DIR); } bool SeafileTree::Entry::is_file() const { return (type_ == Entry::FILE); } -bool SeafileTree::Entry::is_library() const { return (type_ == Entry::LIBRARY); } -void SeafileTree::Entry::set_name(const QString &name) { name_ = name; } -void SeafileTree::Entry::set_id(const QString &id) { id_ = id; } -void SeafileTree::Entry::set_type(const Type &type) { type_ = type; } - +bool SeafileTree::Entry::is_library() const { + return (type_ == Entry::LIBRARY); +} +void SeafileTree::Entry::set_name(const QString& name) { name_ = name; } +void SeafileTree::Entry::set_id(const QString& id) { id_ = id; } +void SeafileTree::Entry::set_type(const Type& type) { type_ = type; } QString SeafileTree::Entry::ToString() const { return "name : " + name_ + " id : " + id_ + " type : " + TypeToString(type_); } -SeafileTree::Entry& SeafileTree::Entry::operator =(const Entry &entry) { +SeafileTree::Entry& SeafileTree::Entry::operator=(const Entry& entry) { name_ = entry.name(); id_ = entry.id(); type_ = entry.type(); @@ -239,90 +228,81 @@ SeafileTree::Entry& SeafileTree::Entry::operator =(const Entry &entry) { return *this; } -bool SeafileTree::Entry::operator ==(const Entry &a) const { - if(a.name() == name() && a.id() == id() && a.type() == type()) - return true; - - return false; +bool SeafileTree::Entry::operator==(const Entry& a) const { + return a.name() == name() && a.id() == id() && a.type() == type(); } -bool SeafileTree::Entry::operator !=(const Entry &a) const { - return !(operator ==(a)); +bool SeafileTree::Entry::operator!=(const Entry& a) const { + return !(operator==(a)); } SeafileTree::Entry::~Entry() {} - -QString SeafileTree::Entry::TypeToString(const Type &type) { - if (type == DIR) { - return "dir"; +QString SeafileTree::Entry::TypeToString(const Type& type) { + switch (type) { + case DIR: + return "dir"; + case FILE: + return "file"; + case LIBRARY: + return "library"; + default: + return QString::null; } - else if (type == FILE) { - return "file"; - } - else if (type == LIBRARY) { - return "library"; - } - - return QString::null; } -SeafileTree::Entry::Type SeafileTree::Entry::StringToType(const QString &type) { - if (type == "dir") { - return DIR; - } - else if (type == "file") { - return FILE; - } - else if (type == "library") { - return LIBRARY; - } +SeafileTree::Entry::Type SeafileTree::Entry::StringToType(const QString& type) { + if (type == "dir") { + return DIR; + } else if (type == "file") { + return FILE; + } else if (type == "library") { + return LIBRARY; + } - return NONE; + return NONE; } - /* ############################### TreeItem ############################### */ -SeafileTree::TreeItem::TreeItem() { entry_ = Entry(); } - -SeafileTree::TreeItem::TreeItem(const TreeItem ©) { entry_ = copy.entry(); } - -SeafileTree::TreeItem::TreeItem(const Entry &entry) { entry_ = entry; } - -SeafileTree::TreeItem::TreeItem(const Entry &entry, QList *childs) { - entry_ = entry; - childs_ = *childs; -} - -SeafileTree::Entries SeafileTree::TreeItem::childs_entry() const { +SeafileTree::Entries SeafileTree::TreeItem::children_entries() const { Entries entries; - for (TreeItem *item : childs_) { + for (TreeItem* item : children_) { entries.append(Entry(item->entry())); } return entries; } -SeafileTree::TreeItem* SeafileTree::TreeItem::child(int i) const { return childs_.at(i); } -QList SeafileTree::TreeItem::childs() const { return childs_; } +SeafileTree::TreeItem* SeafileTree::TreeItem::child(int i) const { + return children_.at(i); +} +QList SeafileTree::TreeItem::children() const { + return children_; +} SeafileTree::Entry SeafileTree::TreeItem::entry() const { return entry_; } -void SeafileTree::TreeItem::set_entry(const Entry &entry) { entry_ = entry;} -void SeafileTree::TreeItem::set_childs(QList *childs) { childs_ = *childs; } - -void SeafileTree::TreeItem::AppendChild(TreeItem *child) { childs_.append(child); } - -void SeafileTree::TreeItem::AppendChild(const Entry &entry) { - childs_.append(new TreeItem(entry)); +void SeafileTree::TreeItem::set_entry(const Entry& entry) { entry_ = entry; } +void SeafileTree::TreeItem::set_children(const QList& children) { + children_ = children; } -bool SeafileTree::TreeItem::RemoveChild(TreeItem *child) { return childs_.removeOne(child); } +void SeafileTree::TreeItem::AppendChild(TreeItem* child) { + children_.append(child); +} -SeafileTree::TreeItem* SeafileTree::TreeItem::FindChild(const QString &name) const { - for (TreeItem *item : childs_) { - if (item->entry().name() == name) - return item; +void SeafileTree::TreeItem::AppendChild(const Entry& entry) { + children_.append(new TreeItem(entry)); +} + +bool SeafileTree::TreeItem::RemoveChild(TreeItem* child) { + return children_.removeOne(child); +} + +SeafileTree::TreeItem* SeafileTree::TreeItem::FindChild( + const QString& name) const { + for (TreeItem* item : children_) { + if (item->entry().name() == name) return item; } return nullptr; @@ -337,31 +317,25 @@ QString SeafileTree::TreeItem::ToString(int i) const { res += entry_.ToString() + "\n"; - for (TreeItem *item : childs_) { - res += item->ToString( i+1 ); + for (TreeItem* item : children_) { + res += item->ToString(i + 1); } return res; } SeafileTree::TreeItem::~TreeItem() { - // We need to delete childs - for (TreeItem *item : childs_) { - delete item; - } + // We need to delete children + qDeleteAll(children_); } - - -QDataStream & operator << (QDataStream &out, const SeafileTree::Entry &entry) { - out << entry.name_ - << entry.id_ - << static_cast(entry.type_); +QDataStream& operator<<(QDataStream& out, const SeafileTree::Entry& entry) { + out << entry.name_ << entry.id_ << static_cast(entry.type_); return out; } -QDataStream & operator >> (QDataStream &in, SeafileTree::Entry &entry) { +QDataStream& operator>>(QDataStream& in, SeafileTree::Entry& entry) { quint8 temp; in >> entry.name_; @@ -372,34 +346,31 @@ QDataStream & operator >> (QDataStream &in, SeafileTree::Entry &entry) { return in; } -QDataStream & operator << (QDataStream &out, SeafileTree::TreeItem *item) { - out << item->entry_ - << item->childs_; +QDataStream& operator<<(QDataStream& out, SeafileTree::TreeItem* item) { + out << item->entry_ << item->children_; return out; } +QDataStream& operator>>(QDataStream& in, SeafileTree::TreeItem*& item) { + SeafileTree::Entry entry; + QList children; -QDataStream & operator >> (QDataStream &in, SeafileTree::TreeItem *&item) { - SeafileTree::Entry *entry = new SeafileTree::Entry(); - QList *childs = new QList; + in >> entry; + in >> children; - in >> *entry; - in >> *childs; - - item = new SeafileTree::TreeItem(*entry, childs); + item = new SeafileTree::TreeItem(entry, children); return in; } - -QDataStream & operator << (QDataStream &out, const SeafileTree &tree) { +QDataStream& operator<<(QDataStream& out, const SeafileTree& tree) { out << tree.libraries_; return out; } -QDataStream & operator >> (QDataStream &in, SeafileTree &tree) { +QDataStream& operator>>(QDataStream& in, SeafileTree& tree) { in >> tree.libraries_; return in; diff --git a/src/internet/seafiletree.h b/src/internet/seafiletree.h index dc20f2c7b..875c48d35 100644 --- a/src/internet/seafiletree.h +++ b/src/internet/seafiletree.h @@ -17,54 +17,48 @@ class SeafileTree : public QObject { Q_OBJECT -public: - + public: SeafileTree(); - SeafileTree(const SeafileTree ©); + SeafileTree(const SeafileTree& copy); ~SeafileTree(); class Entry { + public: + enum Type { DIR = 0, FILE = 1, LIBRARY = 2, NONE = 3 }; - public: - - enum Type { - DIR = 0, - FILE = 1, - LIBRARY = 2, - NONE = 3 - }; - - Entry(); - Entry(const Entry &entry); - Entry(const QString &name, const QString &id, const Type &type); + Entry(const QString& name = QString(), const QString& id = QString(), + const Type& type = NONE) + : name_(name), id_(id), type_(type) {} + Entry(const Entry& entry) : Entry(entry.name(), entry.id(), entry.type()) {} ~Entry(); QString name() const; - void set_name(const QString &name); + void set_name(const QString& name); QString id() const; - void set_id(const QString &id); + void set_id(const QString& id); Type type() const; - void set_type(const Type &type); + void set_type(const Type& type); bool is_dir() const; bool is_file() const; bool is_library() const; - Entry& operator =(const Entry &entry); - bool operator ==(const Entry &a) const; - bool operator !=(const Entry &a) const; + Entry& operator=(const Entry& entry); + bool operator==(const Entry& a) const; + bool operator!=(const Entry& a) const; QString ToString() const; - static QString TypeToString(const Type &type); - static Type StringToType(const QString &type); + static QString TypeToString(const Type& type); + static Type StringToType(const QString& type); - private: + private: QString name_, id_; Type type_; - friend QDataStream & operator << (QDataStream &out, const SeafileTree::Entry &entry); - friend QDataStream & operator >> (QDataStream &in, SeafileTree::Entry &entry); + friend QDataStream& operator<<(QDataStream& out, + const SeafileTree::Entry& entry); + friend QDataStream& operator>>(QDataStream& in, SeafileTree::Entry& entry); }; typedef QList Entries; @@ -72,61 +66,68 @@ public: // Node of the tree // Contains an entry class TreeItem { - public: - TreeItem(); - TreeItem(const TreeItem ©); - TreeItem(const Entry &entry); - TreeItem(const Entry &entry, QList *childs); + public: + TreeItem(const Entry& entry = Entry(), + const QList& children = QList()) + : entry_(entry), children_(children) {} + TreeItem(const TreeItem& copy) : TreeItem(copy.entry()) {} ~TreeItem(); TreeItem* child(int i) const; - QList childs() const; + QList children() const; // List of each child's entry - Entries childs_entry() const; + Entries children_entries() const; - void set_childs(QList *childs); + void set_children(const QList& children); Entry entry() const; - void set_entry(const Entry &entry); + void set_entry(const Entry& entry); - void AppendChild(TreeItem *child); - void AppendChild(const Entry &entry); + void AppendChild(TreeItem* child); + void AppendChild(const Entry& entry); // True if child is removed - bool RemoveChild(TreeItem *child); + bool RemoveChild(TreeItem* child); // nullptr if we didn't find a child entry with the given name - TreeItem* FindChild(const QString &name) const; + TreeItem* FindChild(const QString& name) const; // Convert the node in QString (for debug) QString ToString(int i) const; - private: + private: Entry entry_; - QList childs_; + QList children_; - friend QDataStream & operator << (QDataStream &out, SeafileTree::TreeItem *item); - friend QDataStream & operator >> (QDataStream &in, SeafileTree::TreeItem *&item); + friend QDataStream& operator<<(QDataStream& out, + SeafileTree::TreeItem* item); + friend QDataStream& operator>>(QDataStream& in, + SeafileTree::TreeItem*& item); }; QList libraries() const; - void AddLibrary(const QString &name, const QString &id); - void DeleteLibrary(const QString &id); - bool AddEntry(const QString &library, const QString &path, const Entry &entry); - bool DeleteEntry(const QString &library, const QString &path, const Entry &entry); + void AddLibrary(const QString& name, const QString& id); + void DeleteLibrary(const QString& id); + bool AddEntry(const QString& library, const QString& path, + const Entry& entry); + bool DeleteEntry(const QString& library, const QString& path, + const Entry& entry); - // Get a list of pair (path, entry) corresponding to the subfiles (and recursively to the subsubfiles...) of the given item - QList> GetRecursiveFilesOfDir(const QString &path, const TreeItem *item); + // Get a list of pair (path, entry) corresponding to the subfiles (and + // recursively to the subsubfiles...) of the given item + QList> GetRecursiveFilesOfDir( + const QString& path, const TreeItem* item); // nullptr if we didn't find the library with the given id - TreeItem* FindLibrary(const QString &library); + TreeItem* FindLibrary(const QString& library); // nullptr if we didn't find the item - TreeItem* FindFromAbsolutePath(const QString &library, const QString &path); + TreeItem* FindFromAbsolutePath(const QString& library, const QString& path); // Compare the server entries with the tree // Emit signals (ToDelete, ToAdd, ToUpdate) - void CheckEntries(const Entries &server_entries, const Entry &library, const QString &path); + void CheckEntries(const Entries& server_entries, const Entry& library, + const QString& path); // Destroy the tree void Clear(); @@ -136,27 +137,29 @@ public: signals: // Entry to delete in the tree - void ToDelete(const QString &library, const QString &path, const SeafileTree::Entry &entry); + void ToDelete(const QString& library, const QString& path, + const SeafileTree::Entry& entry); // Entry to add in the tree - void ToAdd(const QString &library, const QString &path, const SeafileTree::Entry &entry); + void ToAdd(const QString& library, const QString& path, + const SeafileTree::Entry& entry); // Entry to update in the tree - void ToUpdate(const QString &library, const QString &path, const SeafileTree::Entry &entry); + void ToUpdate(const QString& library, const QString& path, + const SeafileTree::Entry& entry); -private: + private: QList libraries_; - friend QDataStream & operator << (QDataStream &out, const SeafileTree &tree); - friend QDataStream & operator >> (QDataStream &in, SeafileTree &tree); + friend QDataStream& operator<<(QDataStream& out, const SeafileTree& tree); + friend QDataStream& operator>>(QDataStream& in, SeafileTree& tree); }; -QDataStream & operator << (QDataStream &out, const SeafileTree &tree); -QDataStream & operator >> (QDataStream &in, SeafileTree &tree); +QDataStream& operator<<(QDataStream& out, const SeafileTree& tree); +QDataStream& operator>>(QDataStream& in, SeafileTree& tree); -QDataStream & operator << (QDataStream &out, const SeafileTree::Entry &entry); -QDataStream & operator >> (QDataStream &in, SeafileTree::Entry &entry); - -QDataStream & operator << (QDataStream &out, SeafileTree::TreeItem *item); -QDataStream & operator >> (QDataStream &in, SeafileTree::TreeItem *&item); +QDataStream& operator<<(QDataStream& out, const SeafileTree::Entry& entry); +QDataStream& operator>>(QDataStream& in, SeafileTree::Entry& entry); +QDataStream& operator<<(QDataStream& out, SeafileTree::TreeItem* item); +QDataStream& operator>>(QDataStream& in, SeafileTree::TreeItem*& item); #endif // SEAFILETREE_H