[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: =?utf-8?q?=5Bmuon=5D_installer=3A_Add_initial_backend_support_fo?=
From: Jonathan Thomas <echidnaman () kubuntu ! org>
Date: 2011-02-25 18:23:51
Message-ID: 20110225182351.83E33A609B () git ! kde ! org
[Download RAW message or body]
Git commit bca00f81020d8f03a75c66c32d077378c34e017b by Jonathan Thomas.
Committed on 25/02/2011 at 19:22.
Pushed by jmthomas into branch 'master'.
Add initial backend support for the Ubuntu application reviews API. (No review GUI just yet, that's next)
M +12 -3 installer/ApplicationDetailsView/ApplicationDetailsWidget.cpp
M +2 -0 installer/ApplicationDetailsView/ApplicationDetailsWidget.h
M +1 -0 installer/CMakeLists.txt
A +98 -0 installer/ReviewsBackend/Review.cpp [License: GPL (v2/3)]
A +59 -0 installer/ReviewsBackend/Review.h [License: GPL (v2/3)]
M +99 -0 installer/ReviewsBackend/ReviewsBackend.cpp
M +12 -0 installer/ReviewsBackend/ReviewsBackend.h
http://commits.kde.org/muon/bca00f81020d8f03a75c66c32d077378c34e017b
diff --git a/installer/ApplicationDetailsView/ApplicationDetailsWidget.cpp \
b/installer/ApplicationDetailsView/ApplicationDetailsWidget.cpp index 1ce7166..d93fb76 100644
--- a/installer/ApplicationDetailsView/ApplicationDetailsWidget.cpp
+++ b/installer/ApplicationDetailsView/ApplicationDetailsWidget.cpp
@@ -66,6 +66,7 @@
#include "effects/GraphicsOpacityDropShadowEffect.h"
#include "ScreenShotViewer.h"
#include "ReviewsBackend/Rating.h"
+#include "ReviewsBackend/Review.h"
#include "ReviewsBackend/ReviewsBackend.h"
#include "../../libmuon/MuonStrings.h"
@@ -305,8 +306,6 @@ void ApplicationDetailsWidget::setApplication(Application *app)
{
m_app = app;
- //kDebug() << m_appBackend->reviewsBackend()->ratingForApplication(app)->rating();
-
// FIXME: Always keep label size at 48x48, and render the largest size
// we can up to that point. Otherwise some icons will be blurry
m_iconLabel->setPixmap(KIcon(app->icon()).pixmap(48,48));
@@ -314,7 +313,8 @@ void ApplicationDetailsWidget::setApplication(Application *app)
m_nameLabel->setText(QLatin1Literal("<h1>") % app->name() % QLatin1Literal("</h1>"));
m_shortDescLabel->setText(app->comment());
- Rating *rating = m_appBackend->reviewsBackend()->ratingForApplication(app);
+ ReviewsBackend *reviewsBackend = m_appBackend->reviewsBackend();
+ Rating *rating = reviewsBackend->ratingForApplication(app);
if (rating) {
m_ratingWidget->setRating(rating->rating());
m_ratingCountLabel->setText(i18ncp("@label The number of ratings the app has",
@@ -349,6 +349,11 @@ void ApplicationDetailsWidget::setApplication(Application *app)
populateAddons();
+ // Fetch reviews
+ reviewsBackend->fetchReviews(app);
+ connect(reviewsBackend, SIGNAL(reviewsReady(Application *, QList<Review *>)),
+ this, SLOT(populateReviews(Application *, QList<Review *>)));
+
QString homepageUrl = app->package()->homepage();
if (!homepageUrl.isEmpty()) {
QString websiteString = i18nc("@label visible text for an app's URL", "Website");
@@ -735,6 +740,10 @@ void ApplicationDetailsWidget::populateAddons()
m_addonsApplyButton->setEnabled(false);
}
+void ApplicationDetailsWidget::populateReviews(Application *app, const QList<Review *> &reviews)
+{
+}
+
void ApplicationDetailsWidget::addonStateChanged(const QModelIndex &left, const QModelIndex &right)
{
Q_UNUSED(right);
diff --git a/installer/ApplicationDetailsView/ApplicationDetailsWidget.h \
b/installer/ApplicationDetailsView/ApplicationDetailsWidget.h index a3d135f..b63e3be 100644
--- a/installer/ApplicationDetailsView/ApplicationDetailsWidget.h
+++ b/installer/ApplicationDetailsView/ApplicationDetailsWidget.h
@@ -46,6 +46,7 @@ class KTemporaryFile;
class Application;
class ClickableLabel;
+class Review;
class ScreenShotViewer;
// Widget for showing details about a single application
@@ -110,6 +111,7 @@ private Q_SLOTS:
void actionButtonClicked();
void cancelButtonClicked();
void populateAddons();
+ void populateReviews(Application *app, const QList<Review *> &reviews);
void addonStateChanged(const QModelIndex &left, const QModelIndex &right);
void addonsApplyButtonClicked();
void addonsRevertButtonClicked();
diff --git a/installer/CMakeLists.txt b/installer/CMakeLists.txt
index b594ad9..7e9a337 100644
--- a/installer/CMakeLists.txt
+++ b/installer/CMakeLists.txt
@@ -28,6 +28,7 @@ set(muon_installer_SRCS
ScreenShotViewer.cpp
Transaction.cpp
ReviewsBackend/Rating.cpp
+ ReviewsBackend/Review.cpp
ReviewsBackend/ReviewsBackend.cpp)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/ApplicationDetailsView/HaveQZeitgeist.h.in
diff --git a/installer/ReviewsBackend/Review.cpp b/installer/ReviewsBackend/Review.cpp
new file mode 100644
index 0000000..fa2974f
--- /dev/null
+++ b/installer/ReviewsBackend/Review.cpp
@@ -0,0 +1,98 @@
+/***************************************************************************
+ * Copyright © 2011 Jonathan Thomas <echidnaman@kubuntu.org> *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU General Public License as *
+ * published by the Free Software Foundation; either version 2 of *
+ * the License or (at your option) version 3 or any later version *
+ * accepted by the membership of KDE e.V. (or its successor approved *
+ * by the membership of KDE e.V.), which shall act as a proxy *
+ * defined in Section 14 of version 3 of the license. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. *
+ ***************************************************************************/
+
+#include "Review.h"
+
+Review::Review(const QVariantMap &data)
+{
+ m_appName = data.value("app_name").toString();
+ m_packageName = data.value("package_name").toString();
+ m_packageVersion = data.value("version").toString();
+ m_language = data.value("language").toString();
+ m_summary = data.value("summary").toString();
+ m_reviewText = data.value("review_text").toString();
+ m_reviewer = data.value("reviewer_username").toString();
+
+ QString creationDate = data.value("date_created").toString();
+ m_creationDate = QDateTime::fromString(creationDate, "yyyy-MM-dd HH:mm:ss");
+
+ m_shouldShow = !data.value("hide").toBool();
+ m_id = data.value("id").toULongLong();
+ m_rating = data.value("rating").toInt() * 2;
+}
+
+Review::~Review()
+{
+}
+
+QString Review::applicationName() const
+{
+ return m_appName;
+}
+
+QString Review::packageName() const
+{
+ return m_packageName;
+}
+
+QString Review::packageVersion() const
+{
+ return m_packageVersion;
+}
+
+QString Review::language() const
+{
+ return m_language;
+}
+
+QString Review::summary() const
+{
+ return m_summary;
+}
+
+QString Review::reviewText() const
+{
+ return m_reviewText;
+}
+
+QString Review::reviewer() const
+{
+ return m_reviewer;
+}
+
+QDateTime Review::creationDate() const
+{
+ return m_creationDate;
+}
+
+bool Review::shouldShow() const
+{
+ return m_shouldShow;
+}
+
+quint64 Review::id() const
+{
+ return m_id;
+}
+
+int Review::rating() const
+{
+ return m_rating;
+}
diff --git a/installer/ReviewsBackend/Review.h b/installer/ReviewsBackend/Review.h
new file mode 100644
index 0000000..aabe54d
--- /dev/null
+++ b/installer/ReviewsBackend/Review.h
@@ -0,0 +1,59 @@
+/***************************************************************************
+ * Copyright © 2011 Jonathan Thomas <echidnaman@kubuntu.org> *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU General Public License as *
+ * published by the Free Software Foundation; either version 2 of *
+ * the License or (at your option) version 3 or any later version *
+ * accepted by the membership of KDE e.V. (or its successor approved *
+ * by the membership of KDE e.V.), which shall act as a proxy *
+ * defined in Section 14 of version 3 of the license. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. *
+ ***************************************************************************/
+
+#ifndef REVIEW_H
+#define REVIEW_H
+
+#include <QtCore/QDateTime>
+#include <QtCore/QVariant>
+
+class Review
+{
+public:
+ explicit Review(const QVariantMap &data);
+ ~Review();
+
+ QString applicationName() const;
+ QString packageName() const;
+ QString packageVersion() const;
+ QString language() const;
+ QString summary() const;
+ QString reviewText() const;
+ QString reviewer() const;
+ QDateTime creationDate() const;
+ bool shouldShow() const;
+ quint64 id() const;
+ int rating() const;
+
+private:
+ QString m_appName;
+ QDateTime m_creationDate;
+ bool m_shouldShow;
+ quint64 m_id;
+ QString m_language;
+ QString m_packageName;
+ int m_rating;
+ QString m_reviewText;
+ QString m_reviewer;
+ QString m_summary;
+ QString m_packageVersion;
+};
+
+#endif
diff --git a/installer/ReviewsBackend/ReviewsBackend.cpp b/installer/ReviewsBackend/ReviewsBackend.cpp
index e0d4175..cfe336b 100644
--- a/installer/ReviewsBackend/ReviewsBackend.cpp
+++ b/installer/ReviewsBackend/ReviewsBackend.cpp
@@ -20,9 +20,12 @@
#include "ReviewsBackend.h"
+#include <QtCore/QProcess>
#include <QtCore/QStringBuilder>
+#include <KGlobal>
#include <KIO/Job>
+#include <KLocale>
#include <KTemporaryFile>
#include <KUrl>
#include <KDebug>
@@ -31,11 +34,13 @@
#include "../Application.h"
#include "Rating.h"
+#include "Review.h"
ReviewsBackend::ReviewsBackend(QObject *parent)
: QObject(parent)
, m_serverBase("http://reviews.staging.ubuntu.com/reviews/api/1.0/")
, m_ratingsFile(0)
+ , m_reviewsFile(0)
{
fetchRatings();
}
@@ -107,3 +112,97 @@ Rating *ReviewsBackend::ratingForApplication(Application *app) const
return 0;
}
+void ReviewsBackend::fetchReviews(Application *app)
+{
+ // Check our cache before fetching from the 'net
+ QString hashName = app->package()->latin1Name() + app->name();
+ if (m_reviewsCache.contains(hashName)) {
+ emit reviewsReady(app, m_reviewsCache.value(hashName));
+ return;
+ }
+
+ QString lang = getLanguage();
+ QString origin = QLatin1String("any");
+
+ QString program = QLatin1String("lsb_release -c -s");
+ QProcess lsb_release;
+ lsb_release.start(program);
+ lsb_release.waitForFinished();
+ QString distroSeries = lsb_release.readAllStandardOutput();
+ distroSeries = distroSeries.trimmed();
+
+ QString version = QLatin1String("any");
+ QString packageName = app->package()->latin1Name();
+ QString appName = ';' + app->name();
+ appName.replace(' ', QLatin1String("%2B"));
+
+ KUrl reviewsUrl(m_serverBase % lang % '/' % origin % '/' % distroSeries %
+ '/' % version % '/' % packageName % appName % '/' %
+ QLatin1Literal("page") % '/' % '1');
+ kDebug() << reviewsUrl;
+
+ if (m_reviewsFile) {
+ m_reviewsFile->deleteLater();
+ m_reviewsFile = 0;
+ }
+
+ m_reviewsFile = new KTemporaryFile();
+ m_reviewsFile->open();
+
+ KIO::FileCopyJob *getJob = KIO::file_copy(reviewsUrl,
+ m_reviewsFile->fileName(), -1,
+ KIO::Overwrite | KIO::HideProgressInfo);
+ m_jobHash[getJob] = app;
+ connect(getJob, SIGNAL(result(KJob *)),
+ this, SLOT(reviewsFetched(KJob *)));
+}
+
+void ReviewsBackend::reviewsFetched(KJob *job)
+{
+ if (job->error()) {
+ return;
+ }
+
+ QFile file(m_reviewsFile->fileName());
+ file.open(QIODevice::ReadOnly | QIODevice::Text);
+
+ QJson::Parser parser;
+ QByteArray json = file.readAll();
+
+ bool ok = false;
+ QVariant reviews = parser.parse(json, &ok);
+
+ if (!ok) {
+ return;
+ }
+
+ QList<Review *> reviewsList;
+ foreach (const QVariant &data, reviews.toList()) {
+ Review *review = new Review(data.toMap());
+ kDebug() << "Summary:" << review->summary();
+ reviewsList << review;
+ }
+
+ Application *app = m_jobHash.value(job);
+ m_jobHash.remove(job);
+
+ m_reviewsCache[app->package()->latin1Name() + app->name()] = reviewsList;
+
+ emit reviewsReady(app, reviewsList);
+}
+
+QString ReviewsBackend::getLanguage()
+{
+ QStringList fullLangs;
+ // The reviews API abbreviates all langs past the _ char except these
+ fullLangs << "pt_BR" << "zh_CN" << "zh_TW";
+
+ QString language = KGlobal::locale()->language();
+
+ if (fullLangs.contains(language)) {
+ return language;
+ }
+
+ return language.split('_').first();
+}
+
diff --git a/installer/ReviewsBackend/ReviewsBackend.h b/installer/ReviewsBackend/ReviewsBackend.h
index 5d8e53d..92de5f8 100644
--- a/installer/ReviewsBackend/ReviewsBackend.h
+++ b/installer/ReviewsBackend/ReviewsBackend.h
@@ -29,6 +29,7 @@ class KTemporaryFile;
class Application;
class Rating;
+class Review;
class ReviewsBackend : public QObject
{
@@ -39,15 +40,26 @@ public:
Rating *ratingForApplication(Application *app) const;
+ void fetchReviews(Application *app);
+
private:
QString m_serverBase;
KTemporaryFile *m_ratingsFile;
+ KTemporaryFile *m_reviewsFile;
QList<Rating *> m_ratings;
+ // cache key is package name + app name, since both by their own may not be unique
+ QHash<QString, QList<Review *> > m_reviewsCache;
+ QHash<KJob *, Application *> m_jobHash;
void fetchRatings();
+ QString getLanguage();
private Q_SLOTS:
void ratingsFetched(KJob *job);
+ void reviewsFetched(KJob *job);
+
+Q_SIGNALS:
+ void reviewsReady(Application *app, QList<Review *>);
};
#endif
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic