Audacity 3.2.0
Public Types | Public Member Functions | Public Attributes | List of all members
audacity::cloud::audiocom::anonymous_namespace{UploadService.cpp}::AudiocomUploadOperation Struct Referencefinal
Inheritance diagram for audacity::cloud::audiocom::anonymous_namespace{UploadService.cpp}::AudiocomUploadOperation:
[legend]
Collaboration diagram for audacity::cloud::audiocom::anonymous_namespace{UploadService.cpp}::AudiocomUploadOperation:
[legend]

Public Types

using Clock = std::chrono::steady_clock
 

Public Member Functions

 AudiocomUploadOperation (const ServiceConfig &serviceConfig, wxString fileName, wxString projectName, bool isPublic, UploadService::CompletedCallback completedCallback, UploadService::ProgressCallback progressCallback)
 
void SetRequiredHeaders (audacity::network_manager::Request &request) const
 
void FailPromise (UploadOperationCompleted::Result result, std::string errorMessage)
 
void CompletePromise ()
 
void InitiateUpload (std::string_view authToken)
 
void HandleUploadPolicy (std::string uploadPolicyJSON)
 
void HandleUploadProgress (uint64_t current, uint64_t total)
 
void HandleS3UploadCompleted (std::shared_ptr< audacity::network_manager::IResponse > response)
 
bool IsCompleted () override
 Returns true if the upload is finished. More...
 
void Abort () override
 Abort the upload, if running. More...
 
void DiscardResult () override
 
- Public Member Functions inherited from audacity::cloud::audiocom::UploadOperation
virtual ~UploadOperation ()
 
virtual bool IsCompleted ()=0
 Returns true if the upload is finished. More...
 
virtual void Abort ()=0
 Abort the upload, if running. More...
 
virtual void DiscardResult ()=0
 

Public Attributes

const ServiceConfigmServiceConfig
 
const wxString mFileName
 
const wxString mProjectName
 
const bool mIsPublic
 
UploadService::CompletedCallback mCompletedCallback
 
UploadService::ProgressCallback mProgressCallback
 
std::string mAuthToken
 
std::string mSuccessUrl
 
std::string mFailureUrl
 
std::string mProgressUrl
 
std::string mAudioID
 
std::string mUploadToken
 
std::string mUserName
 
std::string mAudioSlug
 
Clock::time_point mLastProgressReportTime
 
std::mutex mStatusMutex
 
std::mutex mCallbacksMutex
 
std::weak_ptr< audacity::network_manager::IResponsemActiveResponse
 
bool mCompleted {}
 
bool mAborted {}
 

Detailed Description

Definition at line 173 of file UploadService.cpp.

Member Typedef Documentation

◆ Clock

using audacity::cloud::audiocom::anonymous_namespace{UploadService.cpp}::AudiocomUploadOperation::Clock = std::chrono::steady_clock

Definition at line 213 of file UploadService.cpp.

Constructor & Destructor Documentation

◆ AudiocomUploadOperation()

audacity::cloud::audiocom::anonymous_namespace{UploadService.cpp}::AudiocomUploadOperation::AudiocomUploadOperation ( const ServiceConfig serviceConfig,
wxString  fileName,
wxString  projectName,
bool  isPublic,
UploadService::CompletedCallback  completedCallback,
UploadService::ProgressCallback  progressCallback 
)
inline

Member Function Documentation

◆ Abort()

void audacity::cloud::audiocom::anonymous_namespace{UploadService.cpp}::AudiocomUploadOperation::Abort ( )
inlineoverridevirtual

Abort the upload, if running.

Implements audacity::cloud::audiocom::UploadOperation.

Definition at line 521 of file UploadService.cpp.

References audacity::cloud::audiocom::UploadOperationCompleted::Aborted.

◆ CompletePromise()

void audacity::cloud::audiocom::anonymous_namespace{UploadService.cpp}::AudiocomUploadOperation::CompletePromise ( )
inline

Definition at line 257 of file UploadService.cpp.

258 {
259 {
260 std::lock_guard<std::mutex> lock(mStatusMutex);
261 mCompleted = true;
262 }
263
264 std::lock_guard<std::mutex> callbacksLock(mCallbacksMutex);
265
267 {
268 const auto uploadURL =
269 mAuthToken.empty() ?
272
275 UploadSuccessfulPayload { mAudioID, mAudioSlug, mUploadToken, uploadURL } });
276 }
277
280 }
std::string GetFinishUploadPage(std::string_view audioID, std::string_view token) const
Helper to construct the page URL for the anonymous upload last stage.
std::string GetAudioURL(std::string_view userSlug, std::string_view audioSlug) const
Helper to construct the page URL for the authorised upload.

References audacity::cloud::audiocom::ServiceConfig::GetAudioURL(), audacity::cloud::audiocom::ServiceConfig::GetFinishUploadPage(), and audacity::cloud::audiocom::UploadOperationCompleted::Success.

Here is the call graph for this function:

◆ DiscardResult()

void audacity::cloud::audiocom::anonymous_namespace{UploadService.cpp}::AudiocomUploadOperation::DiscardResult ( )
inlineoverridevirtual

Abort the upload, if running, notify audio.com that the uploaded file is no longer needed otherwise

Implements audacity::cloud::audiocom::UploadOperation.

Definition at line 546 of file UploadService.cpp.

547 {
548 using namespace audacity::network_manager;
549
550 Abort();
551
552 auto url = mServiceConfig.GetAPIUrl("/audio");
553 url += "/" + mAudioID + "?token=" + mUploadToken;
554
555 Request request(url);
556 auto response = NetworkManager::GetInstance().doDelete(request);
557
558 response->setRequestFinishedCallback(
559 [response](auto)
560 {
561 // Do nothing
562 });
563 }
std::string GetAPIUrl(std::string_view apiURI) const
Helper to construct the full URLs for the API.
ResponsePtr doDelete(const Request &request)

References audacity::network_manager::NetworkManager::doDelete(), audacity::cloud::audiocom::ServiceConfig::GetAPIUrl(), and audacity::network_manager::NetworkManager::GetInstance().

Here is the call graph for this function:

◆ FailPromise()

void audacity::cloud::audiocom::anonymous_namespace{UploadService.cpp}::AudiocomUploadOperation::FailPromise ( UploadOperationCompleted::Result  result,
std::string  errorMessage 
)
inline

Definition at line 238 of file UploadService.cpp.

239 {
240 {
241 std::lock_guard<std::mutex> lock(mStatusMutex);
242 mCompleted = true;
243 }
244
245 std::lock_guard<std::mutex> callbacksLock(mCallbacksMutex);
246
248 {
250 UploadOperationCompleted { result, ParseUploadFailedMessage(errorMessage) });
251 }
252
255 }
UploadFailedPayload ParseUploadFailedMessage(const std::string &payloadText)

References audacity::cloud::audiocom::anonymous_namespace{UploadService.cpp}::ParseUploadFailedMessage().

Here is the call graph for this function:

◆ HandleS3UploadCompleted()

void audacity::cloud::audiocom::anonymous_namespace{UploadService.cpp}::AudiocomUploadOperation::HandleS3UploadCompleted ( std::shared_ptr< audacity::network_manager::IResponse response)
inline

Definition at line 477 of file UploadService.cpp.

478 {
479 using namespace audacity::network_manager;
480
481 const auto responseCode = response->getHTTPCode();
482
483 const bool success =
484 responseCode == 200 || responseCode == 201 || responseCode == 204;
485
486 Request request(success ? mSuccessUrl : mFailureUrl);
487 SetRequiredHeaders(request);
488
489 std::lock_guard<std::mutex> lock(mStatusMutex);
490
491 if (mAborted)
492 return;
493
494 auto finalResponse = success ? NetworkManager::GetInstance().doPost(request, nullptr, 0) :
496
497 mActiveResponse = finalResponse;
498
499 finalResponse->setRequestFinishedCallback(
500 [finalResponse, sharedThis = shared_from_this(), this, success](auto)
501 {
502 const auto httpCode = finalResponse->getHTTPCode();
503 if (success && httpCode >= 200 && httpCode < 300)
504 {
506 return;
507 }
508
511 finalResponse->readAll<std::string>());
512 });
513 }
ResponsePtr doPost(const Request &request, const void *data, size_t size)
@ UploadFailed
Upload failed for some other reason.
void FailPromise(UploadOperationCompleted::Result result, std::string errorMessage)

References audacity::network_manager::NetworkManager::doDelete(), audacity::network_manager::NetworkManager::doPost(), audacity::network_manager::NetworkManager::GetInstance(), and audacity::cloud::audiocom::UploadOperationCompleted::UploadFailed.

Here is the call graph for this function:

◆ HandleUploadPolicy()

void audacity::cloud::audiocom::anonymous_namespace{UploadService.cpp}::AudiocomUploadOperation::HandleUploadPolicy ( std::string  uploadPolicyJSON)
inline

Definition at line 339 of file UploadService.cpp.

340 {
341 using namespace audacity::network_manager;
342
343 rapidjson::Document document;
344 document.Parse(uploadPolicyJSON.data(), uploadPolicyJSON.length());
345
346 if (
347 !document.HasMember("url") || !document.HasMember("success") ||
348 !document.HasMember("fail") || !document.HasMember("progress"))
349 {
352 uploadPolicyJSON);
353
354 return;
355 }
356
357 auto form = std::make_unique<MultipartData>();
358
359 if (document.HasMember("fields"))
360 {
361 const auto& fields = document["fields"];
362
363 for (auto it = fields.MemberBegin(); it != fields.MemberEnd(); ++it)
364 form->Add(it->name.GetString(), it->value.GetString());
365 }
366
367 const auto fileField =
368 document.HasMember("field") ? document["field"].GetString() : "file";
369
370 const wxFileName name { mFileName };
371
372 try
373 {
374 // We have checked for the file existence on the main thread
375 // already. For safety sake check for any exception thrown by AddFile
376 // anyway
377 form->AddFile(fileField, DeduceMimeType(name.GetExt()), name);
378 }
379 catch (...)
380 {
381 // Just fail the promise in case if any exception was thrown
382 // UploadService user is responsible to display an appropriate dialog
384 return;
385 }
386
387
388 const auto url = document["url"].GetString();
389
390 mSuccessUrl = document["success"].GetString();
391 mFailureUrl = document["fail"].GetString();
392 mProgressUrl = document["progress"].GetString();
393
394 if (document.HasMember("extra"))
395 {
396 const auto& extra = document["extra"];
397
398 mAudioID = extra["audio"]["id"].GetString();
399 mAudioSlug = extra["audio"]["slug"].GetString();
400
401 if (extra.HasMember("token"))
402 mUploadToken = extra["token"].GetString();
403
404 mUserName = extra["audio"]["username"].GetString();
405 }
406
407 const auto encType = document.HasMember("enctype") ?
408 document["enctype"].GetString() :
409 "multipart/form-data";
410
411 Request request(url);
412
413 request.setHeader(common_headers::ContentType, encType);
414 request.setHeader(
416
417 // We only lock late and for very short time
418 std::lock_guard<std::mutex> lock(mStatusMutex);
419
420 if (mAborted)
421 return;
422
423 auto response =
424 NetworkManager::GetInstance().doPost(request, std::move(form));
425
426 mActiveResponse = response;
427
428 response->setRequestFinishedCallback(
429 [response, sharedThis = shared_from_this(), this](auto)
430 {
431 HandleS3UploadCompleted(response);
432 });
433
434 response->setUploadProgressCallback(
435 [response, sharedThis = shared_from_this(),
436 this](auto current, auto total)
437 { HandleUploadProgress(current, total); });
438 }
const TranslatableString name
Definition: Distortion.cpp:76
@ UnexpectedResponse
Audacity has failed to understand audio.com response.
void HandleS3UploadCompleted(std::shared_ptr< audacity::network_manager::IResponse > response)

References audacity::network_manager::common_headers::Accept, audacity::network_manager::common_content_types::ApplicationJson, audacity::network_manager::common_headers::ContentType, audacity::cloud::audiocom::anonymous_namespace{UploadService.cpp}::DeduceMimeType(), audacity::network_manager::NetworkManager::doPost(), audacity::cloud::audiocom::UploadOperationCompleted::FileNotFound, audacity::network_manager::NetworkManager::GetInstance(), name, audacity::network_manager::Request::setHeader(), and audacity::cloud::audiocom::UploadOperationCompleted::UnexpectedResponse.

Here is the call graph for this function:

◆ HandleUploadProgress()

void audacity::cloud::audiocom::anonymous_namespace{UploadService.cpp}::AudiocomUploadOperation::HandleUploadProgress ( uint64_t  current,
uint64_t  total 
)
inline

Definition at line 440 of file UploadService.cpp.

441 {
442 {
443 std::lock_guard<std::mutex> callbacksLock(mCallbacksMutex);
444
446 mProgressCallback(current, total);
447 }
448
449 const auto now = Clock::now();
450
452 {
454
455 using namespace audacity::network_manager;
456 Request request(mProgressUrl);
457
458 request.setHeader(
460 request.setHeader(
462
463 auto payload = GetProgressPayload(current, total);
464
465 std::lock_guard<std::mutex> lock(mStatusMutex);
466
467 if (mAborted)
468 return;
469
470 auto response = NetworkManager::GetInstance().doPatch(
471 request, payload.data(), payload.size());
472
473 response->setRequestFinishedCallback([response](auto) {});
474 }
475 }
std::chrono::milliseconds GetProgressCallbackTimeout() const
Timeout between progress callbacks.
ResponsePtr doPatch(const Request &request, const void *data, size_t size)
std::string GetProgressPayload(uint64_t current, uint64_t total)

References audacity::network_manager::common_headers::Accept, audacity::network_manager::common_content_types::ApplicationJson, audacity::network_manager::common_headers::ContentType, audacity::network_manager::NetworkManager::doPatch(), audacity::network_manager::NetworkManager::GetInstance(), audacity::cloud::audiocom::ServiceConfig::GetProgressCallbackTimeout(), audacity::cloud::audiocom::anonymous_namespace{UploadService.cpp}::GetProgressPayload(), and audacity::network_manager::Request::setHeader().

Here is the call graph for this function:

◆ InitiateUpload()

void audacity::cloud::audiocom::anonymous_namespace{UploadService.cpp}::AudiocomUploadOperation::InitiateUpload ( std::string_view  authToken)
inline

Definition at line 282 of file UploadService.cpp.

283 {
284 using namespace audacity::network_manager;
285
286 Request request(mServiceConfig.GetAPIUrl("/audio"));
287
288 request.setHeader(
290
291 request.setHeader(
293
294 mAuthToken = std::string(authToken);
295 SetRequiredHeaders(request);
296
298
299 std::lock_guard<std::mutex> lock(mStatusMutex);
300
301 // User has already aborted? Do not send the request.
302 if (mAborted)
303 return;
304
305 auto response = NetworkManager::GetInstance().doPost(
306 request, payload.data(), payload.size());
307
308 mActiveResponse = response;
309
310 response->setRequestFinishedCallback(
311 [response, sharedThis = shared_from_this(), this](auto) {
312 auto responseCode = response->getHTTPCode();
313
314 if (responseCode == 201)
315 {
316 HandleUploadPolicy(response->readAll<std::string>());
317 }
318 else if (responseCode == 401)
319 {
322 response->readAll<std::string>());
323 }
324 else if (responseCode == 422)
325 {
328 response->readAll<std::string>());
329 }
330 else
331 {
334 response->readAll<std::string>());
335 }
336 });
337 }
std::string GetUploadRequestPayload(const wxString &filePath, const wxString &projectName, bool isPublic)
@ InvalidData
audio.com has failed to understand what Audacity wants

References audacity::network_manager::common_headers::Accept, audacity::network_manager::common_content_types::ApplicationJson, audacity::network_manager::common_headers::ContentType, audacity::network_manager::NetworkManager::doPost(), audacity::cloud::audiocom::ServiceConfig::GetAPIUrl(), audacity::network_manager::NetworkManager::GetInstance(), audacity::cloud::audiocom::anonymous_namespace{UploadService.cpp}::GetUploadRequestPayload(), audacity::cloud::audiocom::UploadOperationCompleted::InvalidData, audacity::network_manager::Request::setHeader(), audacity::cloud::audiocom::UploadOperationCompleted::Unauthorized, and audacity::cloud::audiocom::UploadOperationCompleted::UnexpectedResponse.

Here is the call graph for this function:

◆ IsCompleted()

bool audacity::cloud::audiocom::anonymous_namespace{UploadService.cpp}::AudiocomUploadOperation::IsCompleted ( )
inlineoverridevirtual

Returns true if the upload is finished.

Implements audacity::cloud::audiocom::UploadOperation.

Definition at line 515 of file UploadService.cpp.

516 {
517 std::lock_guard<std::mutex> lock(mStatusMutex);
518 return mCompleted;
519 }

◆ SetRequiredHeaders()

void audacity::cloud::audiocom::anonymous_namespace{UploadService.cpp}::AudiocomUploadOperation::SetRequiredHeaders ( audacity::network_manager::Request request) const
inline

Definition at line 224 of file UploadService.cpp.

225 {
226 if (!mAuthToken.empty())
227 request.setHeader(
229
230 const auto language = mServiceConfig.GetAcceptLanguageValue();
231
232 if (!language.empty())
233 request.setHeader(
235 language);
236 }
std::string GetAcceptLanguageValue() const
Returns the preferred language.
Request & setHeader(const std::string &name, std::string value)
Definition: Request.cpp:46

References audacity::network_manager::common_headers::AcceptLanguage, audacity::network_manager::common_headers::Authorization, audacity::cloud::audiocom::ServiceConfig::GetAcceptLanguageValue(), and audacity::network_manager::Request::setHeader().

Here is the call graph for this function:

Member Data Documentation

◆ mAborted

bool audacity::cloud::audiocom::anonymous_namespace{UploadService.cpp}::AudiocomUploadOperation::mAborted {}

Definition at line 222 of file UploadService.cpp.

◆ mActiveResponse

std::weak_ptr<audacity::network_manager::IResponse> audacity::cloud::audiocom::anonymous_namespace{UploadService.cpp}::AudiocomUploadOperation::mActiveResponse

Definition at line 220 of file UploadService.cpp.

◆ mAudioID

std::string audacity::cloud::audiocom::anonymous_namespace{UploadService.cpp}::AudiocomUploadOperation::mAudioID

Definition at line 207 of file UploadService.cpp.

◆ mAudioSlug

std::string audacity::cloud::audiocom::anonymous_namespace{UploadService.cpp}::AudiocomUploadOperation::mAudioSlug

Definition at line 211 of file UploadService.cpp.

◆ mAuthToken

std::string audacity::cloud::audiocom::anonymous_namespace{UploadService.cpp}::AudiocomUploadOperation::mAuthToken

Definition at line 201 of file UploadService.cpp.

◆ mCallbacksMutex

std::mutex audacity::cloud::audiocom::anonymous_namespace{UploadService.cpp}::AudiocomUploadOperation::mCallbacksMutex
mutable

Definition at line 218 of file UploadService.cpp.

◆ mCompleted

bool audacity::cloud::audiocom::anonymous_namespace{UploadService.cpp}::AudiocomUploadOperation::mCompleted {}

Definition at line 221 of file UploadService.cpp.

◆ mCompletedCallback

UploadService::CompletedCallback audacity::cloud::audiocom::anonymous_namespace{UploadService.cpp}::AudiocomUploadOperation::mCompletedCallback

Definition at line 198 of file UploadService.cpp.

◆ mFailureUrl

std::string audacity::cloud::audiocom::anonymous_namespace{UploadService.cpp}::AudiocomUploadOperation::mFailureUrl

Definition at line 204 of file UploadService.cpp.

◆ mFileName

const wxString audacity::cloud::audiocom::anonymous_namespace{UploadService.cpp}::AudiocomUploadOperation::mFileName

Definition at line 193 of file UploadService.cpp.

◆ mIsPublic

const bool audacity::cloud::audiocom::anonymous_namespace{UploadService.cpp}::AudiocomUploadOperation::mIsPublic

Definition at line 196 of file UploadService.cpp.

◆ mLastProgressReportTime

Clock::time_point audacity::cloud::audiocom::anonymous_namespace{UploadService.cpp}::AudiocomUploadOperation::mLastProgressReportTime

Definition at line 215 of file UploadService.cpp.

◆ mProgressCallback

UploadService::ProgressCallback audacity::cloud::audiocom::anonymous_namespace{UploadService.cpp}::AudiocomUploadOperation::mProgressCallback

Definition at line 199 of file UploadService.cpp.

◆ mProgressUrl

std::string audacity::cloud::audiocom::anonymous_namespace{UploadService.cpp}::AudiocomUploadOperation::mProgressUrl

Definition at line 205 of file UploadService.cpp.

◆ mProjectName

const wxString audacity::cloud::audiocom::anonymous_namespace{UploadService.cpp}::AudiocomUploadOperation::mProjectName

Definition at line 194 of file UploadService.cpp.

◆ mServiceConfig

const ServiceConfig& audacity::cloud::audiocom::anonymous_namespace{UploadService.cpp}::AudiocomUploadOperation::mServiceConfig

Definition at line 191 of file UploadService.cpp.

◆ mStatusMutex

std::mutex audacity::cloud::audiocom::anonymous_namespace{UploadService.cpp}::AudiocomUploadOperation::mStatusMutex
mutable

Definition at line 217 of file UploadService.cpp.

◆ mSuccessUrl

std::string audacity::cloud::audiocom::anonymous_namespace{UploadService.cpp}::AudiocomUploadOperation::mSuccessUrl

Definition at line 203 of file UploadService.cpp.

◆ mUploadToken

std::string audacity::cloud::audiocom::anonymous_namespace{UploadService.cpp}::AudiocomUploadOperation::mUploadToken

Definition at line 208 of file UploadService.cpp.

◆ mUserName

std::string audacity::cloud::audiocom::anonymous_namespace{UploadService.cpp}::AudiocomUploadOperation::mUserName

Definition at line 209 of file UploadService.cpp.


The documentation for this struct was generated from the following file: