| 332 | } |
| 333 | |
| 334 | std::string CmdDeleteRemoteApp(const std::string& provider, const std::string& accountId, const std::string& appId) { |
| 335 | std::string tokenPath = GetTokenPath(provider); |
| 336 | if (tokenPath.empty()) { |
| 337 | return JsonError("Cannot determine config directory"); |
| 338 | } |
| 339 | |
| 340 | auto prov = CreateCloudProvider(provider); |
| 341 | if (!prov) { |
| 342 | return JsonError("Unknown provider: " + provider); |
| 343 | } |
| 344 | |
| 345 | if (!prov->Init(tokenPath)) { |
| 346 | return JsonError("Failed to initialize provider"); |
| 347 | } |
| 348 | |
| 349 | if (!prov->IsAuthenticated()) { |
| 350 | prov->Shutdown(); |
| 351 | return JsonError("Not authenticated"); |
| 352 | } |
| 353 | |
| 354 | // List all files under accountId/appId/ and delete them |
| 355 | std::string prefix = accountId + "/" + appId + "/"; |
| 356 | auto files = prov->List(prefix); |
| 357 | |
| 358 | int deleted = 0; |
| 359 | int failed = 0; |
| 360 | for (const auto& f : files) { |
| 361 | if (prov->Remove(f.path)) { |
| 362 | deleted++; |
| 363 | } else { |
| 364 | failed++; |
| 365 | } |
| 366 | } |
| 367 | |
| 368 | prov->Shutdown(); |
| 369 | |
| 370 | return JsonObject({ |
| 371 | {"success", JsonBool(failed == 0)}, |
| 372 | {"deleted", JsonInt(deleted)}, |
| 373 | {"failed", JsonInt(failed)} |
| 374 | }); |
| 375 | } |
| 376 | |
| 377 | std::string CmdListBlobs(const std::string& provider, const std::string& accountId, const std::string& appId) { |
| 378 | std::string tokenPath = GetTokenPath(provider); |
no test coverage detected