Commit d8d79299 authored by Paweł Wegner's avatar Paweł Wegner

Refactored move and rename to use EitherError.

parent ef88aad3
......@@ -93,13 +93,13 @@ MockProvider::createDirectoryAsync(IItem::Pointer parent,
ICloudProvider::MoveItemRequest::Pointer MockProvider::moveItemAsync(
IItem::Pointer, IItem::Pointer, MoveItemCallback callback) {
callback(false);
callback(Error{500, ""});
return util::make_unique<MockMoveItemRequest>();
}
ICloudProvider::RenameItemRequest::Pointer MockProvider::renameItemAsync(
IItem::Pointer, const std::string&, RenameItemCallback callback) {
callback(false);
callback(Error{500, ""});
return util::make_unique<MockMoveItemRequest>();
}
......
......@@ -128,7 +128,7 @@ class MockProvider : public ICloudProvider {
public:
void finish() override {}
void cancel() override {}
bool result() override { return false; }
EitherError<void> result() override { return Error{500, "unimplemented"}; }
};
MockProvider();
......
......@@ -411,9 +411,9 @@ void Window::createDirectory(QString name) {
void Window::markMovedItem(int item_id) {
if (moved_file_) {
move_item_request_ = cloud_provider_->moveItemAsync(
moved_file_, current_directory_, [this](bool e) {
moved_file_, current_directory_, [this](EitherError<void> e) {
std::unique_lock<std::mutex> lock(stream_mutex());
if (e)
if (!e.left())
std::cerr << "[DIAG] Successfully moved file\n";
else
std::cerr << "[FAIL] Failed to move file.\n";
......@@ -428,9 +428,9 @@ void Window::markMovedItem(int item_id) {
void Window::renameItem(int item_id, QString name) {
auto item = directory_model_.get(item_id)->item();
rename_item_request_ = cloud_provider_->renameItemAsync(
item, name.toStdString(), [this](bool e) {
item, name.toStdString(), [this](EitherError<void> e) {
std::unique_lock<std::mutex> lock(stream_mutex());
if (e)
if (!e.left())
std::cerr << "[DIAG] Successfully renamed file\n";
else
std::cerr << "[FAIL] Failed to rename file.\n";
......
......@@ -63,12 +63,13 @@ IItem::Pointer AmazonDrive::rootDirectory() const {
ICloudProvider::MoveItemRequest::Pointer AmazonDrive::moveItemAsync(
IItem::Pointer s, IItem::Pointer d, MoveItemCallback callback) {
auto r = util::make_unique<Request<bool>>(shared_from_this());
r->set_resolver([=](Request<bool>* r) -> bool {
auto r = util::make_unique<Request<EitherError<void>>>(shared_from_this());
r->set_resolver([=](Request<EitherError<void>>* r) -> EitherError<void> {
Item* source = static_cast<Item*>(s.get());
Item* destination = static_cast<Item*>(d.get());
for (const std::string& parent : source->parents()) {
std::stringstream output;
Error error;
int code = r->sendRequest(
[=](std::ostream& stream) {
auto request = http()->create(
......@@ -81,14 +82,14 @@ ICloudProvider::MoveItemRequest::Pointer AmazonDrive::moveItemAsync(
stream << json;
return request;
},
output);
output, &error);
if (!IHttpRequest::isSuccess(code)) {
callback(false);
return false;
callback(error);
return error;
}
}
callback(true);
return true;
callback(nullptr);
return nullptr;
});
return std::move(r);
}
......
......@@ -48,10 +48,12 @@ std::string escapePath(IHttp* http, const std::string& str) {
return result;
}
bool rename(Request<bool>* r, std::string dest_id, std::string source_id,
std::string region, IHttp* http) {
EitherError<void> rename(Request<EitherError<void>>* r, std::string dest_id,
std::string source_id, std::string region,
IHttp* http) {
if (!source_id.empty() && source_id.back() != '/') {
std::stringstream output;
Error error;
int code = r->sendRequest(
[=](std::ostream&) {
auto dest_data = AmazonS3::split(dest_id);
......@@ -66,31 +68,33 @@ bool rename(Request<bool>* r, std::string dest_id, std::string source_id,
"/" + source_data.first + "/" + source_data.second));
return request;
},
output);
if (!IHttpRequest::isSuccess(code)) return false;
output, &error);
if (!IHttpRequest::isSuccess(code)) return error;
} else {
auto directory =
r->provider()
->getItemDataAsync(source_id, [](EitherError<IItem>) {})
->result()
.right();
if (!directory) return false;
Request<bool>::Semaphore semaphore(r);
->result();
if (directory.left()) return directory.left();
Request<EitherError<void>>::Semaphore semaphore(r);
auto children_request = r->provider()->listDirectoryAsync(
directory, [&semaphore](EitherError<std::vector<IItem::Pointer>>) {
directory.right(),
[&semaphore](EitherError<std::vector<IItem::Pointer>>) {
semaphore.notify();
});
semaphore.wait();
if (r->is_cancelled()) {
children_request->cancel();
return false;
return Error{IHttpRequest::Aborted, ""};
}
for (auto item : *children_request->result().right()) {
auto p =
rename(r, dest_id + "/" + item->filename(), item->id(), region, http);
if (p.left()) return p;
}
for (auto item : *children_request->result().right())
if (!rename(r, dest_id + "/" + item->filename(), item->id(), region,
http))
return false;
}
std::stringstream output;
Error error;
int code = r->sendRequest(
[=](std::ostream&) {
auto data = AmazonS3::split(source_id);
......@@ -99,9 +103,9 @@ bool rename(Request<bool>* r, std::string dest_id, std::string source_id,
escapePath(http, data.second),
"DELETE");
},
output);
if (!IHttpRequest::isSuccess(code)) return false;
return true;
output, &error);
if (!IHttpRequest::isSuccess(code)) return error;
return nullptr;
}
std::string host(std::string url) {
......@@ -165,29 +169,29 @@ AuthorizeRequest::Pointer AmazonS3::authorizeAsync() {
ICloudProvider::MoveItemRequest::Pointer AmazonS3::moveItemAsync(
IItem::Pointer source, IItem::Pointer destination,
MoveItemCallback callback) {
auto r = util::make_unique<Request<bool>>(shared_from_this());
r->set_resolver([=](Request<bool>* r) -> bool {
bool success = rename(r, destination->id() + source->filename(),
source->id(), region_, http());
callback(success);
return success;
auto r = util::make_unique<Request<EitherError<void>>>(shared_from_this());
r->set_resolver([=](Request<EitherError<void>>* r) -> EitherError<void> {
auto p = rename(r, destination->id() + source->filename(), source->id(),
region_, http());
callback(p);
return p;
});
return std::move(r);
}
ICloudProvider::RenameItemRequest::Pointer AmazonS3::renameItemAsync(
IItem::Pointer item, const std::string& name, RenameItemCallback callback) {
auto r = util::make_unique<Request<bool>>(shared_from_this());
r->set_resolver([=](Request<bool>* r) -> bool {
auto r = util::make_unique<Request<EitherError<void>>>(shared_from_this());
r->set_resolver([=](Request<EitherError<void>>* r) -> EitherError<void> {
std::string path = split(item->id()).second;
if (!path.empty() && path.back() == '/') path.pop_back();
if (path.find_first_of('/') == std::string::npos)
path = split(item->id()).first + Auth::SEPARATOR;
else
path = split(item->id()).first + Auth::SEPARATOR + getPath(path) + "/";
bool success = rename(r, path + name, item->id(), region_, http());
callback(success);
return success;
auto p = rename(r, path + name, item->id(), region_, http());
callback(p);
return p;
});
return std::move(r);
}
......
......@@ -532,56 +532,59 @@ ICloudProvider::CreateDirectoryRequest::Pointer MegaNz::createDirectoryAsync(
ICloudProvider::MoveItemRequest::Pointer MegaNz::moveItemAsync(
IItem::Pointer source, IItem::Pointer destination,
MoveItemCallback callback) {
auto r = util::make_unique<Request<bool>>(shared_from_this());
r->set_resolver([=](Request<bool>* r) {
auto r = util::make_unique<Request<EitherError<void>>>(shared_from_this());
r->set_resolver([=](Request<EitherError<void>>* r) -> EitherError<void> {
if (!ensureAuthorized(r)) {
callback(false);
return false;
Error error{401, "authorization error"};
callback(error);
return error;
}
std::unique_ptr<mega::MegaNode> source_node(
mega_->getNodeByPath(source->id().c_str()));
std::unique_ptr<mega::MegaNode> destination_node(
mega_->getNodeByPath(destination->id().c_str()));
if (source_node && destination_node) {
Request<bool>::Semaphore semaphore(r);
Request<EitherError<void>>::Semaphore semaphore(r);
RequestListener listener(&semaphore);
mega_->moveNode(source_node.get(), destination_node.get(), &listener);
semaphore.wait();
mega_->removeRequestListener(&listener);
if (listener.status_ == Listener::SUCCESS) {
callback(true);
return true;
callback(nullptr);
return nullptr;
}
}
callback(false);
return false;
Error error{500, ""};
callback(error);
return error;
});
return std::move(r);
}
ICloudProvider::RenameItemRequest::Pointer MegaNz::renameItemAsync(
IItem::Pointer item, const std::string& name, RenameItemCallback callback) {
auto r = util::make_unique<Request<bool>>(shared_from_this());
r->set_resolver([=](Request<bool>* r) {
auto r = util::make_unique<Request<EitherError<void>>>(shared_from_this());
r->set_resolver([=](Request<EitherError<void>>* r) -> EitherError<void> {
if (!ensureAuthorized(r)) {
callback(false);
return false;
Error error{401, "authorization error"};
callback(error);
return error;
}
std::unique_ptr<mega::MegaNode> node(
mega_->getNodeByPath(item->id().c_str()));
if (node) {
Request<bool>::Semaphore semaphore(r);
Request<EitherError<void>>::Semaphore semaphore(r);
RequestListener listener(&semaphore);
mega_->renameNode(node.get(), name.c_str(), &listener);
semaphore.wait();
mega_->removeRequestListener(&listener);
if (listener.status_ == Listener::SUCCESS) {
callback(true);
return true;
callback(nullptr);
return nullptr;
}
}
callback(false);
return false;
callback(Error{500, ""});
return Error{500, ""};
});
return std::move(r);
}
......
......@@ -52,8 +52,8 @@ class ICloudProvider {
using GetItemDataRequest = IRequest<EitherError<IItem>>;
using DeleteItemRequest = IRequest<EitherError<void>>;
using CreateDirectoryRequest = IRequest<EitherError<IItem>>;
using MoveItemRequest = IRequest<bool>;
using RenameItemRequest = IRequest<bool>;
using MoveItemRequest = IRequest<EitherError<void>>;
using RenameItemRequest = IRequest<EitherError<void>>;
class ICallback {
public:
......@@ -333,10 +333,9 @@ class ICloudProvider {
*
* @return object representing the pending request
*/
virtual MoveItemRequest::Pointer moveItemAsync(IItem::Pointer source,
IItem::Pointer destination,
MoveItemCallback callback =
[](bool) {}) = 0;
virtual MoveItemRequest::Pointer moveItemAsync(
IItem::Pointer source, IItem::Pointer destination,
MoveItemCallback callback = [](EitherError<void>) {}) = 0;
/**
* Renames item.
......@@ -352,7 +351,7 @@ class ICloudProvider {
*/
virtual RenameItemRequest::Pointer renameItemAsync(
IItem::Pointer item, const std::string& name,
RenameItemCallback callback = [](bool) {}) = 0;
RenameItemCallback callback = [](EitherError<void>) {}) = 0;
/**
* Simplified version of listDirectoryAsync.
......
......@@ -215,8 +215,8 @@ using GetItemCallback = std::function<void(EitherError<IItem>)>;
using GetItemDataCallback = std::function<void(EitherError<IItem>)>;
using DeleteItemCallback = std::function<void(EitherError<void>)>;
using CreateDirectoryCallback = std::function<void(EitherError<IItem>)>;
using MoveItemCallback = std::function<void(bool)>;
using RenameItemCallback = std::function<void(bool)>;
using MoveItemCallback = std::function<void(EitherError<void>)>;
using RenameItemCallback = std::function<void(EitherError<void>)>;
using ListDirectoryCallback =
std::function<void(EitherError<std::vector<IItem::Pointer>>)>;
using DownloadFileCallback = std::function<void(bool)>;
......
......@@ -32,19 +32,26 @@ MoveItemRequest::MoveItemRequest(std::shared_ptr<CloudProvider> p,
IItem::Pointer destination,
MoveItemCallback callback)
: Request(p) {
set_resolver([=](Request<bool>* r) {
set_resolver([=](Request<EitherError<void>>* r) -> EitherError<void> {
if (destination->type() != IItem::FileType::Directory) {
callback(false);
return false;
Error e{403, "destination not a directory"};
callback(e);
return e;
}
std::stringstream output;
Error error;
int code = r->sendRequest(
[=](std::ostream& stream) {
return p->moveItemRequest(*source, *destination, stream);
},
output);
callback(IHttpRequest::isSuccess(code));
return IHttpRequest::isSuccess(code);
output, &error);
if (IHttpRequest::isSuccess(code)) {
callback(nullptr);
return nullptr;
} else {
callback(error);
return error;
}
});
}
......
......@@ -28,7 +28,7 @@
namespace cloudstorage {
class MoveItemRequest : public Request<bool> {
class MoveItemRequest : public Request<EitherError<void>> {
public:
MoveItemRequest(std::shared_ptr<CloudProvider>, IItem::Pointer source,
IItem::Pointer destination, MoveItemCallback);
......
......@@ -32,19 +32,20 @@ RenameItemRequest::RenameItemRequest(std::shared_ptr<CloudProvider> p,
const std::string& name,
RenameItemCallback callback)
: Request(p) {
set_resolver([=](Request*) {
set_resolver([=](Request*) -> EitherError<void> {
std::stringstream output;
Error error;
int code = sendRequest(
[=](std::ostream& stream) {
return provider()->renameItemRequest(*item, name, stream);
},
output);
output, &error);
if (IHttpRequest::isSuccess(code)) {
callback(true);
return false;
callback(nullptr);
return nullptr;
} else {
callback(false);
return false;
callback(error);
return error;
}
});
}
......
......@@ -28,7 +28,7 @@
namespace cloudstorage {
class RenameItemRequest : public Request<bool> {
class RenameItemRequest : public Request<EitherError<void>> {
public:
RenameItemRequest(std::shared_ptr<CloudProvider>, IItem::Pointer,
const std::string&, RenameItemCallback);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment