File indexing completed on 2024-09-15 04:25:27
0001 /* 0002 This file is part of Choqok, the KDE micro-blogging client 0003 0004 SPDX-FileCopyrightText: 2010-2012 Mehrdad Momeny <mehrdad.momeny@gmail.com> 0005 0006 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0007 */ 0008 0009 #include "ocsmicroblog.h" 0010 0011 #include <KLocalizedString> 0012 #include <KMessageBox> 0013 #include <KPluginFactory> 0014 #include <KConfig> 0015 0016 #include <Attica/ProviderManager> 0017 0018 #include "application.h" 0019 #include "accountmanager.h" 0020 #include "editaccountwidget.h" 0021 #include "postwidget.h" 0022 0023 #include "ocsaccount.h" 0024 #include "ocsdebug.h" 0025 #include "ocsconfigurewidget.h" 0026 0027 K_PLUGIN_CLASS_WITH_JSON(OCSMicroblog, "choqok_ocs.json") 0028 0029 OCSMicroblog::OCSMicroblog(QObject *parent, const QVariantList &) 0030 : MicroBlog(QLatin1String("choqok_ocs"), parent) 0031 , mProviderManager(new Attica::ProviderManager) 0032 , mIsOperational(false) 0033 { 0034 connect(mProviderManager, &Attica::ProviderManager::defaultProvidersLoaded, 0035 this, &OCSMicroblog::slotDefaultProvidersLoaded); 0036 mProviderManager->loadDefaultProviders(); 0037 setServiceName(QLatin1String("Social Desktop Activities")); 0038 } 0039 0040 OCSMicroblog::~OCSMicroblog() 0041 { 0042 delete mProviderManager; 0043 } 0044 0045 void OCSMicroblog::saveTimeline(Choqok::Account *account, const QString &timelineName, 0046 const QList< Choqok::UI::PostWidget * > &timeline) 0047 { 0048 qCDebug(CHOQOK); 0049 QString fileName = Choqok::AccountManager::generatePostBackupFileName(account->alias(), timelineName); 0050 KConfig postsBackup(fileName, KConfig::NoGlobals, QStandardPaths::DataLocation); 0051 0052 ///Clear previous data: 0053 for (const QString &group: postsBackup.groupList()) { 0054 postsBackup.deleteGroup(group); 0055 } 0056 0057 for (Choqok::UI::PostWidget *wd: timeline) { 0058 const Choqok::Post *post = wd->currentPost(); 0059 KConfigGroup grp(&postsBackup, post->creationDateTime.toString()); 0060 grp.writeEntry("creationDateTime", post->creationDateTime); 0061 grp.writeEntry("postId", post->postId); 0062 grp.writeEntry("text", post->content); 0063 grp.writeEntry("authorId", post->author.userId); 0064 grp.writeEntry("authorUserName", post->author.userName); 0065 grp.writeEntry("authorRealName", post->author.realName); 0066 grp.writeEntry("authorProfileImageUrl", post->author.profileImageUrl); 0067 grp.writeEntry("authorDescription" , post->author.description); 0068 grp.writeEntry("authorLocation" , post->author.location); 0069 grp.writeEntry("authorUrl" , post->author.homePageUrl); 0070 grp.writeEntry("link", post->link); 0071 grp.writeEntry("isRead" , post->isRead); 0072 } 0073 postsBackup.sync(); 0074 if (Choqok::Application::isShuttingDown()) { 0075 Q_EMIT readyForUnload(); 0076 } 0077 } 0078 0079 QList< Choqok::Post * > OCSMicroblog::loadTimeline(Choqok::Account *account, const QString &timelineName) 0080 { 0081 qCDebug(CHOQOK) << timelineName; 0082 QList< Choqok::Post * > list; 0083 QString fileName = Choqok::AccountManager::generatePostBackupFileName(account->alias(), timelineName); 0084 KConfig postsBackup(fileName, KConfig::NoGlobals, QStandardPaths::DataLocation); 0085 QStringList tmpList = postsBackup.groupList(); 0086 0087 QList<QDateTime> groupList; 0088 for (const QString &str: tmpList) { 0089 groupList.append(QDateTime::fromString(str)); 0090 } 0091 std::sort(groupList.begin(), groupList.end()); 0092 int count = groupList.count(); 0093 if (count) { 0094 Choqok::Post *st = nullptr; 0095 for (int i = 0; i < count; ++i) { 0096 st = new Choqok::Post; 0097 KConfigGroup grp(&postsBackup, groupList[i].toString()); 0098 st->creationDateTime = grp.readEntry("creationDateTime", QDateTime::currentDateTime()); 0099 st->postId = grp.readEntry("postId", QString()); 0100 st->content = grp.readEntry("text", QString()); 0101 st->author.userId = grp.readEntry("authorId", QString()); 0102 st->author.userName = grp.readEntry("authorUserName", QString()); 0103 st->author.realName = grp.readEntry("authorRealName", QString()); 0104 st->author.profileImageUrl = grp.readEntry("authorProfileImageUrl", QUrl()); 0105 st->author.description = grp.readEntry("authorDescription" , QString()); 0106 st->author.location = grp.readEntry("authorLocation", QString()); 0107 st->author.homePageUrl = grp.readEntry("authorUrl", QUrl()); 0108 st->link = grp.readEntry("link", QUrl()); 0109 st->isRead = grp.readEntry("isRead", true); 0110 0111 list.append(st); 0112 } 0113 } 0114 return list; 0115 } 0116 0117 Choqok::Account *OCSMicroblog::createNewAccount(const QString &alias) 0118 { 0119 OCSAccount *acc = qobject_cast<OCSAccount *>(Choqok::AccountManager::self()->findAccount(alias)); 0120 if (!acc) { 0121 return new OCSAccount(this, alias); 0122 } else { 0123 return nullptr;//If there's an account with this alias, So We can't create a new one 0124 } 0125 } 0126 0127 ChoqokEditAccountWidget *OCSMicroblog::createEditAccountWidget(Choqok::Account *account, QWidget *parent) 0128 { 0129 qCDebug(CHOQOK); 0130 OCSAccount *acc = qobject_cast<OCSAccount *>(account); 0131 if (acc || !account) { 0132 return new OCSConfigureWidget(this, acc, parent); 0133 } else { 0134 qCDebug(CHOQOK) << "Account passed here was not a valid OCSAccount!"; 0135 return nullptr; 0136 } 0137 } 0138 0139 void OCSMicroblog::createPost(Choqok::Account *theAccount, Choqok::Post *post) 0140 { 0141 if (!mIsOperational) { 0142 Q_EMIT errorPost(theAccount, post, OtherError, i18n("OCS plugin is not initialized yet. Try again later.")); 0143 return; 0144 } 0145 qCDebug(CHOQOK); 0146 OCSAccount *acc = qobject_cast<OCSAccount *>(theAccount); 0147 Attica::PostJob *job = acc->provider().postActivity(post->content); 0148 mJobsAccount.insert(job, acc); 0149 mJobsPost.insert(job, post); 0150 connect(job, &Attica::PostJob::finished, this, 0151 &OCSMicroblog::slotCreatePost); 0152 job->start(); 0153 } 0154 0155 void OCSMicroblog::slotCreatePost(Attica::BaseJob *job) 0156 { 0157 OCSAccount *acc = mJobsAccount.take(job); 0158 Choqok::Post *post = mJobsPost.take(job); 0159 Q_EMIT postCreated(acc, post); 0160 } 0161 0162 void OCSMicroblog::abortCreatePost(Choqok::Account *theAccount, Choqok::Post *post) 0163 { 0164 qCDebug(CHOQOK); 0165 Q_UNUSED(post); 0166 OCSAccount *acc = qobject_cast<OCSAccount *>(theAccount); 0167 Attica::BaseJob *job = mJobsAccount.key(acc); 0168 if (job) { 0169 job->abort(); 0170 } 0171 } 0172 0173 void OCSMicroblog::fetchPost(Choqok::Account *theAccount, Choqok::Post *post) 0174 { 0175 Q_UNUSED(theAccount); 0176 Q_UNUSED(post); 0177 KMessageBox::error(choqokMainWindow, i18n("Not Supported")); 0178 } 0179 0180 void OCSMicroblog::removePost(Choqok::Account *theAccount, Choqok::Post *post) 0181 { 0182 Q_UNUSED(theAccount); 0183 Q_UNUSED(post); 0184 KMessageBox::error(choqokMainWindow, i18n("Not Supported")); 0185 } 0186 0187 Attica::ProviderManager *OCSMicroblog::providerManager() 0188 { 0189 return mProviderManager; 0190 } 0191 0192 void OCSMicroblog::updateTimelines(Choqok::Account *theAccount) 0193 { 0194 if (!mIsOperational) { 0195 scheduledTasks.insertMulti(theAccount, Update); 0196 return; 0197 } 0198 qCDebug(CHOQOK); 0199 OCSAccount *acc = qobject_cast<OCSAccount *>(theAccount); 0200 if (!acc) { 0201 qCCritical(CHOQOK) << "OCSMicroblog::updateTimelines: acc is not an OCSAccount"; 0202 return; 0203 } 0204 Attica::ListJob <Attica::Activity> *job = acc->provider().requestActivities(); 0205 mJobsAccount.insert(job, acc); 0206 connect(job, &Attica::BaseJob::finished, this, &OCSMicroblog::slotTimelineLoaded); 0207 job->start(); 0208 } 0209 0210 void OCSMicroblog::slotTimelineLoaded(Attica::BaseJob *job) 0211 { 0212 qCDebug(CHOQOK); 0213 OCSAccount *acc = mJobsAccount.take(job); 0214 if (job->metadata().error() == Attica::Metadata::NoError) { 0215 Attica::Activity::List actList = static_cast< Attica::ListJob<Attica::Activity> * >(job)->itemList(); 0216 Q_EMIT timelineDataReceived(acc, QLatin1String("Activity"), parseActivityList(actList)); 0217 } else { 0218 Q_EMIT error(acc, ServerError, job->metadata().message(), Low); 0219 } 0220 } 0221 0222 QList< Choqok::Post * > OCSMicroblog::parseActivityList(const Attica::Activity::List &list) 0223 { 0224 qCDebug(CHOQOK) << list.count(); 0225 QList< Choqok::Post * > resultList; 0226 for (const Attica::Activity &act: list) { 0227 Choqok::Post *pst = new Choqok::Post; 0228 pst->postId = act.id(); 0229 pst->content = act.message(); 0230 pst->creationDateTime = act.timestamp(); 0231 pst->link = act.link(); 0232 pst->isError = !act.isValid(); 0233 pst->author.userId = act.associatedPerson().id(); 0234 pst->author.userName = act.associatedPerson().id(); 0235 pst->author.homePageUrl = QUrl::fromUserInput(act.associatedPerson().homepage()); 0236 pst->author.location = QStringLiteral("%1(%2)").arg(act.associatedPerson().country()) 0237 .arg(act.associatedPerson().city()); 0238 pst->author.profileImageUrl = act.associatedPerson().avatarUrl(); 0239 pst->author.realName = QStringLiteral("%1 %2").arg(act.associatedPerson().firstName()) 0240 .arg(act.associatedPerson().lastName()); 0241 resultList.insert(0, pst); 0242 } 0243 return resultList; 0244 } 0245 0246 Choqok::TimelineInfo *OCSMicroblog::timelineInfo(const QString &timelineName) 0247 { 0248 if (timelineName == QLatin1String("Activity")) { 0249 Choqok::TimelineInfo *info = new Choqok::TimelineInfo; 0250 info->name = i18nc("Timeline Name", "Activity"); 0251 info->description = i18n("Social activities"); 0252 info->icon = QLatin1String("user-home"); 0253 return info; 0254 } else { 0255 qCCritical(CHOQOK) << "timelineName is not valid!"; 0256 return nullptr; 0257 } 0258 } 0259 0260 bool OCSMicroblog::isOperational() 0261 { 0262 return mIsOperational; 0263 } 0264 0265 void OCSMicroblog::slotDefaultProvidersLoaded() 0266 { 0267 qCDebug(CHOQOK); 0268 mIsOperational = true; 0269 Q_EMIT initialized(); 0270 0271 for (Choqok::Account *acc: scheduledTasks.keys()) { 0272 switch (scheduledTasks.value(acc)) { 0273 case Update: 0274 updateTimelines(acc); 0275 break; 0276 default: 0277 break; 0278 }; 0279 } 0280 } 0281 0282 QUrl OCSMicroblog::profileUrl(Choqok::Account *account, const QString &username) const 0283 { 0284 OCSAccount *acc = qobject_cast<OCSAccount *>(account); 0285 if (acc->providerUrl().host().contains(QLatin1String("opendesktop.org"))) { 0286 return QUrl::fromUserInput(QStringLiteral("https://opendesktop.org/usermanager/search.php?username=%1").arg(username)); 0287 } 0288 return QUrl(); 0289 } 0290 0291 void OCSMicroblog::aboutToUnload() 0292 { 0293 Q_EMIT saveTimelines(); 0294 } 0295 0296 #include "moc_ocsmicroblog.cpp" 0297 #include "ocsmicroblog.moc"