16#include "../OAuthService.h"
17#include "../ServiceConfig.h"
64 std::vector<std::pair<int64_t, std::string>>
NewHashes;
70 std::function<
void()> onBlocksLocked)
82 Hasher = std::make_unique<BlockHasher>();
94 const auto id = pBlock->GetBlockID();
98 id, pBlock->GetSampleFormat(), pBlock });
116 const auto result =
Hasher->TakeResult();
118 for (
auto [
id, hash] : result)
135 Blocks[it->second].Hash = std::move(hash);
160 bool GetHash(int64_t blockId, std::string& hash)
const override
171 hash = std::move(*cachedResult);
176 void UpdateHash(int64_t blockId,
const std::string& hash)
override
183 for (
const auto& urls : missingBlockUrls)
193 const auto index = it->second;
206 , mServiceConfig { config }
207 , mOAuthService { oauthService }
208 , mAudiocomTrace { trace }
209 , mProjectName {
std::move(
name) }
210 , mUploadMode { mode }
211 , mCancellationContext { concurrency::CancellationContext::Create() }
229 auto snapshot = std::make_shared<LocalProjectSnapshot>(
232 snapshot->mProjectCloudExtension.OnUploadOperationCreated(snapshot);
234 snapshot->mProjectBlocksLock = std::make_unique<ProjectBlocksLock>(
236 [weakSnapshot = std::weak_ptr(snapshot)]
238 auto snapshot = weakSnapshot.lock();
240 if (snapshot ==
nullptr)
243 auto project = snapshot->GetProject();
248 snapshot->mProjectCloudExtension.OnBlocksHashed(*snapshot);
251 return snapshot->mCreateSnapshotPromise.get_future();
256 return mCompleted.load(std::memory_order_acquire);
277 mCancelled.store(
true, std::memory_order_release);
289 mCancelled.store(
true, std::memory_order_release);
303 if (!
mCompleted.exchange(
true, std::memory_order_release))
318 for (
const auto& uploadError : uploadResult.
UploadErrors)
325 const auto deducedError =
DeduceError(uploadError.Code);
331 errorType = deducedError;
337 errorType = deducedError;
352 XO(
"Project was closed before snapshot was created")));
357 const bool createNew =
373 std::back_inserter(projectForm.
Hashes),
374 [](
const auto& block) { return block.Hash; });
395 if (!language.empty())
402 auto serializedForm =
Serialize(projectForm);
405 request, serializedForm.data(), serializedForm.size());
407 response->setRequestFinishedCallback(
408 [
this, response, createNew, weakThis = weak_from_this()](
auto)
410 auto strongThis = weakThis.lock();
414 const auto error = response->getError();
416 if (error != NetworkError::NoError)
424 const auto body = response->readAll<std::string>();
430 XO(
"Invalid Response: %s").
Format(body).Translation()));
450 XO(
"Project was closed before snapshot was created")));
470 if (
mCancelled.load(std::memory_order_acquire))
477 projectData.ProjectSnapshot,
480 auto strongThis = weakThis.lock();
491 db.RemovePendingSnapshot(projectId, snapshotId);
492 db.RemovePendingProjectBlob(projectId, snapshotId);
493 db.RemovePendingProjectBlocks(projectId, snapshotId);
500 db.RemovePendingProjectBlob(projectId, snapshotId);
511 [
this, weakThis = weak_from_this()](
512 auto result,
auto block,
auto uploadResult)
514 auto strongThis = weakThis.lock();
526 const auto completed =
527 result.UploadedBlocks == result.TotalBlocks ||
528 result.FailedBlocks != 0;
529 const bool succeeded = completed && result.FailedBlocks == 0;
559 std::vector<PendingProjectBlockData> pendingBlocks;
566 block.BlockUrls.SuccessUrl, block.BlockUrls.FailUrl, block.Block.Id,
567 static_cast<int>(block.Block.Format), block.Block.Hash });
575 using namespace network_manager;
584 response->setRequestFinishedCallback(
585 [
this, response, weakThis = weak_from_this()](
auto)
587 auto strongThis = weakThis.lock();
595 if (response->getError() != NetworkError::NoError)
601 mCompleted.store(
true, std::memory_order_release);
613 using namespace network_manager;
623 response->setRequestFinishedCallback(
624 [
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
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
LocalProjectSnapshot(Tag, const ServiceConfig &config, const OAuthService &oauthService, ProjectCloudExtension &extension, std::string name, UploadMode mode, AudiocomTrace trace)
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)
const AudiocomTrace mAudiocomTrace
std::unique_ptr< ProjectBlocksLock > mProjectBlocksLock
void MarkSnapshotSynced()
std::optional< CreateSnapshotResponse > mCreateSnapshotResponse
ProjectCloudExtension & mProjectCloudExtension
static Future Create(const ServiceConfig &config, const OAuthService &oauthService, ProjectCloudExtension &extension, std::string name, UploadMode mode, AudiocomTrace trace)
const ServiceConfig & mServiceConfig
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 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.
void OnSyncCompleted(const ProjectUploadOperation *uploadOperation, std::optional< CloudSyncError > error, AudiocomTrace trace)
This method is called from any 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