Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
crsib committed Feb 21, 2024
1 parent 45a9e28 commit 9267d91
Show file tree
Hide file tree
Showing 8 changed files with 149 additions and 71 deletions.
76 changes: 42 additions & 34 deletions libraries/lib-cloud-audiocom/ServiceConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,18 @@

#include <rapidjson/document.h>

#include "Prefs.h"
#include "CodeConversions.h"


#include "Prefs.h"

namespace cloud::audiocom
{
namespace
{
StringSetting audioComApiEndpoint {
L"/CloudServices/AudioCom/ApiEndpoint",
L"https://api.audio.com"
};
StringSetting audioComApiEndpoint { L"/CloudServices/AudioCom/ApiEndpoint",
L"https://api.audio.com" };

StringSetting audioComOAuthClientID {
L"/CloudServices/AudioCom/OAuthClientID",
L"1741964426607541"
};
StringSetting audioComOAuthClientID { L"/CloudServices/AudioCom/OAuthClientID",
L"1741964426607541" };

StringSetting audioComOAuthClientSecret {
L"/CloudServices/AudioCom/OAuthClientSecret",
Expand All @@ -56,19 +50,19 @@ StringSetting audioComFinishUploadPage {
L"https://audio.com/audacity/upload?audioId={audio_id}&token={auth_token}&clientId={auth_client_id}"
};

StringSetting audioComAudioURL {
L"/CloudServices/AudioCom/AudioURL",
L"https://audio.com/{user_slug}/audio/{audio_slug}/edit"
};
StringSetting audioComFrontendUrl { L"/CloudServices/AudioCom/FrontendURL",
L"https://audio.com" };

StringSetting audioComAudioDownloadMimeType {
L"/CloudServices/AudioCom/DownloadMimeType",
L"audio/x-wav"
L"/CloudServices/AudioCom/DownloadMimeType", L"audio/x-wav"
};

std::string Substitute(std::string pattern, std::initializer_list<std::pair<std::string_view, std::string_view>> substitutions)
std::string Substitute(
std::string pattern,
std::initializer_list<std::pair<std::string_view, std::string_view>>
substitutions)
{
for(auto& [key, value] : substitutions)
for (auto& [key, value] : substitutions)
{
auto pos = pattern.find(key);

Expand All @@ -90,13 +84,13 @@ std::string Substitute(std::string pattern, std::initializer_list<std::pair<std:

ServiceConfig::ServiceConfig()
{
mApiEndpoint = audacity::ToUTF8(audioComApiEndpoint.Read());
mOAuthClientID = audacity::ToUTF8(audioComOAuthClientID.Read());
mApiEndpoint = audacity::ToUTF8(audioComApiEndpoint.Read());
mOAuthClientID = audacity::ToUTF8(audioComOAuthClientID.Read());
mOAuthClientSecret = audacity::ToUTF8(audioComOAuthClientSecret.Read());
mOAuthRedirectURL = audacity::ToUTF8(audioComOAuthRedirectURL.Read());
mOAuthLoginPage = audacity::ToUTF8(audioComOAuthLoginPage.Read());
mFinishUploadPage = audacity::ToUTF8(audioComFinishUploadPage.Read());
mAudioURL = audacity::ToUTF8(audioComAudioURL.Read());
mOAuthRedirectURL = audacity::ToUTF8(audioComOAuthRedirectURL.Read());
mOAuthLoginPage = audacity::ToUTF8(audioComOAuthLoginPage.Read());
mFinishUploadPage = audacity::ToUTF8(audioComFinishUploadPage.Read());
mFrontendURL = audacity::ToUTF8(audioComFrontendUrl.Read());
mPreferredMimeType = audacity::ToUTF8(audioComAudioDownloadMimeType.Read());
}

Expand Down Expand Up @@ -144,7 +138,10 @@ std::string ServiceConfig::GetAudioURL(
std::string_view userSlug, std::string_view audioSlug) const
{
return Substitute(
mAudioURL, { { "user_slug", userSlug }, { "audio_slug", audioSlug } });
"{frontend_url}/{user_slug}/audio/{audio_slug}/edit",
{ { "frontend_url", mFrontendURL },
{ "user_slug", userSlug },
{ "audio_slug", audioSlug } });
}

std::chrono::milliseconds ServiceConfig::GetProgressCallbackTimeout() const
Expand Down Expand Up @@ -198,7 +195,6 @@ ServiceConfig::GetExportConfig(const std::string& mimeType) const
throw std::invalid_argument("unknown mime-type");
}


std::string ServiceConfig::GetDownloadMime() const
{
return mPreferredMimeType;
Expand All @@ -209,7 +205,9 @@ std::string ServiceConfig::GetAcceptLanguageValue() const
auto language = Languages::GetLang();

if (language.Contains(L"-") && language.Length() > 2)
return wxString::Format("%s;q=1.0, %s;q=0.7, *;q=0.5", language, language.Left(2)).ToStdString();
return wxString::Format(
"%s;q=1.0, %s;q=0.7, *;q=0.5", language, language.Left(2))
.ToStdString();
else
return wxString::Format("%s;q=1.0, *;q=0.5", language).ToStdString();
}
Expand All @@ -222,7 +220,8 @@ std::string ServiceConfig::GetCreateProjectUrl() const
std::string
ServiceConfig::GetCreateSnapshotUrl(std::string_view projectId) const
{
return Substitute("{api_url}/project/{project_id}/snapshot",
return Substitute(
"{api_url}/project/{project_id}/snapshot",
{ { "api_url", mApiEndpoint }, { "project_id", projectId } });
}

Expand All @@ -248,11 +247,10 @@ std::string ServiceConfig::GetProjectsUrl(int page, int pageSize) const
std::string ServiceConfig::GetProjectInfoUrl(std::string_view projectId) const
{
return Substitute(
"{api_url}/project/{project_id}",
{
{ "api_url", mApiEndpoint },
{ "project_id", projectId },
});
"{api_url}/project/{project_id}", {
{ "api_url", mApiEndpoint },
{ "project_id", projectId },
});
}

std::string ServiceConfig::GetSnapshotInfoUrl(
Expand All @@ -277,6 +275,16 @@ std::string ServiceConfig::GetNetworkStatsUrl(std::string_view projectId) const
});
}

std::string ServiceConfig::GetProjectPageUrl(
std::string_view userId, std::string_view projectId) const
{
return Substitute(
"{frontend_url}/{user_slug}/projects/{project_id}",
{ { "frontend_url", mFrontendURL },
{ "user_slug", userId },
{ "project_id", projectId } });
}

const ServiceConfig& GetServiceConfig()
{
static ServiceConfig config;
Expand Down
5 changes: 4 additions & 1 deletion libraries/lib-cloud-audiocom/ServiceConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,17 @@ class CLOUD_AUDIOCOM_API ServiceConfig final
std::string_view projectId, std::string_view snapshotId) const;

std::string GetNetworkStatsUrl(std::string_view projectId) const;
std::string
GetProjectPageUrl(std::string_view userId, std::string_view projectId) const;

private:
std::string mApiEndpoint;
std::string mOAuthClientID;
std::string mOAuthClientSecret;
std::string mOAuthRedirectURL;
std::string mOAuthLoginPage;
std::string mFinishUploadPage;
std::string mAudioURL;
std::string mFrontendURL;
std::string mPreferredMimeType;
};

Expand Down
101 changes: 73 additions & 28 deletions libraries/lib-cloud-audiocom/sync/CloudProjectsDatabase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,23 +53,19 @@ CREATE TABLE IF NOT EXISTS block_hashes
CREATE INDEX IF NOT EXISTS block_hashes_index ON block_hashes (hash);
CREATE TABLE IF NOT EXISTS migrations
CREATE TABLE IF NOT EXISTS project_users
(
version INTEGER PRIMARY KEY
project_id INTEGER,
user_name TEXT,
PRIMARY KEY (project_id)
);
INSERT OR IGNORE INTO migrations (version) VALUES (0);
)";

}

CloudProjectsDatabase::CloudProjectsDatabase()
{
AppEvents::OnAppInitialized(
[this]
{
OpenConnection();
});
AppEvents::OnAppInitialized([this] { OpenConnection(); });
}

CloudProjectsDatabase& CloudProjectsDatabase::Get()
Expand Down Expand Up @@ -124,7 +120,7 @@ std::optional<DBProjectData> CloudProjectsDatabase::GetProjectDataForPath(
auto statement = connection->CreateStatement(
"SELECT project_id, snapshot_id, saves_count, last_audio_preview_save, local_path, last_modified, last_read, sync_status FROM projects WHERE local_path = ? LIMIT 1");

if (!statement)
if (!statement)
return {};

return DoGetProjectData(statement->Prepare(projectFilePath).Run());
Expand All @@ -138,12 +134,17 @@ bool CloudProjectsDatabase::MarkProjectAsSynced(
if (!connection)
return false;

auto statement = connection->CreateStatement ("UPDATE projects SET sync_status = ? WHERE project_id = ? AND snapshot_id = ?");
auto statement = connection->CreateStatement(
"UPDATE projects SET sync_status = ? WHERE project_id = ? AND snapshot_id = ?");

if (!statement)
return false;

auto result = statement->Prepare(static_cast<int>(DBProjectData::SyncStatusSynced), projectId, snapshotId).Run();
auto result = statement
->Prepare(
static_cast<int>(DBProjectData::SyncStatusSynced),
projectId, snapshotId)
.Run();

if (!result.IsOk())
return false;
Expand All @@ -170,7 +171,7 @@ void CloudProjectsDatabase::UpdateProjectBlockList(

if (!result.IsOk())
{
assert(false);
assert(false);
}
}

Expand All @@ -182,7 +183,8 @@ std::optional<std::string> CloudProjectsDatabase::GetBlockHash(
if (!connection)
return {};

auto statement = connection->CreateStatement ("SELECT hash FROM block_hashes WHERE project_id = ? AND block_id = ? LIMIT 1");
auto statement = connection->CreateStatement(
"SELECT hash FROM block_hashes WHERE project_id = ? AND block_id = ? LIMIT 1");

if (!statement)
return {};
Expand Down Expand Up @@ -216,7 +218,7 @@ void CloudProjectsDatabase::UpdateBlockHashes(
std::string("UpdateBlockHashes_") +
std::to_string(reinterpret_cast<size_t>(&localVar)));

auto statement = connection->CreateStatement (
auto statement = connection->CreateStatement(
"INSERT OR REPLACE INTO block_hashes (project_id, block_id, hash) VALUES (?, ?, ?)");

for (const auto& [blockId, hash] : hashes)
Expand All @@ -225,33 +227,76 @@ void CloudProjectsDatabase::UpdateBlockHashes(
transaction.Commit();
}

bool CloudProjectsDatabase::UpdateProjectData(
const DBProjectData& projectData)
bool CloudProjectsDatabase::UpdateProjectData(const DBProjectData& projectData)
{
auto connection = GetConnection();

if (!connection)
return false;

auto statement = connection->CreateStatement (
auto statement = connection->CreateStatement(
"INSERT OR REPLACE INTO projects (project_id, snapshot_id, saves_count, last_audio_preview_save, local_path, last_modified, last_read, sync_status) VALUES (?, ?, ?, ?, ?, ?, ?, ?)");

if (!statement)
return false;

auto result = statement->Prepare (
projectData.ProjectId,
projectData.SnapshotId,
projectData.SavesCount,
projectData.LastAudioPreview,
projectData.LocalPath,
projectData.LastModified,
projectData.LastRead,
projectData.SyncStatus).Run();
auto result = statement
->Prepare(
projectData.ProjectId, projectData.SnapshotId,
projectData.SavesCount, projectData.LastAudioPreview,
projectData.LocalPath, projectData.LastModified,
projectData.LastRead, projectData.SyncStatus)
.Run();

return result.IsOk();
}

std::string
CloudProjectsDatabase::GetProjectUserSlug(std::string_view projectId)
{
auto connection = GetConnection();

if (!connection)
return {};

auto statement = connection->CreateStatement(
"SELECT user_name FROM project_users WHERE project_id = ? LIMIT 1");

if (!statement)
return {};

auto result = statement->Prepare(projectId).Run();

for (auto row : result)
{
std::string slug;

if (!row.Get(0, slug))
return {};

return slug;
}

return {};
}

void CloudProjectsDatabase::SetProjectUserSlug(
std::string_view projectId, std::string_view slug)
{
auto connection = GetConnection();

if (!connection)
return;

auto statement = connection->CreateStatement(
"INSERT OR REPLACE INTO project_users (project_id, user_name) VALUES (?, ?)");

if (!statement)
return;

statement->Prepare(projectId, slug).Run();
}

std::optional<DBProjectData>
CloudProjectsDatabase::DoGetProjectData(sqlite::RunResult result) const
{
Expand Down Expand Up @@ -297,7 +342,7 @@ bool CloudProjectsDatabase::OpenConnection()
if (mConnection)
return true;

const auto configDir = FileNames::ConfigDir();
const auto configDir = FileNames::ConfigDir();
const auto configPath = configDir + "/audiocom_sync.db";

mConnection = sqlite::SafeConnection::Open(audacity::ToUTF8(configPath));
Expand Down
3 changes: 3 additions & 0 deletions libraries/lib-cloud-audiocom/sync/CloudProjectsDatabase.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ class CloudProjectsDatabase final

bool UpdateProjectData(const DBProjectData& projectData);

std::string GetProjectUserSlug(std::string_view projectId);
void SetProjectUserSlug(std::string_view projectId, std::string_view slug);

private:
std::optional<DBProjectData> DoGetProjectData(sqlite::RunResult result) const;
bool OpenConnection();
Expand Down
Loading

0 comments on commit 9267d91

Please sign in to comment.