From 0e58e5ca473288b2426351b2560e1f649e5a48e4 Mon Sep 17 00:00:00 2001 From: Heran Yang Date: Wed, 6 Mar 2024 17:15:55 +0800 Subject: [PATCH 1/4] Support multiple accounts Support multiple accounts Modify delete account info --- src/account-mgr.cpp | 26 ++++++++++++++++++++++++++ src/account-mgr.h | 3 +++ src/account.h | 6 ++++++ src/daemon-mgr.cpp | 15 +++++++++++++++ src/rpc/rpc-client.cpp | 26 ++++++++++++++++++++++++++ src/seadrive-gui.cpp | 36 ++++++++++++++++++++++++++++++++++-- src/seadrive-gui.h | 3 ++- src/ui/tray-icon.cpp | 2 +- 8 files changed, 113 insertions(+), 4 deletions(-) diff --git a/src/account-mgr.cpp b/src/account-mgr.cpp index 0a1dce45..f16ed0ec 100644 --- a/src/account-mgr.cpp +++ b/src/account-mgr.cpp @@ -413,6 +413,8 @@ int AccountManager::resyncAccount(const Account& account) #if defined(Q_OS_WIN32) setAccountSyncRoot(updated_account); +#elif defined(Q_OS_LINUX) + setAccountDisplayName(updated_account); #endif SeafileRpcClient *rpc_client = gui->rpcClient(updated_account.domainID()); @@ -631,6 +633,10 @@ void AccountManager::addAccountToDaemon(const Account& account) gui->fileProviderManager()->registerDomain(added_account); gui->fileProviderManager()->askUserToEnable(); } +#elif defined(Q_OS_LINUX) + if (added_account.isValid()) { + setAccountDisplayName(added_account); + } #endif #ifndef Q_OS_MAC @@ -852,6 +858,26 @@ void AccountManager::setAccountSyncRoot(Account &account) } #endif +#if defined(Q_OS_LINUX) +void AccountManager::setAccountDisplayName(Account &account) +{ + QString name = account.accountInfo.name; + if (name.isEmpty()) { + name = account.username; + } + QString displayName = name + "(" + account.serverUrl.host() + ")"; + account.displayName = displayName; + + QMutexLocker locker(&accounts_mutex_); + for (size_t i = 0; i < accounts_.size(); i++) { + if (accounts_.at(i) == account) { + accounts_[i].displayName = displayName; + break; + } + } +} +#endif + void AccountManager::reloginAccount(const Account &account) { if (account.isShibboleth) { diff --git a/src/account-mgr.h b/src/account-mgr.h index 3976b543..b43c3a4b 100644 --- a/src/account-mgr.h +++ b/src/account-mgr.h @@ -129,6 +129,9 @@ private slots: const QString getOldSyncRootDir(const Account& account); const QString genSyncRootName(const Account& account); void setAccountSyncRoot(Account &account); +#endif +#if defined(Q_OS_LINUX) + void setAccountDisplayName(Account &account); #endif static bool loadAccountsCB(struct sqlite3_stmt *stmt, void *data); static bool loadServerInfoCB(struct sqlite3_stmt *stmt, void *data); diff --git a/src/account.h b/src/account.h index fe7cbd80..7551bb65 100644 --- a/src/account.h +++ b/src/account.h @@ -26,6 +26,8 @@ class Account { QString token; #if defined(Q_OS_WIN32) QString syncRoot; +#elif defined (Q_OS_LINUX) + QString displayName; #endif qint64 lastVisited; bool isShibboleth; @@ -68,6 +70,8 @@ class Account { token(rhs.token), #if defined(Q_OS_WIN32) syncRoot(rhs.syncRoot), +#elif defined(Q_OS_LINUX) + displayName(rhs.displayName), #endif lastVisited(rhs.lastVisited), isShibboleth(rhs.isShibboleth), @@ -87,6 +91,8 @@ class Account { token = rhs.token; #if defined(Q_OS_WIN32) syncRoot = rhs.syncRoot; +#elif defined(Q_OS_LINUX) + displayName = rhs.displayName; #endif lastVisited = rhs.lastVisited; isShibboleth = rhs.isShibboleth; diff --git a/src/daemon-mgr.cpp b/src/daemon-mgr.cpp index 9fb48ae2..591ceb21 100644 --- a/src/daemon-mgr.cpp +++ b/src/daemon-mgr.cpp @@ -176,6 +176,21 @@ QStringList DaemonManager::collectSeaDriveArgs() args << sync_root_path; #endif +#if defined(Q_OS_LINUX) + args << "-f"; + + QString fuse_opts = qgetenv("SEADRIVE_FUSE_OPTS"); + if (fuse_opts.isEmpty()) { + QStringList umount_arguments; + umount_arguments << "-u" << gui->seadriveRoot(); + QProcess::execute("fusermount", umount_arguments); + QString mount_dir = gui->seadriveRoot(); + args << mount_dir; + } else { + args << fuse_opts.split(" "); + } +#endif + auto stream = qWarning() << "starting seadrive daemon:" << kSeadriveExecutable; foreach (const QString& arg, args) { stream << arg; diff --git a/src/rpc/rpc-client.cpp b/src/rpc/rpc-client.cpp index 83c3b8f7..f2fa424c 100644 --- a/src/rpc/rpc-client.cpp +++ b/src/rpc/rpc-client.cpp @@ -619,6 +619,32 @@ bool SeafileRpcClient::addAccount(const Account& account) return true; } +#elif defined(Q_OS_LINUX) +bool SeafileRpcClient::addAccount(const Account& account) +{ + GError *error = NULL; + QString serverAddr = account.serverUrl.toEncoded().data(); + if (serverAddr.endsWith("/")) { + serverAddr = serverAddr.left(serverAddr.size() - 1); + } + + searpc_client_call__int(seadrive_rpc_client_, "seafile_add_account", &error, + 5, + "string", toCStr(serverAddr), + "string", toCStr(account.username), + "string", toCStr(account.token), + "string", toCStr(account.displayName), + "int", account.isPro() ? 1 : 0); + if (error) { + qWarning() << "Unable to add account" << account << ":" + << (error->message ? error->message : ""); + g_error_free(error); + return false; + } + qWarning() << "Add account" << account; + + return true; +} #endif bool SeafileRpcClient::deleteAccount(const Account& account, bool remove_cache) diff --git a/src/seadrive-gui.cpp b/src/seadrive-gui.cpp index 11c5929b..caf19596 100644 --- a/src/seadrive-gui.cpp +++ b/src/seadrive-gui.cpp @@ -482,6 +482,17 @@ void SeadriveGui::start() RemoteWipeService::instance()->start(); AccountInfoService::instance()->start(); +#elif defined(Q_OS_LINUX) + settings_mgr_->loadProxySettings(); + settings_mgr_->applyProxySettings(); + + loginAccounts(); + + connect(daemon_mgr_, SIGNAL(daemonStarted()), + this, SLOT(onDaemonStarted())); + connect(daemon_mgr_, SIGNAL(daemonRestarted()), + this, SLOT(onDaemonRestarted())); + daemon_mgr_->startSeadriveDaemon(); #endif } @@ -543,8 +554,8 @@ void SeadriveGui::onDaemonStarted() message_poller->start(); message_pollers_.insert(EMPTY_DOMAIN_ID, message_poller); } -#if defined(Q_OS_WIN32) - rpc_client->connectDaemon(); +#if defined(Q_OS_WIN32) || defined(Q_OS_LINUX) + rpc_client_->connectDaemon(); #endif auto accounts = account_mgr_->activeAccounts(); @@ -800,6 +811,22 @@ bool SeadriveGui::initLog() } #endif + // On linux we must unmount the mount point dir before trying to create it, + // otherwise checkdir_with_mkdir would think it doesn't exist and try to + // create it, but the creation operation would fail. +#if defined(Q_OS_LINUX) + QStringList umount_arguments; + umount_arguments << "-u" << seadriveRoot(); + QProcess::execute("fusermount", umount_arguments); +#endif + +#if defined(Q_OS_LINUX) + if (checkdir_with_mkdir(toCStr(seadriveRoot())) < 0) { + errorAndExit(tr("Failed to initialize: failed to create seadrive mount folder")); + return false; + } +#endif + if (applet_log_init(toCStr(seadrive_dir.absolutePath())) < 0) { errorAndExit(tr("Failed to initialize log: %1").arg(g_strerror(errno))); return false; @@ -1023,6 +1050,11 @@ QString SeadriveGui::seadriveRoot() const { return seadrive_root_; } +#elif defined(Q_OS_LINUX) +QString SeadriveGui::seadriveRoot() const +{ + return QDir::home().absoluteFilePath(getBrand()); +} #endif QString SeadriveGui::getUniqueClientId() diff --git a/src/seadrive-gui.h b/src/seadrive-gui.h index f21bd035..1daa6f0e 100644 --- a/src/seadrive-gui.h +++ b/src/seadrive-gui.h @@ -67,7 +67,7 @@ class SeadriveGui : public QObject { void migrateOldConfig(const QString& data_dir); -#if defined(Q_OS_WIN32) +#if defined(Q_OS_WIN32) || defined(Q_OS_LINUX) QString seadriveRoot() const; #endif @@ -107,6 +107,7 @@ private slots: void onDaemonStarted(); void onDaemonRestarted(); void onDaemonRestarted(const QString& domain_id); + void connectDaemon(); private: diff --git a/src/ui/tray-icon.cpp b/src/ui/tray-icon.cpp index 6acbd305..0126f15b 100644 --- a/src/ui/tray-icon.cpp +++ b/src/ui/tray-icon.cpp @@ -714,7 +714,7 @@ void SeafileTrayIcon::deleteAccount() return; } -#ifdef Q_OS_WIN32 +#if defined(Q_OS_WIN32) || defined(Q_OS_LINUX) QString question = tr("Are you sure to remove account from \"%1\"?").arg(account.serverUrl.toString()); #else QString question = tr("Are you sure to remove account from \"%1\"? After removing account, you can still find downloaded files at ~/Library/CloudStorage.").arg(account.serverUrl.toString()); From 8b8477e4d90c2253eecc7056d95d0ea4f844e2b5 Mon Sep 17 00:00:00 2001 From: Heran Yang Date: Thu, 28 Nov 2024 11:15:00 +0800 Subject: [PATCH 2/4] Fix rebase error --- src/rpc/rpc-client.cpp | 3 ++- src/seadrive-gui.cpp | 2 +- src/ui/search-dialog.cpp | 6 ++++++ src/ui/transfer-progress-dialog.cpp | 2 +- src/ui/tray-icon.cpp | 4 ++++ 5 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/rpc/rpc-client.cpp b/src/rpc/rpc-client.cpp index f2fa424c..6fd28e8e 100644 --- a/src/rpc/rpc-client.cpp +++ b/src/rpc/rpc-client.cpp @@ -629,9 +629,10 @@ bool SeafileRpcClient::addAccount(const Account& account) } searpc_client_call__int(seadrive_rpc_client_, "seafile_add_account", &error, - 5, + 6, "string", toCStr(serverAddr), "string", toCStr(account.username), + "string", toCStr(account.accountInfo.name), "string", toCStr(account.token), "string", toCStr(account.displayName), "int", account.isPro() ? 1 : 0); diff --git a/src/seadrive-gui.cpp b/src/seadrive-gui.cpp index caf19596..9c663b2d 100644 --- a/src/seadrive-gui.cpp +++ b/src/seadrive-gui.cpp @@ -555,7 +555,7 @@ void SeadriveGui::onDaemonStarted() message_pollers_.insert(EMPTY_DOMAIN_ID, message_poller); } #if defined(Q_OS_WIN32) || defined(Q_OS_LINUX) - rpc_client_->connectDaemon(); + rpc_client->connectDaemon(); #endif auto accounts = account_mgr_->activeAccounts(); diff --git a/src/ui/search-dialog.cpp b/src/ui/search-dialog.cpp index 046b4122..b519554c 100644 --- a/src/ui/search-dialog.cpp +++ b/src/ui/search-dialog.cpp @@ -519,6 +519,9 @@ void SearchItemsTableView::openDirectory(bool open_file) #endif #ifdef Q_OS_WIN32 QString root = search_model_->account_.syncRoot; +#endif +#ifdef Q_OS_LINUX + QString root = gui->seadriveRoot(); #endif if (root.isEmpty()) { qWarning() << "failed to get root path"; @@ -561,6 +564,9 @@ void SearchItemsTableView::onItemDoubleClick(const QModelIndex& index) #endif #ifdef Q_OS_WIN32 QString root = search_model_->account_.syncRoot; +#endif +#ifdef Q_OS_LINUX + QString root = gui->seadriveRoot(); #endif if (root.isEmpty()) { qWarning() << "failed to get root path"; diff --git a/src/ui/transfer-progress-dialog.cpp b/src/ui/transfer-progress-dialog.cpp index 582a05a1..0540779c 100644 --- a/src/ui/transfer-progress-dialog.cpp +++ b/src/ui/transfer-progress-dialog.cpp @@ -189,7 +189,7 @@ TransferItemsTableModel::TransferItemsTableModel(QObject* parent) } -#if defined(Q_OS_WIN32) +#if defined(Q_OS_WIN32) || defined(Q_OS_LINUX) void TransferItemsTableModel::setTransferItems() { TransferProgress transfer_progress; diff --git a/src/ui/tray-icon.cpp b/src/ui/tray-icon.cpp index 0126f15b..6abd0fb3 100644 --- a/src/ui/tray-icon.cpp +++ b/src/ui/tray-icon.cpp @@ -709,10 +709,12 @@ void SeafileTrayIcon::deleteAccount() } #endif +#ifndef Q_OS_LINUX if (rpc_client && rpc_client->isAccountUploading(account)) { gui->warningBox(tr("There are changes being uploaded under the account, please try again later")); return; } +#endif #if defined(Q_OS_WIN32) || defined(Q_OS_LINUX) QString question = tr("Are you sure to remove account from \"%1\"?").arg(account.serverUrl.toString()); @@ -739,11 +741,13 @@ void SeafileTrayIcon::resyncAccount() return; } +#ifndef Q_OS_LINUX bool is_uploading = rpc_client->isAccountUploading (account); if (is_uploading) { gui->warningBox (tr("There are changes being uploaded under the account, please try again later")); return; } +#endif QString question = tr("The account will be synced to a new sync root folder. Are you sure to resync account from \"%1\"?").arg(account.serverUrl.toString()); From 33727f6ed5ff8fef19438a5285316fcf8497a52e Mon Sep 17 00:00:00 2001 From: Heran Yang Date: Tue, 10 Dec 2024 10:52:10 +0800 Subject: [PATCH 3/4] Check if rpc is connected --- src/rpc/rpc-client.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/rpc/rpc-client.cpp b/src/rpc/rpc-client.cpp index 6fd28e8e..f3f10739 100644 --- a/src/rpc/rpc-client.cpp +++ b/src/rpc/rpc-client.cpp @@ -622,6 +622,11 @@ bool SeafileRpcClient::addAccount(const Account& account) #elif defined(Q_OS_LINUX) bool SeafileRpcClient::addAccount(const Account& account) { + if (!connected_) { + qWarning("Call searpc from disconnected client"); + return false; + } + GError *error = NULL; QString serverAddr = account.serverUrl.toEncoded().data(); if (serverAddr.endsWith("/")) { From 6f92c80dc492e6520adf095db39a4d874523e0b3 Mon Sep 17 00:00:00 2001 From: Heran Yang Date: Wed, 8 Jan 2025 16:09:39 +0800 Subject: [PATCH 4/4] Mkdir mount folder and check same username --- src/account-mgr.cpp | 12 +++++++++--- src/daemon-mgr.cpp | 5 +++++ src/seadrive-gui.cpp | 9 --------- src/ui/tray-icon.cpp | 8 +++++++- 4 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/account-mgr.cpp b/src/account-mgr.cpp index f16ed0ec..309b2e77 100644 --- a/src/account-mgr.cpp +++ b/src/account-mgr.cpp @@ -413,8 +413,6 @@ int AccountManager::resyncAccount(const Account& account) #if defined(Q_OS_WIN32) setAccountSyncRoot(updated_account); -#elif defined(Q_OS_LINUX) - setAccountDisplayName(updated_account); #endif SeafileRpcClient *rpc_client = gui->rpcClient(updated_account.domainID()); @@ -866,9 +864,17 @@ void AccountManager::setAccountDisplayName(Account &account) name = account.username; } QString displayName = name + "(" + account.serverUrl.host() + ")"; - account.displayName = displayName; + int j = 0; QMutexLocker locker(&accounts_mutex_); + for (size_t i = 0; i < accounts_.size(); i++) { + if (accounts_[i].displayName == displayName) { + j++; + name = QString("%1_%2").arg(name).arg(j); + displayName = name + "(" + account.serverUrl.host() + ")"; + } + } + account.displayName = displayName; for (size_t i = 0; i < accounts_.size(); i++) { if (accounts_.at(i) == account) { accounts_[i].displayName = displayName; diff --git a/src/daemon-mgr.cpp b/src/daemon-mgr.cpp index 591ceb21..2727bd49 100644 --- a/src/daemon-mgr.cpp +++ b/src/daemon-mgr.cpp @@ -189,6 +189,11 @@ QStringList DaemonManager::collectSeaDriveArgs() } else { args << fuse_opts.split(" "); } + + if (checkdir_with_mkdir(toCStr(gui->seadriveRoot())) < 0) { + gui->errorAndExit(tr("Failed to initialize: failed to create seadrive mount folder")); + return args; + } #endif auto stream = qWarning() << "starting seadrive daemon:" << kSeadriveExecutable; diff --git a/src/seadrive-gui.cpp b/src/seadrive-gui.cpp index 9c663b2d..75b152d9 100644 --- a/src/seadrive-gui.cpp +++ b/src/seadrive-gui.cpp @@ -554,9 +554,7 @@ void SeadriveGui::onDaemonStarted() message_poller->start(); message_pollers_.insert(EMPTY_DOMAIN_ID, message_poller); } -#if defined(Q_OS_WIN32) || defined(Q_OS_LINUX) rpc_client->connectDaemon(); -#endif auto accounts = account_mgr_->activeAccounts(); for (int i = 0; i < accounts.size(); i++) { @@ -820,13 +818,6 @@ bool SeadriveGui::initLog() QProcess::execute("fusermount", umount_arguments); #endif -#if defined(Q_OS_LINUX) - if (checkdir_with_mkdir(toCStr(seadriveRoot())) < 0) { - errorAndExit(tr("Failed to initialize: failed to create seadrive mount folder")); - return false; - } -#endif - if (applet_log_init(toCStr(seadrive_dir.absolutePath())) < 0) { errorAndExit(tr("Failed to initialize log: %1").arg(g_strerror(errno))); return false; diff --git a/src/ui/tray-icon.cpp b/src/ui/tray-icon.cpp index 6abd0fb3..0c1bfd2c 100644 --- a/src/ui/tray-icon.cpp +++ b/src/ui/tray-icon.cpp @@ -749,7 +749,13 @@ void SeafileTrayIcon::resyncAccount() } #endif - QString question = tr("The account will be synced to a new sync root folder. Are you sure to resync account from \"%1\"?").arg(account.serverUrl.toString()); +#if defined(Q_OS_WIN32) + QString question = tr("Are you sure to resync account from \"%1\"? Downloaded and uploading files will not be removed").arg(account.serverUrl.toString()); +#elif defined(Q_OS_MAC) + QString question = tr("Are you sure to resync account from \"%1\"? After resyncing account, you can still find downloaded files at ~/Library/CloudStorage.").arg(account.serverUrl.toString()); +#else + QString question = tr("Are you sure to resync account from \"%1\"? Downloaded and uploading files will not be removed").arg(account.serverUrl.toString()); +#endif if (!gui->yesOrNoBox(question, nullptr, false)) { return;