16#include "../OAuthService.h"
17#include "../ServiceConfig.h"
63 std::vector<std::pair<int64_t, std::string>>
NewHashes;
69 std::function<
void()> onBlocksLocked)
81 Hasher = std::make_unique<BlockHasher>();
93 const auto id = pBlock->GetBlockID();
95 id, pBlock->GetSampleFormat(), pBlock });
105 const auto result =
Hasher->TakeResult();
107 for (
auto [
id, hash] : result)
124 Blocks[it->second].Hash = std::move(hash);
149 bool GetHash(int64_t blockId, std::string& hash)
const override
160 hash = std::move(*cachedResult);
165 void UpdateHash(int64_t blockId,
const std::string& hash)
override
172 for (
const auto& urls : missingBlockUrls)
182 const auto index = it->second;
194 , mServiceConfig { config }
195 , mOAuthService { oauthService }
196 , mProjectName {
std::move(
name) }
197 , mUploadMode { mode }
198 , mCancellationContext { concurrency::CancellationContext::Create() }
215 auto snapshot = std::make_shared<LocalProjectSnapshot>(
218 snapshot->mProjectCloudExtension.OnUploadOperationCreated(snapshot);
220 snapshot->mProjectBlocksLock = std::make_unique<ProjectBlocksLock>(
222 [weakSnapshot = std::weak_ptr(snapshot)]
224 auto snapshot = weakSnapshot.lock();
226 if (snapshot ==
nullptr)
229 auto project = snapshot->GetProject();
234 snapshot->mProjectCloudExtension.OnBlocksHashed(*snapshot);
237 return snapshot->mCreateSnapshotPromise.get_future();
242 return mCompleted.load(std::memory_order_acquire);
263 mCancelled.store(
true, std::memory_order_release);
275 mCancelled.store(
true, std::memory_order_release);
289 if (!
mCompleted.exchange(
true, std::memory_order_release))
303 for (
const auto& uploadError : uploadResult.
UploadErrors)
310 const auto deducedError =
DeduceError(uploadError.Code);
316 errorType = deducedError;
322 errorType = deducedError;
337 XO(
"Project was closed before snapshot was created")));
342 const bool createNew =
358 std::back_inserter(projectForm.
Hashes),
359 [](
const auto& block) { return block.Hash; });
380 if (!language.empty())
387 auto serializedForm =
Serialize(projectForm);
390 request, serializedForm.data(), serializedForm.size());
392 response->setRequestFinishedCallback(
393 [
this, response, createNew, weakThis = weak_from_this()](
auto)
395 auto strongThis = weakThis.lock();
399 const auto error = response->getError();
401 if (error != NetworkError::NoError)
409 const auto body = response->readAll<std::string>();
415 XO(
"Invalid Response: %s").
Format(body).Translation()));
435 XO(
"Project was closed before snapshot was created")));
455 if (
mCancelled.load(std::memory_order_acquire))
462 projectData.ProjectSnapshot,
465 auto strongThis = weakThis.lock();
476 db.RemovePendingSnapshot(projectId, snapshotId);
477 db.RemovePendingProjectBlob(projectId, snapshotId);
478 db.RemovePendingProjectBlocks(projectId, snapshotId);
485 db.RemovePendingProjectBlob(projectId, snapshotId);
496 [
this, weakThis = weak_from_this()](
497 auto result,
auto block,
auto uploadResult)
499 auto strongThis = weakThis.lock();
511 const auto completed =
512 result.UploadedBlocks == result.TotalBlocks ||
513 result.FailedBlocks != 0;
514 const bool succeeded = completed && result.FailedBlocks == 0;
544 std::vector<PendingProjectBlockData> pendingBlocks;
551 block.BlockUrls.SuccessUrl, block.BlockUrls.FailUrl, block.Block.Id,
552 static_cast<int>(block.Block.Format), block.Block.Hash });
560 using namespace network_manager;
569 response->setRequestFinishedCallback(
570 [
this, response, weakThis = weak_from_this()](
auto)
572 auto strongThis = weakThis.lock();
580 if (response->getError() != NetworkError::NoError)
586 mCompleted.store(
true, std::memory_order_release);
598 using namespace network_manager;
608 response->setRequestFinishedCallback(
609 [
this, response, strongThis = shared_from_this()](
auto)
Toolkit-neutral facade for basic user interface services.
std::shared_ptr< SampleBlock > SampleBlockPtr
std::unordered_set< SampleBlockID > SampleBlockIDSet
const TranslatableString name
Declare an interface for HTTP response.
Declare a class for performing HTTP requests.
Declare a class for constructing HTTP requests.
std::string ToUpper(const std::string &str)
declares abstract base class Track, TrackList, and iterators over TrackList
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
A flat linked list of tracks supporting Add, Remove, Clear, and Contains, serialization of the list o...
static TrackList & Get(AudacityProject &project)
Service responsible for OAuth authentication against the audio.com service.
std::string GetAccessToken() const
Return the current access token, if any.
Configuration for the audio.com.
std::string GetCreateSnapshotUrl(std::string_view projectId) const
std::string GetCreateProjectUrl() const
std::string GetDeleteSnapshotUrl(std::string_view projectId, std::string_view snapshotId) const
std::string GetAcceptLanguageValue() const
Returns the preferred language.
std::string GetSnapshotSyncUrl(std::string_view projectId, std::string_view snapshotId) const
void UpdateBlockHashes(std::string_view projectId, const std::vector< std::pair< int64_t, std::string > > &hashes)
std::optional< std::string > GetBlockHash(std::string_view projectId, int64_t blockId) const
void AddPendingSnapshot(const PendingSnapshotData &snapshotData)
static CloudProjectsDatabase & Get()
void UpdateProjectBlockList(std::string_view projectId, const SampleBlockIDSet &blockSet)
void RemovePendingProjectBlock(std::string_view projectId, int64_t blockId)
void AddPendingProjectBlocks(const std::vector< PendingProjectBlockData > &blockData)
void AddPendingProjectBlob(const PendingProjectBlobData &blobData)
void RemovePendingSnapshot(std::string_view projectId, std::string_view snapshotId)
static DataUploader & Get()
void Upload(CancellationContextPtr cancellationContex, const ServiceConfig &config, const UploadUrls &target, std::vector< uint8_t > data, std::function< void(ResponseResult)> callback, std::function< void(double)> progressCallback={})
Promise mCreateSnapshotPromise
std::atomic< bool > mCancelled
std::promise< ProjectUploadData > mProjectDataPromise
std::atomic< bool > mCompleted
void DataUploadFailed(const ResponseResult &uploadResult)
std::mutex mCreateSnapshotResponseMutex
~LocalProjectSnapshot() override
void OnSnapshotCreated(const CreateSnapshotResponse &response, bool newProject)
std::weak_ptr< AudacityProject > mWeakProject
std::atomic< bool > mProjectDataReady
std::future< SnapshotData > Future
void UploadFailed(CloudSyncError error)
bool IsCompleted() const override
void UpdateProjectSnapshot()
void StorePendingSnapshot(const CreateSnapshotResponse &response, const ProjectUploadData &data)
std::unique_ptr< ProjectBlocksLock > mProjectBlocksLock
void MarkSnapshotSynced()
std::optional< CreateSnapshotResponse > mCreateSnapshotResponse
ProjectCloudExtension & mProjectCloudExtension
const ServiceConfig & mServiceConfig
LocalProjectSnapshot(Tag, const ServiceConfig &config, const OAuthService &oauthService, ProjectCloudExtension &extension, std::string name, UploadMode mode)
static Future Create(const ServiceConfig &config, const OAuthService &oauthService, ProjectCloudExtension &extension, std::string name, UploadMode mode)
std::shared_ptr< AudacityProject > GetProject()
void SetUploadData(const ProjectUploadData &data) override
std::shared_ptr< MissingBlocksUploader > mMissingBlockUploader
const OAuthService & mOAuthService
concurrency::CancellationContextPtr mCancellationContext
static std::shared_ptr< MissingBlocksUploader > Create(CancellationContextPtr cancellationContex, const ServiceConfig &serviceConfig, std::vector< BlockUploadTask > uploadTasks, MissingBlocksUploadProgressCallback progress)
std::string GetSnapshotId() const
std::string GetCloudProjectId() const
void OnSyncCompleted(const ProjectUploadOperation *uploadOperation, std::optional< CloudSyncError > error)
This method is called from any thread.
void OnSnapshotCreated(const ProjectUploadOperation &uploadOperation, const CreateSnapshotResponse &response)
This method is called from the network thread.
void OnProjectDataUploaded(const ProjectUploadOperation &uploadOperation)
This method is called from the network thread.
void OnBlockUploaded(const ProjectUploadOperation &uploadOperation, std::string_view blockID, bool successful)
This method is called from the network thread.
bool IsCloudProject() const
static NetworkManager & GetInstance()
ResponsePtr doPost(const Request &request, const void *data, size_t size)
ResponsePtr doDelete(const Request &request)
WAVE_TRACK_API void VisitBlocks(TrackList &tracks, BlockVisitor visitor, SampleBlockIDSet *pIDs=nullptr)
ProjectFileIOExtensionRegistry::Extension extension
const AudacityProject & GetProject(const Track &track)
CloudSyncError::ErrorType DeduceError(SyncResultCode code)
std::string Serialize(const ProjectForm &form)
CloudSyncError MakeClientFailure(const TranslatableString &message)
CLOUD_AUDIOCOM_API CloudSyncError DeduceUploadError(audacity::network_manager::IResponse &response)
std::optional< CreateSnapshotResponse > DeserializeCreateSnapshotResponse(const std::string &data)
bool IsUploadRecoverable(SyncResultCode code)
void SetCommonHeaders(Request &request)
const std::string ApplicationJson
std::string sha256(const T &data)
@ ProjectStorageLimitReached
ProjectSyncState SyncState
void UpdateProjectHashesInCache()
std::unordered_map< std::string, size_t > BlockHashToIndex
ProjectCloudExtension & Extension
void UpdateHash(int64_t blockId, const std::string &hash) override
std::unique_ptr< BlockHasher > Hasher
std::vector< std::pair< int64_t, std::string > > NewHashes
SampleBlockIDSet BlockIds
std::unordered_map< int64_t, size_t > BlockIdToIndex
void VisitBlocks(TrackList &tracks)
bool GetHash(int64_t blockId, std::string &hash) const override
std::vector< LockedBlock > Blocks
std::vector< BlockUploadTask > MissingBlocks
std::future< void > UpdateCacheFuture
ProjectBlocksLock(ProjectCloudExtension &extension, AudacityProject &project, std::function< void()> onBlocksLocked)
std::function< void()> OnBlocksLocked
void FillMissingBlocks(const std::vector< UploadUrls > &missingBlockUrls)
~ProjectBlocksLock() override
std::vector< ResponseResult > UploadErrors
std::vector< UploadUrls > MissingBlocks
std::vector< uint8_t > ProjectSnapshot