File indexing completed on 2023-11-26 08:17:49
0001 /* 0002 SPDX-FileCopyrightText: 2018-2023 Laurent Montel <montel@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "accountmanager.h" 0008 #include "localdatabase/localdatabaseutils.h" 0009 #include "managerdatapaths.h" 0010 #include "notificationhistorymanager.h" 0011 #include "notifications/notifierjob.h" 0012 #include "parsemessageurlutils.h" 0013 #include "ruqola_debug.h" 0014 #include "ruqolaglobalconfig.h" 0015 #include <KLocalizedString> 0016 #include <QDir> 0017 #include <QDirIterator> 0018 #include <QSettings> 0019 0020 AccountManager::AccountManager(QObject *parent) 0021 : QObject(parent) 0022 , mRocketChatAccountModel(new RocketChatAccountModel(this)) 0023 , mRocketChatAccountProxyModel(new RocketChatAccountFilterProxyModel(this)) 0024 { 0025 mRocketChatAccountProxyModel->setSourceModel(mRocketChatAccountModel); 0026 loadAccount(); 0027 } 0028 0029 AccountManager::~AccountManager() = default; 0030 0031 int AccountManager::accountNumber() const 0032 { 0033 return mRocketChatAccountModel->accountNumber(); 0034 } 0035 0036 bool AccountManager::showMessage(const ParseMessageUrlUtils &parseUrl) 0037 { 0038 auto account = mRocketChatAccountModel->accountFromServerUrl(parseUrl.serverHost()); 0039 if (account) { 0040 // const QString path{parseUrl.path()}; 0041 const QString messageId = parseUrl.messageId(); 0042 qCDebug(RUQOLA_LOG) << " parseUrl " << parseUrl; 0043 // https://<server url>/channel/python?msg=sn3gEQom7NcLxTg5h 0044 setCurrentAccount(account->accountName()); 0045 // qDebug() << " account->accountName() : " << account->accountName(); 0046 Q_EMIT mCurrentAccount->raiseWindow(); 0047 Q_EMIT mCurrentAccount->selectChannelAndMessage(messageId, parseUrl.roomId(), parseUrl.roomIdType(), parseUrl.channelType()); 0048 return true; 0049 } 0050 return false; 0051 } 0052 0053 void AccountManager::openMessageUrl(const QString &messageUrl) 0054 { 0055 ParseMessageUrlUtils parseUrl; 0056 if (parseUrl.parseUrl(messageUrl)) { 0057 if (showMessage(parseUrl)) { 0058 return; 0059 } 0060 } 0061 0062 Q_EMIT messageUrlNotFound(i18n("Server not found: %1", messageUrl)); 0063 // TODO report error 0064 } 0065 0066 void AccountManager::connectToAccount(RocketChatAccount *account) 0067 { 0068 connect(account, &RocketChatAccount::notification, this, [this, account](const NotificationInfo &info) { 0069 NotificationHistoryManager::self()->addNotification(info); 0070 0071 switch (info.notificationType()) { 0072 case NotificationInfo::StandardMessage: { 0073 auto job = new NotifierJob; 0074 job->setInfo(info); 0075 connect(job, &NotifierJob::switchToAccountAndRoomName, this, &AccountManager::slotSwitchToAccountAndRoomName); 0076 connect(job, &NotifierJob::sendReply, this, [account](const QString &str, const QString &roomId, const QString &tmId) { 0077 if (tmId.isEmpty()) { 0078 account->sendMessage(roomId, str); 0079 } else { 0080 account->replyOnThread(roomId, tmId, str); 0081 } 0082 // qDebug() << " str" << str << " Room Name " << roomName; 0083 }); 0084 job->start(); 0085 break; 0086 } 0087 case NotificationInfo::ConferenceCall: { 0088 break; 0089 } 0090 } 0091 }); 0092 connect(account, &RocketChatAccount::updateNotification, this, &AccountManager::updateNotification); 0093 connect(account, &RocketChatAccount::roomNeedAttention, this, &AccountManager::roomNeedAttention); 0094 connect(account, &RocketChatAccount::logoutDone, this, &AccountManager::logoutAccountDone); 0095 } 0096 0097 void AccountManager::slotSwitchToAccountAndRoomName(const QString &accountName, const QString &roomName, const QString &channelType) 0098 { 0099 setCurrentAccount(accountName); 0100 QString linkRoom; 0101 if (channelType == QLatin1Char('c')) { 0102 linkRoom = QStringLiteral("ruqola:/room/%1").arg(roomName); 0103 } else { 0104 linkRoom = QStringLiteral("ruqola:/user/%1").arg(roomName); 0105 } 0106 Q_EMIT mCurrentAccount->raiseWindow(); 0107 Q_EMIT mCurrentAccount->openLinkRequested(linkRoom); 0108 } 0109 0110 void AccountManager::loadAccount() 0111 { 0112 qCDebug(RUQOLA_LOG) << " void AccountManager::loadAccount()" << ManagerDataPaths::self()->path(ManagerDataPaths::Config, QString()); 0113 QDirIterator it(ManagerDataPaths::self()->path(ManagerDataPaths::Config, QString()), 0114 QStringList() << QStringLiteral("ruqola.conf"), 0115 QDir::AllEntries | QDir::NoSymLinks | QDir::NoDotAndDotDot, 0116 QDirIterator::Subdirectories); 0117 QVector<RocketChatAccount *> lstAccounts; 0118 while (it.hasNext()) { 0119 const QString val = it.next(); 0120 qCDebug(RUQOLA_LOG) << "Account found list.at(i)" << val; 0121 auto account = new RocketChatAccount(val); 0122 if (account->settings()->isValid()) { 0123 connectToAccount(account); 0124 lstAccounts.append(account); 0125 } else { 0126 account->deleteLater(); 0127 } 0128 } 0129 0130 // New account => empty list. 0131 if (lstAccounts.isEmpty()) { 0132 qCDebug(RUQOLA_LOG) << "Empty list. Create a default rocketchataccount"; 0133 auto account = new RocketChatAccount(); 0134 if (account->accountEnabled()) { 0135 connectToAccount(account); 0136 } 0137 lstAccounts.append(account); 0138 } 0139 0140 mRocketChatAccountModel->setAccounts(lstAccounts); 0141 0142 QSettings settings; 0143 const QString previousAccount = settings.value(QStringLiteral("currentAccount"), QString()).toString(); 0144 if (previousAccount.isEmpty()) { 0145 // Use first one 0146 mCurrentAccount = mRocketChatAccountModel->account(0); 0147 } else { 0148 selectAccount(previousAccount); 0149 if (!mCurrentAccount) { 0150 // Use first one 0151 mCurrentAccount = mRocketChatAccountModel->account(0); 0152 } 0153 } 0154 mRocketChatAccountProxyModel->setAccountOrder(RuqolaGlobalConfig::self()->accountOrder()); 0155 } 0156 0157 RocketChatAccountFilterProxyModel *AccountManager::rocketChatAccountProxyModel() const 0158 { 0159 return mRocketChatAccountProxyModel; 0160 } 0161 0162 RocketChatAccount *AccountManager::account() const 0163 { 0164 return mCurrentAccount; 0165 } 0166 0167 void AccountManager::addAccount(const AccountManagerInfo &info) 0168 { 0169 // TODO verify if account exist or not ? 0170 auto account = new RocketChatAccount(); 0171 account->setAccountName(info.accountName); 0172 account->setUserName(info.userName); 0173 account->setServerUrl(info.serverUrl); 0174 account->setAccountEnabled(info.enabled); 0175 account->setPassword(info.password); 0176 if (info.enabled) { 0177 connectToAccount(account); 0178 } 0179 addAccount(account); 0180 } 0181 0182 void AccountManager::modifyAccount(const AccountManagerInfo &info) 0183 { 0184 RocketChatAccount *account = mRocketChatAccountModel->account(info.accountName); 0185 if (account) { 0186 account->setDisplayName(info.displayName); 0187 account->setUserName(info.userName); 0188 account->setServerUrl(info.serverUrl); 0189 account->setAccountEnabled(info.enabled); 0190 if (!info.enabled) { 0191 // TODO fixme 0192 // disconnect(account, &RocketChatAccount::notification, this, &AccountManager::notification); 0193 disconnect(account, &RocketChatAccount::updateNotification, this, &AccountManager::updateNotification); 0194 disconnect(account, &RocketChatAccount::logoutDone, this, &AccountManager::logoutAccountDone); 0195 } 0196 } 0197 } 0198 0199 RocketChatAccount *AccountManager::accountFromName(const QString &accountName) 0200 { 0201 return mRocketChatAccountModel->account(accountName); 0202 } 0203 0204 QStringList AccountManager::accountsName() const 0205 { 0206 return mRocketChatAccountModel->accountsName(); 0207 } 0208 0209 void AccountManager::addAccount(RocketChatAccount *account) 0210 { 0211 mRocketChatAccountModel->insertAccount(account); 0212 } 0213 0214 void AccountManager::selectAccount(const QString &accountName) 0215 { 0216 RocketChatAccount *account = mRocketChatAccountModel->account(accountName); 0217 if (account) { 0218 mCurrentAccount = account; 0219 } else { 0220 qCWarning(RUQOLA_LOG) << "AccountName " << accountName << " is not found on system."; 0221 } 0222 } 0223 0224 void AccountManager::setCurrentAccount(const QString &accountName) 0225 { 0226 RocketChatAccount *account = mRocketChatAccountModel->account(accountName); 0227 if (account) { 0228 if (mCurrentAccount != account) { 0229 QSettings settings; 0230 settings.setValue(QStringLiteral("currentAccount"), accountName); 0231 settings.sync(); 0232 mCurrentAccount = account; 0233 Q_EMIT currentAccountChanged(); 0234 } 0235 } else { 0236 qCWarning(RUQOLA_LOG) << "AccountName " << accountName << " is not found on system. Fallback to default one."; 0237 } 0238 } 0239 0240 QString AccountManager::currentAccount() const 0241 { 0242 return mCurrentAccount ? mCurrentAccount->accountName() : QString(); 0243 } 0244 0245 void AccountManager::removeLogs(const QString &accountName) 0246 { 0247 const QString directory = LocalDatabaseUtils::localMessageLoggerPath() + accountName; 0248 removeDirectory(directory); 0249 } 0250 0251 void AccountManager::removeDatabaseAccount(const QString &accountName) 0252 { 0253 const QString directory = LocalDatabaseUtils::localAccountDatabasePath() + accountName; 0254 removeDirectory(directory); 0255 } 0256 0257 void AccountManager::removeDirectory(const QString &directory) 0258 { 0259 QDir dir(directory); 0260 if (dir.exists()) { 0261 if (!dir.removeRecursively()) { 0262 qCWarning(RUQOLA_LOG) << " Impossible to remove directory : " << directory; 0263 } 0264 } 0265 } 0266 0267 void AccountManager::removeAccount(const QString &accountName, bool removeLogFiles) 0268 { 0269 auto account = mRocketChatAccountModel->removeAccount(accountName); 0270 if (mRocketChatAccountModel->accountNumber() > 0) { 0271 mCurrentAccount = mRocketChatAccountModel->account(0); 0272 removeDatabaseAccount(accountName); 0273 // TODO remove others files 0274 if (removeLogFiles) { 0275 removeLogs(accountName); 0276 } 0277 } else { 0278 // TODO create new dummy account ! 0279 } 0280 Q_EMIT currentAccountChanged(); 0281 if (account) { 0282 account->deleteLater(); 0283 } 0284 } 0285 0286 RocketChatAccountModel *AccountManager::rocketChatAccountModel() const 0287 { 0288 return mRocketChatAccountModel; 0289 } 0290 0291 QStringList AccountManager::accountNamesSorted() const 0292 { 0293 QStringList lst; 0294 auto model = rocketChatAccountProxyModel(); 0295 for (int i = 0; i < model->rowCount(); ++i) { 0296 const auto index = model->index(i, 0); 0297 auto account = index.data(RocketChatAccountModel::Account).value<RocketChatAccount *>(); 0298 lst << account->displayName(); 0299 } 0300 return lst; 0301 } 0302 0303 #include "moc_accountmanager.cpp"