File indexing completed on 2024-11-17 04:55:41
0001 /* 0002 * SPDX-FileCopyrightText: 2012 Aleix Pol Gonzalez <aleixpol@blue-systems.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 */ 0006 0007 #include "KNSReviews.h" 0008 #include "KNSBackend.h" 0009 #include "KNSResource.h" 0010 #include <KLocalizedString> 0011 #include <KNSCore/EngineBase> 0012 #include <KPasswordDialog> 0013 #include <QDebug> 0014 #include <QDesktopServices> 0015 #include <ReviewsBackend/Rating.h> 0016 #include <ReviewsBackend/Review.h> 0017 #include <attica/content.h> 0018 #include <attica/providermanager.h> 0019 #include <resources/AbstractResource.h> 0020 0021 KNSReviews::KNSReviews(KNSBackend *backend) 0022 : AbstractReviewsBackend(backend) 0023 , m_backend(backend) 0024 { 0025 } 0026 0027 Rating *KNSReviews::ratingForApplication(AbstractResource *resource) const 0028 { 0029 KNSResource *knsResource = qobject_cast<KNSResource *>(resource); 0030 if (!knsResource) { 0031 qDebug() << resource->packageName() << "<= couldn't find resource"; 0032 return nullptr; 0033 } 0034 0035 return knsResource->ratingInstance(); 0036 } 0037 0038 void KNSReviews::fetchReviews(AbstractResource *resource, int page) 0039 { 0040 const auto job = provider().requestComments(Attica::Comment::ContentComment, resource->packageName(), QStringLiteral("0"), page - 1, 10); 0041 if (!job) { 0042 Q_EMIT reviewsReady(resource, {}, false); 0043 return; 0044 } 0045 job->setProperty("app", QVariant::fromValue(resource)); 0046 connect(job, &Attica::BaseJob::finished, this, &KNSReviews::commentsReceived); 0047 job->start(); 0048 acquireFetching(true); 0049 } 0050 0051 void KNSReviews::acquireFetching(bool fetching) 0052 { 0053 if (fetching) { 0054 m_fetching++; 0055 } else { 0056 m_fetching--; 0057 } 0058 0059 if ((!fetching && m_fetching == 0) || (fetching && m_fetching == 1)) { 0060 Q_EMIT fetchingChanged(m_fetching != 0); 0061 } 0062 Q_ASSERT(m_fetching >= 0); 0063 } 0064 0065 static QVector<ReviewPtr> createReviewList(AbstractResource *resource, const Attica::Comment::List comments, int depth = 0) 0066 { 0067 QVector<ReviewPtr> reviews; 0068 for (const Attica::Comment &comment : comments) { 0069 // TODO: language lookup? 0070 ReviewPtr r(new Review(resource->name(), 0071 resource->packageName(), 0072 QStringLiteral("en"), 0073 comment.subject(), 0074 comment.text(), 0075 comment.user(), 0076 comment.date(), 0077 true, 0078 comment.id().toInt(), 0079 comment.score() / 10, 0080 0, 0081 0, 0082 0.0, 0083 QString())); 0084 r->addMetadata(QStringLiteral("NumberOfParents"), depth); 0085 reviews += r; 0086 if (comment.childCount() > 0) { 0087 reviews += createReviewList(resource, comment.children(), depth + 1); 0088 } 0089 } 0090 return reviews; 0091 } 0092 0093 void KNSReviews::commentsReceived(Attica::BaseJob *j) 0094 { 0095 acquireFetching(false); 0096 const auto job = static_cast<Attica::ListJob<Attica::Comment> *>(j); 0097 0098 const auto app = job->property("app").value<AbstractResource *>(); 0099 QVector<ReviewPtr> reviews = createReviewList(app, job->itemList()); 0100 0101 Q_EMIT reviewsReady(app, reviews, !reviews.isEmpty()); 0102 } 0103 0104 bool KNSReviews::isFetching() const 0105 { 0106 return m_fetching > 0; 0107 } 0108 0109 void KNSReviews::flagReview(Review * /*r*/, const QString & /*reason*/, const QString & /*text*/) 0110 { 0111 qWarning() << "cannot flag reviews"; 0112 } 0113 0114 void KNSReviews::deleteReview(Review * /*r*/) 0115 { 0116 qWarning() << "cannot delete comments"; 0117 } 0118 0119 void KNSReviews::sendReview(AbstractResource *resource, const QString &summary, const QString &reviewText, const QString &rating, const QString &userName) 0120 { 0121 Q_UNUSED(userName); 0122 provider().voteForContent(resource->packageName(), rating.toUInt() * 20); 0123 if (!summary.isEmpty()) { 0124 provider().addNewComment(Attica::Comment::ContentComment, resource->packageName(), QString(), QString(), summary, reviewText); 0125 } 0126 } 0127 0128 void KNSReviews::submitUsefulness(Review *review, bool useful) 0129 { 0130 provider().voteForComment(QString::number(review->id()), useful * 5); 0131 } 0132 0133 void KNSReviews::logout() 0134 { 0135 bool ok = provider().saveCredentials(QString(), QString()); 0136 if (!ok) { 0137 qWarning() << "couldn't log out"; 0138 } 0139 } 0140 0141 void KNSReviews::registerAndLogin() 0142 { 0143 QDesktopServices::openUrl(provider().baseUrl()); 0144 } 0145 0146 void KNSReviews::login() 0147 { 0148 const auto dialog = new KPasswordDialog; 0149 dialog->setPrompt(i18n("Log in information for %1", provider().name())); 0150 connect(dialog, &KPasswordDialog::gotUsernameAndPassword, this, &KNSReviews::credentialsReceived); 0151 } 0152 0153 void KNSReviews::credentialsReceived(const QString &user, const QString &password) 0154 { 0155 bool ok = provider().saveCredentials(user, password); 0156 if (!ok) { 0157 qWarning() << "couldn't save" << user << "credentials for" << provider().name(); 0158 } 0159 } 0160 0161 bool KNSReviews::hasCredentials() const 0162 { 0163 return provider().hasCredentials(); 0164 } 0165 0166 QString KNSReviews::userName() const 0167 { 0168 QString user, password; 0169 provider().loadCredentials(user, password); 0170 return user; 0171 } 0172 0173 Attica::Provider KNSReviews::provider() const 0174 { 0175 if (m_backend->engine()->atticaProviders().isEmpty()) { 0176 return {}; 0177 } 0178 return *m_backend->engine()->atticaProviders().constFirst(); 0179 } 0180 0181 bool KNSReviews::isResourceSupported(AbstractResource *resource) const 0182 { 0183 return qobject_cast<KNSResource *>(resource); 0184 }