* @brief Downloads and installs the currently selected addon. */
| 534 | * @brief Downloads and installs the currently selected addon. |
| 535 | */ |
| 536 | void Misc::ExtensionManager::installExtension() |
| 537 | { |
| 538 | if (m_loading) |
| 539 | return; |
| 540 | |
| 541 | if (m_selectedIndex < 0 || m_selectedIndex >= m_filteredExtensions.count()) |
| 542 | return; |
| 543 | |
| 544 | const auto addon = m_filteredExtensions.at(m_selectedIndex).toMap(); |
| 545 | const auto id = addon.value("id").toString(); |
| 546 | const auto type = addon.value("type").toString(); |
| 547 | const auto base = addon.value("_repoBase").toString(); |
| 548 | const auto isLocal = addon.value("_isLocal").toBool(); |
| 549 | |
| 550 | auto files = addon.value("files").toList(); |
| 551 | const auto platforms = addon.value("platforms").toMap(); |
| 552 | const auto override = selectPlatformOverride(platforms, currentPlatformKey()); |
| 553 | const auto platFiles = override.value("files").toList(); |
| 554 | for (const auto& f : platFiles) |
| 555 | if (!files.contains(f)) |
| 556 | files.append(f); |
| 557 | |
| 558 | if (id.isEmpty() || files.isEmpty()) |
| 559 | return; |
| 560 | |
| 561 | if (id.contains("..") || id.contains('/') || id.contains('\\')) |
| 562 | return; |
| 563 | |
| 564 | if (type.contains("..") || type.contains('/') || type.contains('\\')) |
| 565 | return; |
| 566 | |
| 567 | const auto installDir = extensionsPath() + "/" + type + "/" + id; |
| 568 | QDir().mkpath(installDir); |
| 569 | |
| 570 | if (isLocal) { |
| 571 | for (const auto& f : std::as_const(files)) { |
| 572 | const auto localName = f.toString(); |
| 573 | const auto dst = installDir + "/" + localName; |
| 574 | |
| 575 | if (!isPathSafe(dst, installDir)) |
| 576 | continue; |
| 577 | |
| 578 | const auto src = base + localName; |
| 579 | QDir().mkpath(QFileInfo(dst).absolutePath()); |
| 580 | QFile::copy(src, dst); |
| 581 | } |
| 582 | |
| 583 | QJsonObject info; |
| 584 | info.insert("version", addon.value("version").toString()); |
| 585 | info.insert("type", type); |
| 586 | info.insert("repoBase", base); |
| 587 | m_installedExtensions.insert(id, info); |
| 588 | saveInstalledManifest(); |
| 589 | |
| 590 | Q_EMIT extensionInstalled(id); |
| 591 | m_pluginMetadataCache.remove(id); |
| 592 | applyFilter(); |
| 593 | rebuildInstalledPlugins(); |