File indexing completed on 2024-04-21 05:45:05
0001 /*************************************************************************** 0002 * Copyright (C) 2010 by Daniel Nicoletti <dantti12@gmail.com> * 0003 * Copyright (C) 2012-2013 by Matthias Klumpp <matthias@tenstral.net> * 0004 * * 0005 * This program is free software; you can redistribute it and/or * 0006 * modify it under the terms of the GNU General Public License as * 0007 * published by the Free Software Foundation; either version 2 of * 0008 * the License or (at your option) version 3 or any later version * 0009 * accepted by the membership of KDE e.V. (or its successor approved * 0010 * by the membership of KDE e.V.), which shall act as a proxy * 0011 * defined in Section 14 of version 3 of the license. * 0012 * * 0013 * This program is distributed in the hope that it will be useful, * 0014 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0016 * GNU General Public License for more details. * 0017 * * 0018 * You should have received a copy of the GNU General Public License * 0019 * along with this program. If not, see <http://www.gnu.org/licenses/>. * 0020 ***************************************************************************/ 0021 0022 #include <config.h> 0023 0024 #include <optional> 0025 #include <AppStreamQt5/pool.h> 0026 #include <AppStreamQt5/icon.h> 0027 #include <AppStreamQt5/image.h> 0028 #include <AppStreamQt5/screenshot.h> 0029 0030 #include "AppStream.h" 0031 0032 #include <QApplication> 0033 #include <QLoggingCategory> 0034 0035 Q_DECLARE_LOGGING_CATEGORY(APPER_LIB) 0036 0037 AppStreamHelper* AppStreamHelper::m_instance = 0; 0038 0039 AppStreamHelper* AppStreamHelper::instance() 0040 { 0041 if(!m_instance) { 0042 m_instance = new AppStreamHelper(qApp); 0043 m_instance->open(); 0044 } 0045 0046 return m_instance; 0047 } 0048 0049 AppStreamHelper::AppStreamHelper(QObject *parent) 0050 : QObject(parent) 0051 { 0052 #ifdef HAVE_APPSTREAM 0053 // create new AppStream metadata pool 0054 m_pool = new AppStream::Pool(this); 0055 #endif //HAVE_APPSTREAM 0056 } 0057 0058 AppStreamHelper::~AppStreamHelper() 0059 { 0060 } 0061 0062 bool AppStreamHelper::open() 0063 { 0064 #ifdef HAVE_APPSTREAM 0065 QString error; 0066 if (!m_pool->load()) { 0067 qCWarning(APPER_LIB) << "Unable to open AppStream metadata pool:" << m_pool->lastError(); 0068 return false; 0069 } 0070 0071 // // cache application data (we should actually search the data directly via as_pool_search()...) 0072 // auto cptArray = as_pool_get_components(m_pool); 0073 // if (cptArray == NULL) { 0074 // qWarning("AppStream application array way NULL! (This should never happen)"); 0075 // return false; 0076 // } 0077 0078 // for (uint i = 0; i < cptArray->len; i++) { 0079 // auto cpt = AS_COMPONENT (g_ptr_array_index(cptArray, i)); 0080 // // we only want apps at time 0081 // auto cptKind = as_component_get_kind (cpt); 0082 // if ((cptKind != AS_COMPONENT_KIND_DESKTOP_APP) && 0083 // (cptKind != AS_COMPONENT_KIND_CONSOLE_APP) && 0084 // (cptKind != AS_COMPONENT_KIND_WEB_APP)) 0085 // continue; 0086 0087 // Application app; 0088 // // Application name 0089 // app.name = QString::fromUtf8(as_component_get_name(cpt)); 0090 0091 // // Package name 0092 // auto pkgnameC = as_component_get_pkgname(cpt); 0093 // QString pkgName; 0094 // if (pkgnameC != NULL) 0095 // pkgName = QString::fromUtf8(pkgnameC); 0096 0097 // // Desktop file 0098 // app.id = QString::fromUtf8(as_component_get_id(cpt)); 0099 0100 // // Summary 0101 // app.summary = QString::fromUtf8(as_component_get_summary(cpt)); 0102 0103 // // Description 0104 // app.description = QString::fromUtf8(as_component_get_description(cpt)); 0105 0106 // // Application stock icon 0107 // auto icons = as_component_get_icons(cpt); 0108 // for (uint i = 0; i < icons->len; i++) { 0109 // auto icon = AS_ICON (g_ptr_array_index (icons, i)); 0110 // if (as_icon_get_kind (icon) != AS_ICON_KIND_STOCK) 0111 // app.icon_url = QString::fromUtf8(as_icon_get_filename (icon)); 0112 // } 0113 0114 // // Application categories 0115 // app.categories = QStringList(); 0116 // auto cats = as_component_get_categories(cpt); 0117 // for (uint i = 0; i < cats->len; i++) { 0118 // auto category = (const gchar*) g_ptr_array_index (cats, i); 0119 // app.categories << QString::fromUtf8(category); 0120 // } 0121 0122 // // add default screenshot urls 0123 // auto scrs = as_component_get_screenshots (cpt); 0124 0125 // // find default screenshot, if possible (otherwise we get a random one) 0126 // AsScreenshot *scr = NULL; 0127 // for (uint i = 0; i < scrs->len; i++) { 0128 // scr = AS_SCREENSHOT (g_ptr_array_index (scrs, i)); 0129 // if (as_screenshot_get_kind (scr) == AS_SCREENSHOT_KIND_DEFAULT) 0130 // break; 0131 // } 0132 0133 // if (scr != NULL) { 0134 // auto imgs = as_screenshot_get_images (scr); 0135 // for (uint i = 0; i < imgs->len; i++) { 0136 // auto img = AS_IMAGE (g_ptr_array_index (imgs, i)); 0137 // if ((as_image_get_kind (img) == AS_IMAGE_KIND_SOURCE) && (app.screenshot.isEmpty())) { 0138 // app.screenshot = QString::fromUtf8(as_image_get_url (img)); 0139 // } else if ((as_image_get_kind (img) == AS_IMAGE_KIND_THUMBNAIL) && (app.thumbnail.isEmpty())) { 0140 // app.thumbnail = QString::fromUtf8(as_image_get_url (img)); 0141 // } 0142 0143 // if ((!app.screenshot.isEmpty()) && (!app.thumbnail.isEmpty())) 0144 // break; 0145 // } 0146 // } 0147 0148 // m_appInfo.insertMulti(pkgName, app); 0149 // } 0150 0151 auto apps = m_pool->componentsByKind(AppStream::Component::KindDesktopApp); 0152 for (const AppStream::Component &app : apps) { 0153 const QStringList pkgNames = app.packageNames(); 0154 for (const QString &pkgName : pkgNames) { 0155 m_appInfo.insertMulti(pkgName, app); 0156 } 0157 } 0158 0159 return true; 0160 #else 0161 return false; 0162 #endif 0163 } 0164 0165 QList<AppStream::Component> AppStreamHelper::applications(const QString &pkgName) const 0166 { 0167 return m_appInfo.values(pkgName); 0168 } 0169 0170 QString AppStreamHelper::genericIcon(const QString &pkgName) const 0171 { 0172 if (m_appInfo.contains(pkgName)) { 0173 // const QList<AppStream::Component> apps = applications(pkgName); 0174 // for (const AppStream::Component &app : apps) { 0175 // if (!app.icon_url.isEmpty()) { 0176 // return app.icon_url; 0177 // } 0178 // } 0179 } 0180 0181 return QString(); 0182 } 0183 0184 QStringList AppStreamHelper::findPkgNames(const CategoryMatcher &/*parser*/) const 0185 { 0186 QStringList packages; 0187 0188 // QHash<QString, Application>::const_iterator i = m_appInfo.constBegin(); 0189 // while (i != m_appInfo.constEnd()) { 0190 // if (parser.match(i.value().categories)) { 0191 //// kDebug() << i.key() << categories; 0192 // packages << i.key(); 0193 // } 0194 // ++i; 0195 // } 0196 0197 return packages; 0198 } 0199 0200 QUrl AppStreamHelper::thumbnail(const QString &pkgName) const 0201 { 0202 QUrl url; 0203 #ifdef HAVE_APPSTREAM 0204 if (m_appInfo.contains(pkgName)) { 0205 AppStream::Image thumb; 0206 AppStream::Component cpt = m_appInfo.value(pkgName); 0207 const QList<AppStream::Screenshot> screenshots = cpt.screenshotsAll(); 0208 for (const AppStream::Screenshot &screenshot : screenshots) { 0209 const QList<AppStream::Image> images = screenshot.images(); 0210 for (const AppStream::Image &image : images) { 0211 if (image.kind() == AppStream::Image::KindThumbnail) { 0212 if (thumb.kind() == AppStream::Image::KindUnknown || image.size().height() < thumb.size().height()) { 0213 thumb = image; 0214 url = image.url(); 0215 } 0216 } 0217 } 0218 0219 if (screenshot.isDefault() && !url.isEmpty()) { 0220 break; 0221 } 0222 } 0223 } 0224 0225 return url; 0226 #else 0227 Q_UNUSED(pkgName) 0228 return url; 0229 #endif //HAVE_APPSTREAM 0230 } 0231 0232 QUrl AppStreamHelper::screenshot(const QString &pkgName) const 0233 { 0234 QUrl url; 0235 #ifdef HAVE_APPSTREAM 0236 if (m_appInfo.contains(pkgName)) { 0237 AppStream::Component cpt = m_appInfo.value(pkgName); 0238 const QList<AppStream::Screenshot> screenshots = cpt.screenshotsAll(); 0239 for (const AppStream::Screenshot &screenshot : screenshots) { 0240 const QList<AppStream::Image> images = screenshot.images(); 0241 for (const AppStream::Image &image : images) { 0242 url = image.url(); 0243 break; 0244 } 0245 0246 if (screenshot.isDefault() && !url.isEmpty()) { 0247 break; 0248 } 0249 } 0250 } 0251 0252 #else 0253 Q_UNUSED(pkgName) 0254 #endif //HAVE_APPSTREAM 0255 return url; 0256 }