Changeset View
Changeset View
Standalone View
Standalone View
libdiscover/backends/PackageKitBackend/PackageKitBackend.cpp
Show All 37 Lines | |||||
38 | #include <QStringList> | 38 | #include <QStringList> | ||
39 | #include <QDebug> | 39 | #include <QDebug> | ||
40 | #include <QTimer> | 40 | #include <QTimer> | ||
41 | #include <QStandardPaths> | 41 | #include <QStandardPaths> | ||
42 | #include <QFile> | 42 | #include <QFile> | ||
43 | #include <QAction> | 43 | #include <QAction> | ||
44 | #include <QMimeDatabase> | 44 | #include <QMimeDatabase> | ||
45 | #include <QFileSystemWatcher> | 45 | #include <QFileSystemWatcher> | ||
46 | #include <QFutureWatcher> | ||||
47 | #include <QtConcurrentRun> | ||||
46 | 48 | | |||
47 | #include <PackageKit/Transaction> | 49 | #include <PackageKit/Transaction> | ||
48 | #include <PackageKit/Daemon> | 50 | #include <PackageKit/Daemon> | ||
49 | #include <PackageKit/Offline> | 51 | #include <PackageKit/Offline> | ||
50 | #include <PackageKit/Details> | 52 | #include <PackageKit/Details> | ||
51 | 53 | | |||
52 | #include <KLocalizedString> | 54 | #include <KLocalizedString> | ||
53 | #include <KProtocolManager> | 55 | #include <KProtocolManager> | ||
▲ Show 20 Lines • Show All 61 Lines • ▼ Show 20 Line(s) | 116 | setWhenAvailable(PackageKit::Daemon::getTimeSinceAction(PackageKit::Transaction::RoleRefreshCache), [this](uint timeSince) { | |||
115 | if (timeSince > 3600) | 117 | if (timeSince > 3600) | ||
116 | checkForUpdates(); | 118 | checkForUpdates(); | ||
117 | else | 119 | else | ||
118 | fetchUpdates(); | 120 | fetchUpdates(); | ||
119 | acquireFetching(false); | 121 | acquireFetching(false); | ||
120 | }, this); | 122 | }, this); | ||
121 | } | 123 | } | ||
122 | 124 | | |||
123 | PackageKitBackend::~PackageKitBackend() = default; | 125 | PackageKitBackend::~PackageKitBackend() | ||
126 | { | ||||
127 | m_threadPool.waitForDone(200); | ||||
128 | m_threadPool.clear(); | ||||
129 | } | ||||
124 | 130 | | |||
125 | void PackageKitBackend::updateProxy() | 131 | void PackageKitBackend::updateProxy() | ||
126 | { | 132 | { | ||
127 | 133 | | |||
128 | if (PackageKit::Daemon::isRunning()) { | 134 | if (PackageKit::Daemon::isRunning()) { | ||
129 | static bool everHad = KProtocolManager::useProxy(); | 135 | static bool everHad = KProtocolManager::useProxy(); | ||
130 | if (!everHad && !KProtocolManager::useProxy()) | 136 | if (!everHad && !KProtocolManager::useProxy()) | ||
131 | return; | 137 | return; | ||
Show All 21 Lines | 158 | else | |||
153 | m_isFetching--; | 159 | m_isFetching--; | ||
154 | 160 | | |||
155 | if ((!f && m_isFetching==0) || (f && m_isFetching==1)) { | 161 | if ((!f && m_isFetching==0) || (f && m_isFetching==1)) { | ||
156 | emit fetchingChanged(); | 162 | emit fetchingChanged(); | ||
157 | } | 163 | } | ||
158 | Q_ASSERT(m_isFetching>=0); | 164 | Q_ASSERT(m_isFetching>=0); | ||
159 | } | 165 | } | ||
160 | 166 | | |||
161 | void PackageKitBackend::reloadPackageList() | 167 | struct DelayedAppStreamLoad { | ||
168 | QVector<AppStream::Component> components; | ||||
169 | QHash<QString, AppStream::Component> missingComponents; | ||||
170 | bool correct = true; | ||||
171 | }; | ||||
172 | | ||||
173 | static DelayedAppStreamLoad loadAppStream(AppStream::Pool* appdata) | ||||
162 | { | 174 | { | ||
163 | acquireFetching(true); | 175 | DelayedAppStreamLoad ret; | ||
164 | if (m_refresher) { | | |||
165 | disconnect(m_refresher.data(), &PackageKit::Transaction::finished, this, &PackageKitBackend::reloadPackageList); | | |||
166 | } | | |||
167 | 176 | | |||
168 | QString error; | 177 | QString error; | ||
169 | m_appdata.reset(new AppStream::Pool); | 178 | ret.correct = appdata->load(&error); | ||
170 | const bool b = m_appdata->load(&error); | 179 | if (!ret.correct) { | ||
171 | if (!b && m_packages.packages.isEmpty()) { | | |||
172 | qWarning() << "Could not open the AppStream metadata pool" << error; | 180 | qWarning() << "Could not open the AppStream metadata pool" << error; | ||
173 | | ||||
174 | QTimer::singleShot(0, this, [this]() { | | |||
175 | Q_EMIT passiveMessage(i18n("Please make sure that Appstream is properly set up on your system")); | | |||
176 | }); | | |||
177 | } | 181 | } | ||
178 | 182 | | |||
179 | const auto components = m_appdata->components(); | 183 | const auto components = appdata->components(); | ||
180 | QStringList neededPackages; | 184 | ret.components.reserve(components.size()); | ||
181 | neededPackages.reserve(components.size()); | | |||
182 | foreach(const AppStream::Component& component, components) { | 185 | foreach(const AppStream::Component& component, components) { | ||
183 | if (component.kind() == AppStream::Component::KindFirmware) | 186 | if (component.kind() == AppStream::Component::KindFirmware) | ||
184 | continue; | 187 | continue; | ||
185 | 188 | | |||
186 | const auto pkgNames = component.packageNames(); | 189 | const auto pkgNames = component.packageNames(); | ||
187 | if (pkgNames.isEmpty()) { | 190 | if (pkgNames.isEmpty()) { | ||
188 | const auto entries = component.launchable(AppStream::Launchable::KindDesktopId).entries(); | 191 | const auto entries = component.launchable(AppStream::Launchable::KindDesktopId).entries(); | ||
189 | if (component.kind() == AppStream::Component::KindDesktopApp && !entries.isEmpty()) { | 192 | if (component.kind() == AppStream::Component::KindDesktopApp && !entries.isEmpty()) { | ||
190 | const QString file = locateService(entries.first()); | 193 | const QString file = PackageKitBackend::locateService(entries.first()); | ||
191 | if (!file.isEmpty()) { | 194 | if (!file.isEmpty()) { | ||
195 | ret.missingComponents[file] = component; | ||||
196 | } | ||||
197 | } | ||||
198 | } else { | ||||
broulik: Coding style .. | |||||
199 | ret.components << component; | ||||
200 | } | ||||
201 | } | ||||
202 | return ret; | ||||
203 | } | ||||
204 | | ||||
205 | void PackageKitBackend::reloadPackageList() | ||||
206 | { | ||||
207 | acquireFetching(true); | ||||
208 | if (m_refresher) { | ||||
209 | disconnect(m_refresher.data(), &PackageKit::Transaction::finished, this, &PackageKitBackend::reloadPackageList); | ||||
210 | } | ||||
211 | | ||||
212 | m_appdata.reset(new AppStream::Pool); | ||||
213 | | ||||
214 | auto fw = new QFutureWatcher<DelayedAppStreamLoad>(this); | ||||
215 | connect(fw, &QFutureWatcher<DelayedAppStreamLoad>::finished, this, [this, fw]() { | ||||
216 | const auto data = fw->result(); | ||||
217 | fw->deleteLater(); | ||||
218 | | ||||
219 | if (!data.correct && m_packages.packages.isEmpty()) { | ||||
220 | QTimer::singleShot(0, this, [this]() { | ||||
221 | Q_EMIT passiveMessage(i18n("Please make sure that Appstream is properly set up on your system")); | ||||
222 | }); | ||||
223 | } | ||||
224 | QStringList neededPackages; | ||||
225 | neededPackages.reserve(data.components.size()); | ||||
226 | for (const auto &component: data.components) { | ||||
227 | const auto pkgNames = component.packageNames(); | ||||
228 | addComponent(component, pkgNames); | ||||
229 | neededPackages << pkgNames; | ||||
230 | } | ||||
231 | for (auto it = data.missingComponents.constBegin(), itEnd = data.missingComponents.constEnd(); it != itEnd; ++it) { | ||||
192 | acquireFetching(true); | 232 | acquireFetching(true); | ||
233 | const auto file = it.key(); | ||||
234 | const auto component = it.value(); | ||||
193 | auto trans = PackageKit::Daemon::searchFiles(file); | 235 | auto trans = PackageKit::Daemon::searchFiles(file); | ||
194 | connect(trans, &PackageKit::Transaction::package, this, [trans](PackageKit::Transaction::Info info, const QString &packageID){ | 236 | connect(trans, &PackageKit::Transaction::package, this, [trans](PackageKit::Transaction::Info info, const QString &packageID){ | ||
195 | if (info == PackageKit::Transaction::InfoInstalled) | 237 | if (info == PackageKit::Transaction::InfoInstalled) | ||
196 | trans->setProperty("installedPackage", packageID); | 238 | trans->setProperty("installedPackage", packageID); | ||
197 | }); | 239 | }); | ||
198 | connect(trans, &PackageKit::Transaction::finished, this, [this, trans, component](PackageKit::Transaction::Exit status) { | 240 | connect(trans, &PackageKit::Transaction::finished, this, [this, trans, component](PackageKit::Transaction::Exit status) { | ||
199 | const auto pkgidVal = trans->property("installedPackage"); | 241 | const auto pkgidVal = trans->property("installedPackage"); | ||
200 | if (status == PackageKit::Transaction::ExitSuccess && !pkgidVal.isNull()) { | 242 | if (status == PackageKit::Transaction::ExitSuccess && !pkgidVal.isNull()) { | ||
201 | const auto pkgid = pkgidVal.toString(); | 243 | const auto pkgid = pkgidVal.toString(); | ||
202 | auto res = addComponent(component, {PackageKit::Daemon::packageName(pkgid)}); | 244 | auto res = addComponent(component, {PackageKit::Daemon::packageName(pkgid)}); | ||
203 | res->clearPackageIds(); | 245 | res->clearPackageIds(); | ||
204 | res->addPackageId(PackageKit::Transaction::InfoInstalled, pkgid, true); | 246 | res->addPackageId(PackageKit::Transaction::InfoInstalled, pkgid, true); | ||
205 | } | 247 | } | ||
206 | acquireFetching(false); | 248 | acquireFetching(false); | ||
207 | }); | 249 | }); | ||
208 | continue; | | |||
209 | } | 250 | } | ||
210 | } | | |||
211 | | ||||
212 | qCDebug(LIBDISCOVER_BACKEND_LOG) << "no packages for" << component.id(); | | |||
213 | continue; | | |||
214 | } | | |||
215 | neededPackages += pkgNames; | | |||
216 | 251 | | |||
217 | addComponent(component, pkgNames); | | |||
218 | } | | |||
219 | | ||||
220 | acquireFetching(false); | | |||
221 | if (!neededPackages.isEmpty()) { | 252 | if (!neededPackages.isEmpty()) { | ||
222 | neededPackages.removeDuplicates(); | 253 | neededPackages.removeDuplicates(); | ||
223 | resolvePackages(neededPackages); | 254 | resolvePackages(neededPackages); | ||
224 | } else { | 255 | } else { | ||
225 | qCDebug(LIBDISCOVER_BACKEND_LOG) << "empty appstream db"; | 256 | qCDebug(LIBDISCOVER_BACKEND_LOG) << "empty appstream db"; | ||
226 | if (PackageKit::Daemon::backendName() == QLatin1String("aptcc") || PackageKit::Daemon::backendName().isEmpty()) { | 257 | if (PackageKit::Daemon::backendName() == QLatin1String("aptcc") || PackageKit::Daemon::backendName().isEmpty()) { | ||
227 | checkForUpdates(); | 258 | checkForUpdates(); | ||
228 | } | 259 | } | ||
229 | } | 260 | } | ||
261 | acquireFetching(false); | ||||
262 | if (!m_appstreamInitialized) { | ||||
263 | m_appstreamInitialized = true; | ||||
264 | Q_EMIT loadedAppStream(); | ||||
265 | } | ||||
266 | }); | ||||
267 | fw->setFuture(QtConcurrent::run(&m_threadPool, &loadAppStream, m_appdata.get())); | ||||
230 | } | 268 | } | ||
231 | 269 | | |||
232 | AppPackageKitResource* PackageKitBackend::addComponent(const AppStream::Component& component, const QStringList& pkgNames) | 270 | AppPackageKitResource* PackageKitBackend::addComponent(const AppStream::Component& component, const QStringList& pkgNames) | ||
233 | { | 271 | { | ||
234 | Q_ASSERT(isFetching()); | 272 | Q_ASSERT(isFetching()); | ||
235 | Q_ASSERT(!pkgNames.isEmpty()); | 273 | Q_ASSERT(!pkgNames.isEmpty()); | ||
236 | 274 | | |||
237 | 275 | | |||
▲ Show 20 Lines • Show All 174 Lines • ▼ Show 20 Line(s) | 441 | if (!m_refresher) { | |||
412 | }); | 450 | }); | ||
413 | } else { | 451 | } else { | ||
414 | qWarning() << "already resetting"; | 452 | qWarning() << "already resetting"; | ||
415 | } | 453 | } | ||
416 | } | 454 | } | ||
417 | 455 | | |||
418 | QList<AppStream::Component> PackageKitBackend::componentsById(const QString& id) const | 456 | QList<AppStream::Component> PackageKitBackend::componentsById(const QString& id) const | ||
419 | { | 457 | { | ||
458 | Q_ASSERT(m_appstreamInitialized); | ||||
420 | return m_appdata->componentsById(id); | 459 | return m_appdata->componentsById(id); | ||
421 | } | 460 | } | ||
422 | 461 | | |||
423 | ResultsStream* PackageKitBackend::search(const AbstractResourcesBackend::Filters& filter) | 462 | ResultsStream* PackageKitBackend::search(const AbstractResourcesBackend::Filters& filter) | ||
424 | { | 463 | { | ||
425 | if (!filter.resourceUrl.isEmpty()) { | 464 | if (!filter.resourceUrl.isEmpty()) { | ||
426 | return findResourceByPackageName(filter.resourceUrl); | 465 | return findResourceByPackageName(filter.resourceUrl); | ||
427 | } else if (!filter.extends.isEmpty()) { | 466 | } else if (!filter.extends.isEmpty()) { | ||
428 | const auto ext = kTransform<QVector<AbstractResource*>>(m_packages.extendedBy.value(filter.extends), [](AppPackageKitResource* a){ return a; }); | 467 | const auto ext = kTransform<QVector<AbstractResource*>>(m_packages.extendedBy.value(filter.extends), [](AppPackageKitResource* a){ return a; }); | ||
429 | return new ResultsStream(QStringLiteral("PackageKitStream-extends"), ext); | 468 | return new ResultsStream(QStringLiteral("PackageKitStream-extends"), ext); | ||
430 | } else if (filter.search.isEmpty()) { | 469 | } else if (filter.search.isEmpty()) { | ||
431 | return new ResultsStream(QStringLiteral("PackageKitStream-all"), kFilter<QVector<AbstractResource*>>(m_packages.packages, [](AbstractResource* res) { return res->type() != AbstractResource::Technical && !qobject_cast<PackageKitResource*>(res)->extendsItself(); })); | 470 | return new ResultsStream(QStringLiteral("PackageKitStream-all"), kFilter<QVector<AbstractResource*>>(m_packages.packages, [](AbstractResource* res) { return res->type() != AbstractResource::Technical && !qobject_cast<PackageKitResource*>(res)->extendsItself(); })); | ||
432 | } else { | 471 | } else { | ||
472 | auto stream = new ResultsStream(QStringLiteral("PackageKitStream-search")); | ||||
473 | const auto f = [this, stream, filter] () { | ||||
433 | const QList<AppStream::Component> components = m_appdata->search(filter.search); | 474 | const QList<AppStream::Component> components = m_appdata->search(filter.search); | ||
434 | const QStringList ids = kTransform<QStringList>(components, [](const AppStream::Component& comp) { return comp.id(); }); | 475 | const QStringList ids = kTransform<QStringList>(components, [](const AppStream::Component& comp) { return comp.id(); }); | ||
435 | auto stream = new ResultsStream(QStringLiteral("PackageKitStream-search")); | | |||
436 | if (!ids.isEmpty()) { | 476 | if (!ids.isEmpty()) { | ||
437 | const auto resources = kFilter<QVector<AbstractResource*>>(resourcesByPackageNames<QVector<AbstractResource*>>(ids), [](AbstractResource* res){ return !qobject_cast<PackageKitResource*>(res)->extendsItself(); }); | 477 | const auto resources = kFilter<QVector<AbstractResource*>>(resourcesByPackageNames<QVector<AbstractResource*>>(ids), [](AbstractResource* res){ return !qobject_cast<PackageKitResource*>(res)->extendsItself(); }); | ||
438 | QTimer::singleShot(0, this, [stream, resources] () { | | |||
439 | Q_EMIT stream->resourcesFound(resources); | 478 | Q_EMIT stream->resourcesFound(resources); | ||
440 | }); | | |||
441 | } | 479 | } | ||
442 | 480 | | |||
443 | PackageKit::Transaction * tArch = PackageKit::Daemon::resolve(filter.search, PackageKit::Transaction::FilterArch); | 481 | PackageKit::Transaction * tArch = PackageKit::Daemon::resolve(filter.search, PackageKit::Transaction::FilterArch); | ||
444 | connect(tArch, &PackageKit::Transaction::package, this, &PackageKitBackend::addPackageArch); | 482 | connect(tArch, &PackageKit::Transaction::package, this, &PackageKitBackend::addPackageArch); | ||
445 | connect(tArch, &PackageKit::Transaction::package, stream, [stream](PackageKit::Transaction::Info /*info*/, const QString &packageId){ | 483 | connect(tArch, &PackageKit::Transaction::package, stream, [stream](PackageKit::Transaction::Info /*info*/, const QString &packageId){ | ||
446 | stream->setProperty("packageId", packageId); | 484 | stream->setProperty("packageId", packageId); | ||
447 | }); | 485 | }); | ||
448 | connect(tArch, &PackageKit::Transaction::finished, stream, [stream, ids, this](PackageKit::Transaction::Exit status) { | 486 | connect(tArch, &PackageKit::Transaction::finished, stream, [stream, ids, this](PackageKit::Transaction::Exit status) { | ||
449 | getPackagesFinished(); | 487 | getPackagesFinished(); | ||
450 | if (status == PackageKit::Transaction::Exit::ExitSuccess) { | 488 | if (status == PackageKit::Transaction::Exit::ExitSuccess) { | ||
451 | const auto packageId = stream->property("packageId"); | 489 | const auto packageId = stream->property("packageId"); | ||
452 | if (!packageId.isNull()) { | 490 | if (!packageId.isNull()) { | ||
453 | const auto res = resourcesByPackageNames<QVector<AbstractResource*>>({PackageKit::Daemon::packageName(packageId.toString())}); | 491 | const auto res = resourcesByPackageNames<QVector<AbstractResource*>>({PackageKit::Daemon::packageName(packageId.toString())}); | ||
454 | Q_EMIT stream->resourcesFound(kFilter<QVector<AbstractResource*>>(res, [ids](AbstractResource* res){ return !ids.contains(res->appstreamId()); })); | 492 | Q_EMIT stream->resourcesFound(kFilter<QVector<AbstractResource*>>(res, [ids](AbstractResource* res){ return !ids.contains(res->appstreamId()); })); | ||
455 | } | 493 | } | ||
456 | } | 494 | } | ||
457 | stream->finish(); | 495 | stream->finish(); | ||
458 | }, Qt::QueuedConnection); | 496 | }, Qt::QueuedConnection); | ||
497 | }; | ||||
498 | if (!m_appstreamInitialized) { | ||||
499 | connect(this, &PackageKitBackend::loadedAppStream, stream, f); | ||||
500 | } else { | ||||
501 | QTimer::singleShot(0, this, f); | ||||
broulik: Why is this delayed now? | |||||
It's a quirk of how ResultsStream works. We need the results to be emitted when something is listening to it. If you look at it closely, it was already done before. I'll remove the other delay. apol: It's a quirk of how ResultsStream works. We need the results to be emitted when something is… | |||||
502 | } | ||||
459 | return stream; | 503 | return stream; | ||
460 | } | 504 | } | ||
461 | } | 505 | } | ||
462 | 506 | | |||
463 | ResultsStream * PackageKitBackend::findResourceByPackageName(const QUrl& url) | 507 | ResultsStream * PackageKitBackend::findResourceByPackageName(const QUrl& url) | ||
464 | { | 508 | { | ||
465 | AbstractResource* pkg = nullptr; | | |||
466 | if (url.isLocalFile()) { | 509 | if (url.isLocalFile()) { | ||
467 | QMimeDatabase db; | 510 | QMimeDatabase db; | ||
468 | const auto mime = db.mimeTypeForUrl(url); | 511 | const auto mime = db.mimeTypeForUrl(url); | ||
469 | if ( mime.inherits(QStringLiteral("application/vnd.debian.binary-package")) | 512 | if ( mime.inherits(QStringLiteral("application/vnd.debian.binary-package")) | ||
470 | || mime.inherits(QStringLiteral("application/x-rpm")) | 513 | || mime.inherits(QStringLiteral("application/x-rpm")) | ||
471 | || mime.inherits(QStringLiteral("application/x-tar")) | 514 | || mime.inherits(QStringLiteral("application/x-tar")) | ||
472 | || mime.inherits(QStringLiteral("application/x-xz-compressed-tar")) | 515 | || mime.inherits(QStringLiteral("application/x-xz-compressed-tar")) | ||
473 | ) { | 516 | ) { | ||
474 | pkg = new LocalFilePKResource(url, this); | 517 | return new ResultsStream(QStringLiteral("PackageKitStream-localpkg"), QVector<AbstractResource*>{ new LocalFilePKResource(url, this)}); | ||
475 | } | 518 | } | ||
476 | } else if (url.scheme() == QLatin1String("appstream")) { | 519 | } else if (url.scheme() == QLatin1String("appstream")) { | ||
477 | static const QMap<QString, QString> deprecatedAppstreamIds = { | 520 | static const QMap<QString, QString> deprecatedAppstreamIds = { | ||
478 | { QStringLiteral("org.kde.krita.desktop"), QStringLiteral("krita.desktop") }, | 521 | { QStringLiteral("org.kde.krita.desktop"), QStringLiteral("krita.desktop") }, | ||
479 | { QStringLiteral("org.kde.digikam.desktop"), QStringLiteral("digikam.desktop") }, | 522 | { QStringLiteral("org.kde.digikam.desktop"), QStringLiteral("digikam.desktop") }, | ||
480 | { QStringLiteral("org.kde.ktorrent.desktop"), QStringLiteral("ktorrent.desktop") }, | 523 | { QStringLiteral("org.kde.ktorrent.desktop"), QStringLiteral("ktorrent.desktop") }, | ||
481 | { QStringLiteral("org.kde.gcompris.desktop"), QStringLiteral("gcompris.desktop") }, | 524 | { QStringLiteral("org.kde.gcompris.desktop"), QStringLiteral("gcompris.desktop") }, | ||
482 | { QStringLiteral("org.kde.kmymoney.desktop"), QStringLiteral("kmymoney.desktop") }, | 525 | { QStringLiteral("org.kde.kmymoney.desktop"), QStringLiteral("kmymoney.desktop") }, | ||
483 | { QStringLiteral("org.kde.kolourpaint.desktop"), QStringLiteral("kolourpaint.desktop") }, | 526 | { QStringLiteral("org.kde.kolourpaint.desktop"), QStringLiteral("kolourpaint.desktop") }, | ||
484 | { QStringLiteral("org.blender.blender.desktop"), QStringLiteral("blender.desktop") }, | 527 | { QStringLiteral("org.blender.blender.desktop"), QStringLiteral("blender.desktop") }, | ||
485 | }; | 528 | }; | ||
486 | 529 | | |||
487 | const auto appstreamId = AppStreamUtils::appstreamId(url); | 530 | const auto appstreamId = AppStreamUtils::appstreamId(url); | ||
488 | if (appstreamId.isEmpty()) | 531 | if (appstreamId.isEmpty()) | ||
489 | Q_EMIT passiveMessage(i18n("Malformed appstream url '%1'", url.toDisplayString())); | 532 | Q_EMIT passiveMessage(i18n("Malformed appstream url '%1'", url.toDisplayString())); | ||
490 | else { | 533 | else { | ||
534 | auto stream = new ResultsStream(QStringLiteral("PackageKitStream-appstream-url")); | ||||
535 | const auto f = [this, appstreamId, stream] () { | ||||
536 | AbstractResource* pkg = nullptr; | ||||
491 | const auto deprecatedHost = deprecatedAppstreamIds.value(appstreamId); //try this as fallback | 537 | const auto deprecatedHost = deprecatedAppstreamIds.value(appstreamId); //try this as fallback | ||
492 | for (auto it = m_packages.packages.constBegin(), itEnd = m_packages.packages.constEnd(); it != itEnd; ++it) { | 538 | for (auto it = m_packages.packages.constBegin(), itEnd = m_packages.packages.constEnd(); it != itEnd; ++it) { | ||
493 | if (it.key().compare(appstreamId, Qt::CaseInsensitive) == 0 | 539 | if (it.key().compare(appstreamId, Qt::CaseInsensitive) == 0 | ||
494 | || it.key().compare(deprecatedHost, Qt::CaseInsensitive) == 0 | 540 | || it.key().compare(deprecatedHost, Qt::CaseInsensitive) == 0 | ||
495 | || (appstreamId.endsWith(QLatin1String(".desktop")) && appstreamId.compare(it.key()+QLatin1String(".desktop"), Qt::CaseInsensitive) == 0)) { | 541 | || (appstreamId.endsWith(QLatin1String(".desktop")) && appstreamId.compare(it.key()+QLatin1String(".desktop"), Qt::CaseInsensitive) == 0)) { | ||
496 | pkg = it.value(); | 542 | pkg = it.value(); | ||
497 | break; | 543 | break; | ||
498 | } | 544 | } | ||
499 | } | 545 | } | ||
546 | if (pkg) | ||||
547 | Q_EMIT stream->resourcesFound({pkg}); | ||||
548 | stream->finish(); | ||||
500 | // if (!pkg) | 549 | // if (!pkg) | ||
501 | // qCDebug(LIBDISCOVER_BACKEND_LOG) << "could not find" << host << deprecatedHost; | 550 | // qCDebug(LIBDISCOVER_BACKEND_LOG) << "could not find" << host << deprecatedHost; | ||
551 | }; | ||||
552 | if (!m_appstreamInitialized) { | ||||
553 | connect(this, &PackageKitBackend::loadedAppStream, stream, f); | ||||
554 | } else { | ||||
555 | QTimer::singleShot(0, this, f); | ||||
556 | } | ||||
557 | return stream; | ||||
502 | } | 558 | } | ||
503 | } | 559 | } | ||
504 | return new ResultsStream(QStringLiteral("PackageKitStream-url"), pkg ? QVector<AbstractResource*>{pkg} : QVector<AbstractResource*>{}); | 560 | return new ResultsStream(QStringLiteral("PackageKitStream-unknown-url"), {}); | ||
505 | } | 561 | } | ||
506 | 562 | | |||
507 | bool PackageKitBackend::hasSecurityUpdates() const | 563 | bool PackageKitBackend::hasSecurityUpdates() const | ||
508 | { | 564 | { | ||
509 | return m_hasSecurityUpdates; | 565 | return m_hasSecurityUpdates; | ||
510 | } | 566 | } | ||
511 | 567 | | |||
512 | int PackageKitBackend::updatesCount() const | 568 | int PackageKitBackend::updatesCount() const | ||
▲ Show 20 Lines • Show All 176 Lines • Show Last 20 Lines |
Coding style ..