Commit 9eb621e0 authored by Aleix Pol Gonzalez's avatar Aleix Pol Gonzalez 🐧

Fix license display

When we know it's an SPDX license, parse it and offer the result.
Otherwise provide the provided text raw.

BUG: 402687
parent a86eb768
......@@ -394,14 +394,21 @@ DiscoverPage {
Label {
Layout.alignment: Qt.AlignRight
text: i18n("License:")
visible: appInfo.application.license.length>0
visible: appInfo.application.licenses.length>0
}
Kirigami.UrlButton {
RowLayout {
visible: appInfo.application.licenses.length>0
Layout.fillWidth: true
horizontalAlignment: Text.AlignLeft
// tooltip: i18n("See full license terms")
text: appInfo.application.license
url: "https://spdx.org/licenses/" + appInfo.application.license + ".html#licenseText"
Repeater {
model: appInfo.application.licenses
delegate: Kirigami.UrlButton {
horizontalAlignment: Text.AlignLeft
// tooltip: i18n("See full license terms")
text: modelData.name
url: modelData.url
enabled: url !== ""
}
}
}
// Homepage row
......
......@@ -39,14 +39,22 @@ set(discovercommon_SRCS
ecm_qt_declare_logging_category(discovercommon_SRCS HEADER libdiscover_debug.h IDENTIFIER LIBDISCOVER_LOG CATEGORY_NAME org.kde.plasma.libdiscover)
add_library(DiscoverCommon ${discovercommon_SRCS})
if(AppStreamQt_FOUND)
set(discovercommon_SRCS ${discovercommon_SRCS}
target_sources(DiscoverCommon PRIVATE
appstream/OdrsReviewsBackend.cpp
appstream/AppStreamIntegration.cpp
appstream/AppStreamUtils.cpp
)
endif()
target_link_libraries(DiscoverCommon PRIVATE AppStreamQt)
add_library(DiscoverCommon ${discovercommon_SRCS})
if(AppStreamQt_VERSION VERSION_GREATER 0.12.4)
target_compile_definitions(DiscoverCommon PRIVATE -DAPPSTREAM_HAS_SPDX=1)
else()
target_compile_definitions(DiscoverCommon PRIVATE -DAPPSTREAM_HAS_SPDX=0)
endif()
endif()
target_link_libraries(DiscoverCommon
LINK_PUBLIC
......
/***************************************************************************
* Copyright © 2017 Aleix Pol Gonzalez <aleixpol@kde.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 "AppStreamUtils.h"
#include <QJsonArray>
#include <QJsonObject>
#include <QDebug>
#include "utils.h"
#include <KLocalizedString>
#include <AppStreamQt/component.h>
#include <AppStreamQt/release.h>
#include <AppStreamQt/screenshot.h>
#include <AppStreamQt/spdx.h>
using namespace AppStreamUtils;
QUrl AppStreamUtils::imageOfKind(const QList<AppStream::Image>& images, AppStream::Image::Kind kind)
{
QUrl ret;
Q_FOREACH (const AppStream::Image &i, images) {
if (i.kind() == kind) {
ret = i.url();
break;
}
}
return ret;
}
QString AppStreamUtils::changelogToHtml(const AppStream::Component& appdata)
{
if(appdata.releases().isEmpty())
return {};
const auto release = appdata.releases().constFirst();
if (release.description().isEmpty())
return {};
QString changelog = QStringLiteral("<h3>") + release.version() + QStringLiteral("</h3>")
+ QStringLiteral("<p>") + release.description() + QStringLiteral("</p>");
return changelog;
}
QPair<QList<QUrl>, QList<QUrl> > AppStreamUtils::fetchScreenshots(const AppStream::Component& appdata)
{
QList<QUrl> screenshots, thumbnails;
Q_FOREACH (const AppStream::Screenshot &s, appdata.screenshots()) {
const auto images = s.images();
const QUrl thumbnail = AppStreamUtils::imageOfKind(images, AppStream::Image::KindThumbnail);
const QUrl plain = AppStreamUtils::imageOfKind(images, AppStream::Image::KindSource);
if (plain.isEmpty())
qWarning() << "invalid screenshot for" << appdata.name();
screenshots << plain;
thumbnails << (thumbnail.isEmpty() ? plain : thumbnail);
}
return {screenshots, thumbnails};
}
QJsonArray AppStreamUtils::licenses(const AppStream::Component& appdata)
{
#if APPSTREAM_HAS_SPDX
QJsonArray ret;
const auto licenses = AppStream::SPDX::tokenizeLicense(appdata.projectLicense());
static const QLatin1String prop ("@LicenseRef-proprietary=");
for (const auto &token : licenses) {
QString license = token;
license.remove(0, 1); //tokenize prefixes with an @ for some reason
if (!AppStream::SPDX::isLicenseId(license))
continue;
if (license.startsWith(prop))
ret.append(QJsonObject{ {QStringLiteral("name"), i18n("Proprietary")}, {QStringLiteral("url"), license.mid(prop.size())} });
else
ret.append(QJsonObject{ {QStringLiteral("name"), license}, {QStringLiteral("url"), { QLatin1String("https://spdx.org/licenses/") + AppStream::SPDX::asSpdxId(license) + QLatin1String(".html#licenseText") } }});
}
return ret;
#else
return { QJsonObject { {QStringLiteral("name"), appdata.projectLicense() } } };
#endif
}
......@@ -23,55 +23,18 @@
#include <QUrl>
#include <QList>
#include <QDebug>
#include <AppStreamQt/image.h>
#include <AppStreamQt/component.h>
#include <AppStreamQt/release.h>
#include <AppStreamQt/screenshot.h>
namespace AppStreamUtils
{
static QUrl imageOfKind(const QList<AppStream::Image> &images, AppStream::Image::Kind kind)
{
QUrl ret;
Q_FOREACH (const AppStream::Image &i, images) {
if (i.kind() == kind) {
ret = i.url();
break;
}
}
return ret;
}
static QString changelogToHtml(const AppStream::Component &appdata)
{
if(appdata.releases().isEmpty())
return {};
Q_DECL_EXPORT QUrl imageOfKind(const QList<AppStream::Image> &images, AppStream::Image::Kind kind);
const auto release = appdata.releases().constFirst();
if (release.description().isEmpty())
return {};
Q_DECL_EXPORT QString changelogToHtml(const AppStream::Component &appdata);
QString changelog = QStringLiteral("<h3>") + release.version() + QStringLiteral("</h3>")
+ QStringLiteral("<p>") + release.description() + QStringLiteral("</p>");
return changelog;
}
static QPair<QList<QUrl>, QList<QUrl>> fetchScreenshots(const AppStream::Component &appdata)
{
QList<QUrl> screenshots, thumbnails;
Q_FOREACH (const AppStream::Screenshot &s, appdata.screenshots()) {
const auto images = s.images();
const QUrl thumbnail = AppStreamUtils::imageOfKind(images, AppStream::Image::KindThumbnail);
const QUrl plain = AppStreamUtils::imageOfKind(images, AppStream::Image::KindSource);
if (plain.isEmpty())
qWarning() << "invalid screenshot for" << appdata.name();
Q_DECL_EXPORT QPair<QList<QUrl>, QList<QUrl>> fetchScreenshots(const AppStream::Component &appdata);
screenshots << plain;
thumbnails << (thumbnail.isEmpty() ? plain : thumbnail);
}
return {screenshots, thumbnails};
}
Q_DECL_EXPORT QJsonArray licenses(const AppStream::Component &appdata);
}
......
......@@ -105,9 +105,9 @@ QString DummyResource::installedVersion() const
return QStringLiteral("2.3");
}
QString DummyResource::license()
QJsonArray DummyResource::licenses()
{
return QStringLiteral("GPL");
return { QJsonObject{ {QStringLiteral("name"), QStringLiteral("GPL") }, { QStringLiteral("url"), QStringLiteral("https://kde.org") } } };
}
QString DummyResource::longDescription()
......
......@@ -36,7 +36,7 @@ public:
QString longDescription() override;
QString availableVersion() const override;
QString installedVersion() const override;
QString license() override;
QJsonArray licenses() override;
int size() override;
QUrl homepage() override;
QUrl helpURL() override;
......
......@@ -27,6 +27,7 @@
#include <AppStreamQt/icon.h>
#include <AppStreamQt/screenshot.h>
#include <AppStreamQt/spdx.h>
#include <appstream/AppStreamUtils.h>
#include <KFormat>
......@@ -294,9 +295,9 @@ QString FlatpakResource::flatpakName() const
return m_flatpakName;
}
QString FlatpakResource::license()
QJsonArray FlatpakResource::licenses()
{
return m_appdata.projectLicense();
return AppStreamUtils::licenses(m_appdata);
}
QString FlatpakResource::longDescription()
......
......@@ -111,7 +111,7 @@ public:
QUrl donationURL() override;
QString flatpakFileType() const;
QString flatpakName() const;
QString license() override;
QJsonArray licenses() override;
QString longDescription() override;
QString name() const override;
QString origin() const override;
......
......@@ -85,9 +85,9 @@ QString FwupdResource::installedVersion() const
return m_version;
}
QString FwupdResource::license()
QJsonArray FwupdResource::licenses()
{
return m_license;
return { QJsonObject{ {QStringLiteral("name"), m_license} } };
}
QString FwupdResource::longDescription()
......
......@@ -40,7 +40,7 @@ public:
QString longDescription() override;
QString availableVersion() const override;
QString installedVersion() const override;
QString license() override;
QJsonArray licenses() override;
int size() override;
QUrl homepage() override;
QUrl helpURL() override;
......
......@@ -141,9 +141,9 @@ KNSCore::EntryInternal KNSResource::entry() const
return m_entry;
}
QString KNSResource::license()
QJsonArray KNSResource::licenses()
{
return m_entry.license();
return { QJsonObject{ {QStringLiteral("name"), m_entry.license()} } };
}
int KNSResource::size()
......
......@@ -43,7 +43,7 @@ public:
QString packageName() const override;
QStringList categories() override;
QUrl homepage() override;
QString license() override;
QJsonArray licenses() override;
QString longDescription() override;
QList<PackageState> addonsInformation() override { return QList<PackageState>(); }
QString availableVersion() const override;
......
......@@ -100,10 +100,9 @@ QVariant AppPackageKitResource::icon() const
return componentIcon(m_appdata);
}
QString AppPackageKitResource::license()
QJsonArray AppPackageKitResource::licenses()
{
const auto license = m_appdata.projectLicense();
return license.isEmpty() ? PackageKitResource::license() : license;
return m_appdata.projectLicense().isEmpty() ? PackageKitResource::licenses() : AppStreamUtils::licenses(m_appdata);
}
QStringList AppPackageKitResource::mimetypes() const
......
......@@ -43,7 +43,7 @@ class AppPackageKitResource : public PackageKitResource
QUrl bugURL() override;
QUrl donationURL() override;
QString comment() override;
QString license() override;
QJsonArray licenses() override;
QStringList allPackageNames() const override;
QList<PackageState> addonsInformation() override;
QStringList extends() const override;
......
......@@ -81,11 +81,6 @@ void LocalFilePKResource::fetchDetails()
connect(transaction2, &PackageKit::Transaction::finished, this, [] {qDebug() << "."; });
}
QString LocalFilePKResource::license()
{
return m_details.license();
}
void LocalFilePKResource::invokeApplication() const
{
QProcess::startDetached(QStringLiteral(CMAKE_INSTALL_FULL_LIBEXECDIR_KF5 "/discover/runservice"), {m_exec});
......
......@@ -33,7 +33,6 @@ class LocalFilePKResource : public PackageKitResource
QString comment() override;
AbstractResource::State state() override { return m_state; }
QString license() override;
int size() override;
void markInstalled();
QString origin() const override;
......
......@@ -102,10 +102,15 @@ QVariant PackageKitResource::icon() const
return QStringLiteral("applications-other");
}
QString PackageKitResource::license()
QJsonArray PackageKitResource::licenses()
{
fetchDetails();
return m_details.license().isEmpty() ? i18n("Unknown") : m_details.license();
if (!m_details.license().isEmpty()) {
return {{ m_details.license(), {} }};
}
return {};
}
QList<PackageState> PackageKitResource::addonsInformation()
......
......@@ -40,7 +40,7 @@ class PackageKitResource : public AbstractResource
QUrl homepage() override;
QVariant icon() const override;
QStringList categories() override;
QString license() override;
QJsonArray licenses() override;
QString origin() const override;
QString section() override;
AbstractResource::Type type() const override;
......
......@@ -155,9 +155,9 @@ QString SnapResource::installedVersion() const
return m_snap->version();
}
QString SnapResource::license()
QJsonArray SnapResource::licenses()
{
return m_snap->license();
return { QJsonObject{ {QStringLiteral("name"), m_snap->license()} } };
}
QString SnapResource::longDescription()
......
......@@ -45,7 +45,7 @@ public:
QString longDescription() override;
QString availableVersion() const override;
QString installedVersion() const override;
QString license() override;
QJsonArray licenses() override;
int size() override;
QStringList categories() override;
AbstractResource::State state() override;
......
......@@ -28,6 +28,7 @@
#include <QVector>
#include <QCollatorSortKey>
#include <QJsonObject>
#include <QJsonArray>
#include <QDate>
#include "discovercommon_export.h"
......@@ -61,7 +62,7 @@ class DISCOVERCOMMON_EXPORT AbstractResource : public QObject
Q_PROPERTY(QUrl donationURL READ donationURL CONSTANT)
Q_PROPERTY(bool canUpgrade READ canUpgrade NOTIFY stateChanged)
Q_PROPERTY(bool isInstalled READ isInstalled NOTIFY stateChanged)
Q_PROPERTY(QString license READ license CONSTANT)
Q_PROPERTY(QJsonArray licenses READ licenses CONSTANT)
Q_PROPERTY(QString longDescription READ longDescription CONSTANT)
Q_PROPERTY(QString origin READ origin CONSTANT)
Q_PROPERTY(QString displayOrigin READ displayOrigin CONSTANT)
......@@ -147,7 +148,9 @@ class DISCOVERCOMMON_EXPORT AbstractResource : public QObject
virtual int size() = 0;
virtual QString sizeDescription();
virtual QString license() = 0;
///@returns a list of pairs with the name of the license and a URL pointing at it
virtual QJsonArray licenses() = 0;
virtual QString installedVersion() const = 0;
virtual QString availableVersion() const = 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment