Upload/Download banks.

This commit is contained in:
Robin Davies
2021-08-22 21:07:04 -04:00
parent 865e23b413
commit 1bb68548ba
11 changed files with 407 additions and 80 deletions
+18
View File
@@ -93,6 +93,16 @@ public:
presets_.erase(presets_.begin()+from);
presets_.insert(presets_.begin()+to,std::move(t));
}
void updateNextIndex() {
int64_t t = 0;
for (size_t i = 0; i < this->presets_.size(); ++i)
{
int64_t instanceId = this->presets_[i]->instanceId();
if (instanceId > t) t = instanceId;
}
this->nextInstanceId_ = t;
}
int64_t addPreset(const PedalBoard&preset, int64_t afterItem = -1)
{
if (hasName(preset.name()))
@@ -221,6 +231,14 @@ public:
DECLARE_JSON_MAP(BankIndex);
bool hasName(const std::string&name) const {
for (size_t i = 0; i < this->entries_.size(); ++i)
{
if (this->entries_[i].name() == name) return true;
}
return false;
}
void move(size_t from, size_t to)
{
if (from >= this->entries_.size()) {
+3 -3
View File
@@ -325,7 +325,7 @@ void handle_request(
{
return send(server_error(ec.message()));
}
req.prepare_payload();
res.prepare_payload();
return send(std::move(res));
}
else if (req.method() == http::verb::post)
@@ -341,7 +341,7 @@ void handle_request(
res.set(http::field::date, HtmlHelper::timeToHttpDate(time(nullptr)));
res.set(http::field::access_control_allow_origin, req[http::field::origin]);
requestHandler->post_response(request_uri, req, res, ec);
res.keep_alive(req.keep_alive());
res.keep_alive(false); // bug in Beast Server -- posted body not reset.
if (ec == boost::system::errc::no_such_file_or_directory)
return send(not_found(req.target()));
@@ -349,7 +349,7 @@ void handle_request(
{
return send(server_error(ec.message()));
}
req.prepare_payload();
res.prepare_payload();
return send(std::move(res));
}
return send(bad_request("Unknown HTTP-method"));
+13
View File
@@ -313,6 +313,11 @@ PedalBoard PiPedalModel::getPreset(int64_t instanceId)
std::lock_guard guard(mutex);
return this->storage.GetPreset(instanceId);
}
void PiPedalModel::getBank(int64_t instanceId, BankFile*pResult)
{
std::lock_guard guard(mutex);
this->storage.GetBankFile(instanceId, pResult);
}
void PiPedalModel::setPresetChanged(int64_t clientId, bool value)
{
@@ -372,6 +377,14 @@ int64_t PiPedalModel::uploadPreset(const BankFile &bankFile, int64_t uploadAfter
firePresetsChanged(-1);
return newPreset;
}
int64_t PiPedalModel::uploadBank(BankFile &bankFile, int64_t uploadAfter)
{
std::lock_guard(this->mutex);
int64_t newPreset = this->storage.UploadBank(bankFile, uploadAfter);
fireBanksChanged(-1);
return newPreset;
}
void PiPedalModel::loadPreset(int64_t clientId, int64_t instanceId)
{
+3
View File
@@ -126,6 +126,9 @@ public:
void getPresets(PresetIndex*pResult);
PedalBoard getPreset(int64_t instanceId);
void getBank(int64_t instanceId, BankFile*pBank);
int64_t uploadBank(BankFile&bankFile, int64_t uploadAfter = -1);
int64_t uploadPreset(const BankFile&bankFile, int64_t uploadAfter = -1);
void saveCurrentPreset(int64_t clientId);
int64_t saveCurrentPresetAs(int64_t clientId, const std::string& name,int64_t saveAfterInstanceId = -1);
+48 -2
View File
@@ -163,6 +163,7 @@ void Storage::Initialize()
LoadWifiConfigSettings();
}
void Storage::LoadBank(int64_t instanceId)
{
auto indexEntry = this->bankIndex.getBankIndexEntry(instanceId);
@@ -190,11 +191,11 @@ std::filesystem::path Storage::GetChannelSelectionFileName()
{
return this->dataRoot / "JackChannelSelection.json";
}
std::filesystem::path Storage::GetIndexFileName()
std::filesystem::path Storage::GetIndexFileName() const
{
return this->GetPresetsDirectory() / BANKS_FILENAME;
}
std::filesystem::path Storage::GetBankFileName(const std::string &name)
std::filesystem::path Storage::GetBankFileName(const std::string &name) const
{
std::string fileName = SafeEncodeName(name) + BANK_EXTENSION;
return this->GetPresetsDirectory() / fileName;
@@ -274,6 +275,16 @@ void Storage::CreateBank(const std::string &name)
this->SaveBankIndex();
}
void Storage::GetBankFile(int64_t instanceId,BankFile *pBank) const {
auto indexEntry = this->bankIndex.getBankIndexEntry(instanceId);
auto name = indexEntry.name();
std::filesystem::path fileName = GetBankFileName(name);
std::ifstream is(fileName);
json_reader reader(is);
reader.read(pBank);
pBank->name(indexEntry.name());
}
void Storage::LoadBankFile(const std::string &name, BankFile *pBank)
{
std::filesystem::path fileName = GetBankFileName(name);
@@ -400,6 +411,7 @@ void Storage::GetPresetIndex(PresetIndex *pResult)
pResult->presets().push_back(entry);
}
}
PedalBoard Storage::GetPreset(int64_t instanceId) const
{
for (size_t i = 0; i < currentBank.presets().size(); ++i)
@@ -687,6 +699,40 @@ int64_t Storage::UploadPreset(const BankFile&bankFile,int64_t uploadAfter)
this->SaveCurrentBank();
return lastPreset;
}
int64_t Storage::UploadBank(BankFile&bankFile,int64_t uploadAfter)
{
int64_t lastBank = this->bankIndex.selectedBank();
if (uploadAfter != -1)
{
lastBank = uploadAfter;
}
if (bankFile.presets().size() == 0) {
throw PiPedalException("Invalid bank.");
}
bankFile.updateNextIndex();
int n = 2;
std::string baseName = bankFile.name();
while (this->bankIndex.hasName(bankFile.name()))
{
std::stringstream s;
s << baseName << "(" << n++ << ")";
bankFile.name(s.str());
}
std::filesystem::path path = this->GetBankFileName(bankFile.name());
std::ofstream f(path);
if (!f.is_open()) {
throw PiPedalException("Can't write to bank file.");
}
json_writer writer(f);
writer.write(bankFile);
lastBank = this->bankIndex.addBank(lastBank,bankFile.name());
this->SaveBankIndex();
return lastBank;
}
void Storage::SetWifiConfigSettings(const WifiConfigSettings & wifiConfigSettings)
{
+4 -2
View File
@@ -23,8 +23,8 @@ private:
static std::string SafeEncodeName(const std::string& name);
static std::string SafeDecodeName(const std::string& name);
std::filesystem::path GetPresetsDirectory() const;
std::filesystem::path GetIndexFileName();
std::filesystem::path GetBankFileName(const std::string & name);
std::filesystem::path GetIndexFileName() const;
std::filesystem::path GetBankFileName(const std::string & name) const;
std::filesystem::path GetChannelSelectionFileName();
void LoadBankIndex();
@@ -62,7 +62,9 @@ public:
void GetPresetIndex(PresetIndex*pResult);
void SetPresetIndex(const PresetIndex &presetIndex);
PedalBoard GetPreset(int64_t instanceId) const;
void GetBankFile(int64_t instanceId,BankFile*pResult) const;
int64_t UploadPreset(const BankFile&bankFile, int64_t uploadAfter);
int64_t UploadBank(BankFile&bankFile, int64_t uploadAfter);
bool LoadPreset(int64_t presetId);
+79 -2
View File
@@ -62,8 +62,16 @@ public:
std::string strInstanceId = request_uri.query("id");
if (strInstanceId != "")
return true;
} else if (request_uri.segment(1) == "uploadPreset")
{
return true;
}
if (request_uri.segment(1) == "uploadPreset")
if (request_uri.segment(1) == "downloadBank")
{
std::string strInstanceId = request_uri.query("id");
if (strInstanceId != "")
return true;
} else if (request_uri.segment(1) == "uploadBank")
{
return true;
}
@@ -99,6 +107,20 @@ public:
*pContent = s.str();
*pName = pedalBoard.name();
}
void GetBank(const uri &request_uri, std::string *pName, std::string *pContent)
{
std::string strInstanceId = request_uri.query("id");
int64_t instanceId = std::stol(strInstanceId);
BankFile bank;
model->getBank(instanceId,&bank);
std::stringstream s;
json_writer writer(s,true); // do what we can to reduce the file size.
writer.write(bank);
*pContent = s.str();
*pName = bank.name();
}
virtual void head_response(
const uri &request_uri,
@@ -120,6 +142,18 @@ public:
res.set(http::field::content_disposition, GetContentDispositionHeader(name, PRESET_EXTENSION));
return;
}
if (request_uri.segment(1) == "downloadBank")
{
std::string name;
std::string content;
GetBank(request_uri, &name, &content);
res.set(http::field::content_type, "application/octet-stream");
res.set(http::field::cache_control, "no-cache");
res.set(http::field::content_length, content.length());
res.set(http::field::content_disposition, GetContentDispositionHeader(name, BANK_EXTENSION));
return;
}
throw PiPedalException("Not found.");
}
catch (const std::exception &e)
@@ -154,7 +188,20 @@ public:
res.set(http::field::content_length, content.length());
res.set(http::field::content_disposition, GetContentDispositionHeader(name, PRESET_EXTENSION));
res.body() = content;
}
} else if (request_uri.segment(1) == "downloadBank")
{
std::string name;
std::string content;
GetBank(request_uri, &name, &content);
res.set(http::field::content_type, "application/octet-stream");
res.set(http::field::cache_control, "no-cache");
res.set(http::field::content_length, content.length());
res.set(http::field::content_disposition, GetContentDispositionHeader(name, BANK_EXTENSION));
res.body() = content;
} else {
throw PiPedalException("Not found");
}
}
catch (const std::exception &e)
{
@@ -202,6 +249,36 @@ public:
res.set(http::field::content_length, result.length());
res.body() = result;
}
else if (request_uri.segment(1) == "uploadBank" )
{
std::string presetBody = req.body();
std::stringstream s(presetBody);
json_reader reader(s);
uint64_t uploadAfter = -1;
std::string strUploadAfter = request_uri.query("uploadAfter");
if (strUploadAfter.length() != 0)
{
uploadAfter = std::stol(strUploadAfter);
}
BankFile bankFile;
reader.read(&bankFile);
uint64_t instanceId = model->uploadBank(bankFile,uploadAfter);
res.set(http::field::content_type, "application/json");
res.set(http::field::cache_control, "no-cache");
std::stringstream sResult;
sResult << instanceId;
std::string result = sResult.str();
res.set(http::field::content_length, result.length());
res.body() = result;
}
else {
throw PiPedalException("Not found");
}
}
catch (const std::exception &e)