| 76 | } |
| 77 | |
| 78 | Task::Ptr ResourceAPI::getProjectVersions(VersionSearchArgs&& args, Callback<QVector<ModPlatform::IndexedVersion>>&& callbacks) const |
| 79 | { |
| 80 | auto versions_url_optional = getVersionsURL(args); |
| 81 | if (!versions_url_optional.has_value()) |
| 82 | return nullptr; |
| 83 | |
| 84 | auto versions_url = versions_url_optional.value(); |
| 85 | |
| 86 | auto netJob = makeShared<NetJob>(QString("%1::Versions").arg(args.pack->name), APPLICATION->network()); |
| 87 | |
| 88 | auto [action, response] = Net::ApiDownload::makeByteArray(versions_url); |
| 89 | netJob->addNetAction(action); |
| 90 | |
| 91 | QObject::connect(netJob.get(), &NetJob::succeeded, [this, response, callbacks, args] { |
| 92 | QJsonParseError parse_error{}; |
| 93 | QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); |
| 94 | if (parse_error.error != QJsonParseError::NoError) { |
| 95 | qWarning() << "Error while parsing JSON response for getting versions at" << parse_error.offset |
| 96 | << "reason:" << parse_error.errorString(); |
| 97 | qWarning() << *response; |
| 98 | return; |
| 99 | } |
| 100 | |
| 101 | QVector<ModPlatform::IndexedVersion> unsortedVersions; |
| 102 | try { |
| 103 | auto arr = doc.isObject() ? doc.object()["data"].toArray() : doc.array(); |
| 104 | |
| 105 | for (auto versionIter : arr) { |
| 106 | auto obj = versionIter.toObject(); |
| 107 | |
| 108 | auto file = loadIndexedPackVersion(obj, args.resourceType); |
| 109 | if (!file.addonId.isValid()) { |
| 110 | file.addonId = args.pack->addonId; |
| 111 | } |
| 112 | |
| 113 | if (file.fileId.isValid() && !file.downloadUrl.isEmpty()) { // Heuristic to check if the returned value is valid |
| 114 | unsortedVersions.append(file); |
| 115 | } |
| 116 | } |
| 117 | |
| 118 | auto orderSortPredicate = [](const ModPlatform::IndexedVersion& a, const ModPlatform::IndexedVersion& b) -> bool { |
| 119 | // dates are in RFC 3339 format |
| 120 | return a.date > b.date; |
| 121 | }; |
| 122 | std::sort(unsortedVersions.begin(), unsortedVersions.end(), orderSortPredicate); |
| 123 | } catch (const JSONValidationError& e) { |
| 124 | qDebug() << doc; |
| 125 | qWarning() << "Error while reading" << debugName() << "resource version:" << e.cause(); |
| 126 | } |
| 127 | |
| 128 | callbacks.on_succeed(unsortedVersions); |
| 129 | }); |
| 130 | |
| 131 | // Capture a weak_ptr instead of a shared_ptr to avoid circular dependency issues. |
| 132 | // This prevents the lambda from extending the lifetime of the shared resource, |
| 133 | // as it only temporarily locks the resource when needed. |
| 134 | auto weak = netJob.toWeakRef(); |
| 135 | QObject::connect(netJob.get(), &NetJob::failed, [weak, callbacks](const QString& reason) { |
no test coverage detected