1 /*
2 * SPDX-FileCopyrightText: 2017 Aleix Pol Gonzalez <aleixpol@kde.org>
3 *
4 * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
5 */
6
7 #include "AppStreamUtils.h"
8
9 #include "utils.h"
10 #include <AppStreamQt/release.h>
11 #include <AppStreamQt/screenshot.h>
12 #include <KLocalizedString>
13 #include <QDebug>
14 #include <QJsonArray>
15 #include <QJsonObject>
16 #include <QUrlQuery>
17 #include <AppStreamQt/spdx.h>
18
19 using namespace AppStreamUtils;
20
imageOfKind(const QList<AppStream::Image> & images,AppStream::Image::Kind kind)21 QUrl AppStreamUtils::imageOfKind(const QList<AppStream::Image> &images, AppStream::Image::Kind kind)
22 {
23 QUrl ret;
24 for (const AppStream::Image &i : images) {
25 if (i.kind() == kind) {
26 ret = i.url();
27 break;
28 }
29 }
30 return ret;
31 }
32
changelogToHtml(const AppStream::Component & appdata)33 QString AppStreamUtils::changelogToHtml(const AppStream::Component &appdata)
34 {
35 if (appdata.releases().isEmpty())
36 return {};
37
38 const auto release = appdata.releases().constFirst();
39 if (release.description().isEmpty())
40 return {};
41
42 QString changelog =
43 QLatin1String("<h3>") + release.version() + QLatin1String("</h3>") + QStringLiteral("<p>") + release.description() + QStringLiteral("</p>");
44 return changelog;
45 }
46
fetchScreenshots(const AppStream::Component & appdata)47 QPair<QList<QUrl>, QList<QUrl>> AppStreamUtils::fetchScreenshots(const AppStream::Component &appdata)
48 {
49 QList<QUrl> screenshots, thumbnails;
50 const auto appdataScreenshots = appdata.screenshots();
51 for (const AppStream::Screenshot &s : appdataScreenshots) {
52 const auto images = s.images();
53 const QUrl thumbnail = AppStreamUtils::imageOfKind(images, AppStream::Image::KindThumbnail);
54 const QUrl plain = AppStreamUtils::imageOfKind(images, AppStream::Image::KindSource);
55 if (plain.isEmpty())
56 qWarning() << "invalid screenshot for" << appdata.name();
57
58 screenshots << plain;
59 thumbnails << (thumbnail.isEmpty() ? plain : thumbnail);
60 }
61 return {thumbnails, screenshots};
62 }
63
licenses(const AppStream::Component & appdata)64 QJsonArray AppStreamUtils::licenses(const AppStream::Component &appdata)
65 {
66 QJsonArray ret;
67 const auto licenses = AppStream::SPDX::tokenizeLicense(appdata.projectLicense());
68 for (const auto &token : licenses) {
69 QString license = token;
70 license.remove(0, 1); // tokenize prefixes with an @ for some reason
71 if (!AppStream::SPDX::isLicenseId(license))
72 continue;
73 ret.append(QJsonObject{{QStringLiteral("name"), license}, {QStringLiteral("url"), {AppStream::SPDX::licenseUrl(license)}}});
74 }
75 return ret;
76 }
77
appstreamIds(const QUrl & appstreamUrl)78 QStringList AppStreamUtils::appstreamIds(const QUrl &appstreamUrl)
79 {
80 QStringList ret;
81 ret += appstreamUrl.host().isEmpty() ? appstreamUrl.path() : appstreamUrl.host();
82 if (appstreamUrl.hasQuery()) {
83 QUrlQuery query(appstreamUrl);
84 ret << query.queryItemValue(QStringLiteral("alt")).split(QLatin1Char(','), Qt::SkipEmptyParts);
85 }
86 return ret;
87 }
88
versionString(const QString & version,const AppStream::Component & appdata)89 QString AppStreamUtils::versionString(const QString &version, const AppStream::Component &appdata)
90 {
91 if (version.isEmpty()) {
92 return {};
93 } else {
94 if (appdata.releases().isEmpty())
95 return version;
96
97 auto release = appdata.releases().constFirst();
98 if (release.timestamp().isValid() && version.startsWith(release.version())) {
99 QLocale l;
100 qDebug() << "versionversion" << version << release.version();
101 return i18n("%1, released on %2", version, l.toString(release.timestamp().date(), QLocale::ShortFormat));
102 } else {
103 return version;
104 }
105 }
106 }
107