/* * SPDX-FileCopyrightText: 2020 Alexey Minnekhanov * * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL */ #include "AlpineApkResource.h" #include "alpineapk_backend_logging.h" // generated by ECM #include #include #include #include #include #include #include // libdiscover #include "Transaction/AddonList.h" #include "appstream/AppStreamUtils.h" #include "config-paths.h" AlpineApkResource::AlpineApkResource(const QtApk::Package &apkPkg, AppStream::Component &component, AbstractResource::Type typ, AbstractResourcesBackend *parent) : AbstractResource(parent) , m_state(AbstractResource::State::None) , m_type(typ) , m_pkg(apkPkg) , m_appsC(component) { } QList AlpineApkResource::addonsInformation() { return m_addons; } QString AlpineApkResource::availableVersion() const { return m_availableVersion; } bool AlpineApkResource::hasCategory(const QString &category) const { if (hasAppStreamData()) { return m_appsC.categories().contains(category); } return m_category == category; } QString AlpineApkResource::comment() { if (hasAppStreamData()) { return m_appsC.summary(); } return m_pkg.description; } quint64 AlpineApkResource::size() { return m_pkg.size; } QUrl AlpineApkResource::homepage() { if (hasAppStreamData()) { return m_appsC.url(AppStream::Component::UrlKindHomepage); } return QUrl::fromUserInput(m_pkg.url); } QUrl AlpineApkResource::helpURL() { if (hasAppStreamData()) { return m_appsC.url(AppStream::Component::UrlKindHelp); } return QUrl(); } QUrl AlpineApkResource::bugURL() { if (hasAppStreamData()) { return m_appsC.url(AppStream::Component::UrlKindBugtracker); } return QUrl(); } QUrl AlpineApkResource::donationURL() { if (hasAppStreamData()) { return m_appsC.url(AppStream::Component::UrlKindDonation); } return QUrl(); } /// xdg-compatible icon name to represent the resource, url or QIcon QVariant AlpineApkResource::icon() const { if (hasAppStreamData()) { const QList icns = m_appsC.icons(); if (icns.size() == 0) { return QStringLiteral("package-x-generic"); } QIcon ico; const AppStream::Icon &appIco = icns.first(); switch (appIco.kind()) { case AppStream::Icon::KindStock: // we can create icons of this type directly from theme ico = QIcon::fromTheme(appIco.name()); break; case AppStream::Icon::KindLocal: case AppStream::Icon::KindCached: { // try from predefined standard Alpine path const QString appstreamIconsPath = QLatin1String("/usr/share/app-info/icons/"); const QString path = appstreamIconsPath + appIco.url().path(); if (QFileInfo::exists(path)) { ico.addFile(path, appIco.size()); } else { const QString altPath = appstreamIconsPath + QStringLiteral("%1x%2/").arg(appIco.size().width()).arg(appIco.size().height()) + appIco.url().path(); if (QFileInfo::exists(altPath)) { ico.addFile(altPath, appIco.size()); } } } break; default: break; } // return icon only if we successfully loaded it if (!ico.isNull()) { return QVariant::fromValue(ico); } // try to load from icon theme by package name, this is better // than nothing and works surprisingly well for many packages ico = QIcon::fromTheme(m_pkg.name); if (!ico.isNull()) { return QVariant::fromValue(ico); } } return QStringLiteral("package-x-generic"); } QString AlpineApkResource::installedVersion() const { return m_pkg.version; } QJsonArray AlpineApkResource::licenses() { return {QJsonObject{ {QStringLiteral("name"), m_pkg.license}, {QStringLiteral("url"), QStringLiteral("https://spdx.org/license-list")}, }}; } QString AlpineApkResource::longDescription() { if (hasAppStreamData()) { return m_appsC.description(); } return m_pkg.description; } QString AlpineApkResource::name() const { if (hasAppStreamData()) { return m_appsC.name(); } return m_pkg.name; } QString AlpineApkResource::origin() const { return m_originSoruce; } QString AlpineApkResource::packageName() const { return m_pkg.name; } QString AlpineApkResource::section() { return m_sectionName; } AbstractResource::State AlpineApkResource::state() { return m_state; } void AlpineApkResource::fetchChangelog() { if (hasAppStreamData()) { Q_EMIT changelogFetched(AppStreamUtils::changelogToHtml(m_appsC)); } } void AlpineApkResource::fetchScreenshots() { if (hasAppStreamData()) { const Screenshots screenshots = AppStreamUtils::fetchScreenshots(m_appsC); Q_EMIT screenshotsFetched(screenshots); } } QString AlpineApkResource::appstreamId() const { if (hasAppStreamData()) { return m_appsC.id(); } return QString(); } void AlpineApkResource::setState(AbstractResource::State state) { m_state = state; Q_EMIT stateChanged(); } void AlpineApkResource::setCategoryName(const QString &categoryName) { m_category = categoryName; } void AlpineApkResource::setOriginSource(const QString &originSource) { m_originSoruce = originSource; } void AlpineApkResource::setSection(const QString §ionName) { m_sectionName = sectionName; } void AlpineApkResource::setAddons(const AddonList &addons) { const QStringList addonsToInstall = addons.addonsToInstall(); for (const QString &toInstall : addonsToInstall) { setAddonInstalled(toInstall, true); } const QStringList addonsToRemove = addons.addonsToRemove(); for (const QString &toRemove : addonsToRemove) { setAddonInstalled(toRemove, false); } } void AlpineApkResource::setAddonInstalled(const QString &addon, bool installed) { for (PackageState &elem : m_addons) { if (elem.name() == addon) { elem.setInstalled(installed); } } } void AlpineApkResource::setAvailableVersion(const QString &av) { m_availableVersion = av; } bool AlpineApkResource::hasAppStreamData() const { return !m_appsC.id().isEmpty(); } void AlpineApkResource::setAppStreamData(const AppStream::Component &component) { m_appsC = component; } bool AlpineApkResource::canExecute() const { if (hasAppStreamData()) { return (m_appsC.kind() == AppStream::Component::KindDesktopApp && (m_state == AbstractResource::Installed || m_state == AbstractResource::Upgradeable)); } return false; } void AlpineApkResource::invokeApplication() const { const QString desktopFile = QLatin1String("/usr/share/applications/") + appstreamId(); if (QFile::exists(desktopFile)) { QProcess::startDetached(QStringLiteral("kstart5"), {QStringLiteral("--service"), desktopFile}); } } QUrl AlpineApkResource::url() const { if (hasAppStreamData()) { return QUrl(QStringLiteral("appstream://") + appstreamId()); } return QUrl(QLatin1String("apk://") + packageName()); } QString AlpineApkResource::author() const { if (hasAppStreamData()) { return m_appsC.developer().name(); } return m_pkg.maintainer; } QString AlpineApkResource::sourceIcon() const { return QStringLiteral("alpine-linux-logo-icon"); } QDate AlpineApkResource::releaseDate() const { if (hasAppStreamData()) { if (const auto releases = m_appsC.releasesPlain(); !releases.isEmpty()) { auto release = releases.indexSafe(0); if (release) { return release->timestamp().date(); } } } // just build date is fine, too return m_pkg.buildTime.date(); }