[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