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

Rename: supply handle to renamed item.

parent 06674fd3
......@@ -38,8 +38,9 @@ using ItemId = std::pair<std::string, std::string>;
namespace {
void rename(Request<EitherError<void>>::Pointer r, IHttp* http,
std::string region, ItemId dest_id, ItemId source_id,
template <class T>
void rename(typename Request<T>::Pointer r, IHttp* http, std::string region,
ItemId dest_id, ItemId source_id,
std::function<void(EitherError<void>)> complete);
std::string to_string(ItemId str) {
......@@ -64,7 +65,8 @@ std::string escapePath(const std::string& str) {
return result;
}
void remove(Request<EitherError<void>>::Pointer r,
template <class T>
void remove(typename Request<T>::Pointer r,
std::shared_ptr<std::vector<IItem::Pointer>> lst,
std::function<void(EitherError<void>)> complete) {
if (lst->empty()) return complete(nullptr);
......@@ -74,29 +76,30 @@ void remove(Request<EitherError<void>>::Pointer r,
if (e.left())
complete(e.left());
else
remove(r, lst, complete);
remove<T>(r, lst, complete);
}));
}
void rename(Request<EitherError<void>>::Pointer r, IHttp* http,
std::string region,
template <class T>
void rename(typename Request<T>::Pointer r, IHttp* http, std::string region,
std::shared_ptr<std::vector<IItem::Pointer>> lst, ItemId dest_id,
ItemId source_id, std::function<void(EitherError<void>)> complete) {
if (lst->empty()) return complete(nullptr);
auto item = lst->back();
lst->pop_back();
rename(r, http, region, lst, dest_id, source_id, [=](EitherError<void> e) {
rename<T>(r, http, region, lst, dest_id, source_id, [=](EitherError<void> e) {
if (e.left())
complete(e.left());
else
rename(r, http, region,
{dest_id.first, dest_id.second + "/" + item->filename()},
AmazonS3::extract(item->id()), complete);
rename<T>(r, http, region,
{dest_id.first, dest_id.second + "/" + item->filename()},
AmazonS3::extract(item->id()), complete);
});
}
void rename(Request<EitherError<void>>::Pointer r, IHttp* http,
std::string region, ItemId dest_id, ItemId source_id,
template <class T>
void rename(typename Request<T>::Pointer r, IHttp* http, std::string region,
ItemId dest_id, ItemId source_id,
std::function<void(EitherError<void>)> complete) {
auto finalize = [=]() {
auto output = std::make_shared<std::stringstream>();
......@@ -142,13 +145,13 @@ void rename(Request<EitherError<void>>::Pointer r, IHttp* http,
r->subrequest(r->provider()->listDirectoryAsync(
e.right(), [=](EitherError<std::vector<IItem::Pointer>> e) {
if (e.left()) return r->done(e.left());
rename(r, http, region, e.right(), dest_id, source_id,
[=](EitherError<void> e) {
if (e.left())
complete(e.left());
else
finalize();
});
rename<T>(r, http, region, e.right(), dest_id, source_id,
[=](EitherError<void> e) {
if (e.left())
complete(e.left());
else
finalize();
});
}));
}));
}
......@@ -219,10 +222,10 @@ ICloudProvider::MoveItemRequest::Pointer AmazonS3::moveItemAsync(
r->set(
[=](Request<EitherError<void>>::Pointer r) {
auto data = AmazonS3::extract(destination->id());
rename(r, http(), region(),
{data.first, data.second + source->filename()},
AmazonS3::extract(source->id()),
[=](EitherError<void> e) { r->done(e); });
rename<EitherError<void>>(
r, http(), region(), {data.first, data.second + source->filename()},
AmazonS3::extract(source->id()),
[=](EitherError<void> e) { r->done(e); });
},
callback);
return r->run();
......@@ -230,9 +233,9 @@ ICloudProvider::MoveItemRequest::Pointer AmazonS3::moveItemAsync(
ICloudProvider::RenameItemRequest::Pointer AmazonS3::renameItemAsync(
IItem::Pointer item, const std::string& name, RenameItemCallback callback) {
auto r = std::make_shared<Request<EitherError<void>>>(shared_from_this());
auto r = std::make_shared<Request<EitherError<IItem>>>(shared_from_this());
r->set(
[=](Request<EitherError<void>>::Pointer r) {
[=](Request<EitherError<IItem>>::Pointer r) {
auto data = extract(item->id());
auto path = data.second;
if (!path.empty() && path.back() == '/') path.pop_back();
......@@ -240,8 +243,15 @@ ICloudProvider::RenameItemRequest::Pointer AmazonS3::renameItemAsync(
path = "";
else
path = getPath(path) + "/";
rename(r, http(), region(), {data.first, path + name},
extract(item->id()), [=](EitherError<void> e) { r->done(e); });
rename<EitherError<IItem>>(
r, http(), region(), {data.first, path + name}, extract(item->id()),
[=](EitherError<void> e) {
if (e.left()) return r->done(e.left());
IItem::Pointer nitem = util::make_unique<Item>(
item->filename(), item->id(), item->size(), item->timestamp(),
item->type());
r->done(nitem);
});
},
callback);
return r->run();
......@@ -304,10 +314,12 @@ ICloudProvider::DeleteItemRequest::Pointer AmazonS3::deleteItemAsync(
r->subrequest(r->provider()->listDirectoryAsync(
item, [=](EitherError<std::vector<IItem::Pointer>> e) {
if (e.left()) return r->done(e.left());
remove(r, e.right(), [=](EitherError<void> e) {
if (e.left()) return r->done(e.left());
release();
});
remove<EitherError<void>>(r, e.right(),
[=](EitherError<void> e) {
if (e.left())
return r->done(e.left());
release();
});
}));
} else
release();
......
......@@ -511,6 +511,12 @@ IItem::Pointer CloudProvider::getItemDataResponse(std::istream&) const {
return nullptr;
}
IItem::Pointer CloudProvider::renameItemResponse(const IItem&,
const std::string&,
std::istream& response) const {
return getItemDataResponse(response);
}
std::string CloudProvider::getItemUrlResponse(const IItem&,
std::istream&) const {
return "";
......
......@@ -228,6 +228,10 @@ class CloudProvider : public ICloudProvider,
const IItem& directory, std::istream& response,
std::string& next_page_token) const;
virtual IItem::Pointer renameItemResponse(const IItem& old_item,
const std::string& name,
std::istream& response) const;
/**
* Used by default implementation of createDirectoryAsync, should translate
* response into new directory's item object.
......
......@@ -744,15 +744,21 @@ ICloudProvider::MoveItemRequest::Pointer MegaNz::moveItemAsync(
ICloudProvider::RenameItemRequest::Pointer MegaNz::renameItemAsync(
IItem::Pointer item, const std::string& name, RenameItemCallback callback) {
auto r = std::make_shared<Request<EitherError<void>>>(shared_from_this());
auto r = std::make_shared<Request<EitherError<IItem>>>(shared_from_this());
r->set(
[=](Request<EitherError<void>>::Pointer r) {
ensureAuthorized<EitherError<void>>(r, [=] {
[=](Request<EitherError<IItem>>::Pointer r) {
ensureAuthorized<EitherError<IItem>>(r, [=] {
std::unique_ptr<mega::MegaNode> node(
mega_->getNodeByPath(item->id().c_str()));
if (node) {
auto listener = Listener::make<RequestListener>(
[=](EitherError<void> e, Listener*) { r->done(e); }, this);
[=](EitherError<void> e, Listener*) {
if (e.left()) return r->done(e.left());
std::unique_ptr<mega::MegaNode> node(mega_->getNodeByPath(
(getPath(item->id()) + "/" + name).c_str()));
r->done(toItem(node.get()));
},
this);
r->subrequest(listener);
mega_->renameNode(node.get(), name.c_str(), listener.get());
} else
......
......@@ -138,11 +138,13 @@ IHttpRequest::Pointer PCloud::moveItemRequest(const IItem& source,
auto request = http()->create(endpoint() + "/renamefolder");
request->setParameter("folderid", source.id());
request->setParameter("tofolderid", destination.id());
request->setParameter("timeformat", "timestamp");
return request;
} else {
auto request = http()->create(endpoint() + "/renamefile");
request->setParameter("fileid", source.id());
request->setParameter("tofolderid", destination.id());
request->setParameter("timeformat", "timestamp");
return request;
}
}
......@@ -154,11 +156,13 @@ IHttpRequest::Pointer PCloud::renameItemRequest(const IItem& item,
auto request = http()->create(endpoint() + "/renamefolder");
request->setParameter("folderid", item.id());
request->setParameter("toname", util::Url::escape(name));
request->setParameter("timeformat", "timestamp");
return request;
} else {
auto request = http()->create(endpoint() + "/renamefile");
request->setParameter("fileid", item.id());
request->setParameter("toname", util::Url::escape(name));
request->setParameter("timeformat", "timestamp");
return request;
}
}
......
......@@ -171,6 +171,15 @@ IItem::Pointer WebDav::getItemDataResponse(std::istream& stream) const {
return toItem(document.RootElement()->FirstChild());
}
IItem::Pointer WebDav::renameItemResponse(const IItem& item,
const std::string& name,
std::istream&) const {
auto i = util::make_unique<Item>(name, getPath(item.id()) + "/" + name,
item.size(), item.timestamp(), item.type());
i->set_url(static_cast<const Item&>(item).url());
return i;
}
std::vector<IItem::Pointer> WebDav::listDirectoryResponse(const IItem&,
std::istream& stream,
std::string&) const {
......
......@@ -75,6 +75,9 @@ class WebDav : public CloudProvider {
IItem::Pointer getItemDataResponse(std::istream& response) const override;
std::vector<IItem::Pointer> listDirectoryResponse(
const IItem&, std::istream&, std::string& next_page_token) const override;
IItem::Pointer renameItemResponse(const IItem& old_item,
const std::string& name,
std::istream& response) const override;
IItem::Pointer toItem(const tinyxml2::XMLNode*) const;
......
......@@ -213,6 +213,13 @@ IHttpRequest::Pointer YandexDisk::renameItemRequest(const IItem& item,
return request;
}
IItem::Pointer YandexDisk::renameItemResponse(const IItem& item,
const std::string& name,
std::istream&) const {
return util::make_unique<Item>(name, getPath(item.id()) + "/" + name,
item.size(), item.timestamp(), item.type());
}
std::vector<IItem::Pointer> YandexDisk::listDirectoryResponse(
const IItem&, std::istream& stream, std::string& next_page_token) const {
Json::Value response;
......
......@@ -66,6 +66,9 @@ class YandexDisk : public CloudProvider {
IItem::Pointer getItemDataResponse(std::istream& response) const override;
std::string getItemUrlResponse(const IItem&,
std::istream& response) const override;
IItem::Pointer renameItemResponse(const IItem& old_item,
const std::string& name,
std::istream& response) const override;
IItem::Pointer toItem(const Json::Value&) const;
void authorizeRequest(IHttpRequest&) const override;
......
......@@ -54,7 +54,7 @@ class ICloudProvider {
using DeleteItemRequest = IRequest<EitherError<void>>;
using CreateDirectoryRequest = IRequest<EitherError<IItem>>;
using MoveItemRequest = IRequest<EitherError<void>>;
using RenameItemRequest = IRequest<EitherError<void>>;
using RenameItemRequest = IRequest<EitherError<IItem>>;
class IAuthCallback {
public:
......@@ -346,7 +346,7 @@ class ICloudProvider {
*/
virtual RenameItemRequest::Pointer renameItemAsync(
IItem::Pointer item, const std::string& name,
RenameItemCallback callback = [](EitherError<void>) {}) = 0;
RenameItemCallback callback = [](EitherError<IItem>) {}) = 0;
/**
* Lists directory, but returns only one page of items.
......
......@@ -230,7 +230,7 @@ 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(EitherError<void>)>;
using RenameItemCallback = std::function<void(EitherError<void>)>;
using RenameItemCallback = std::function<void(EitherError<IItem>)>;
using ListDirectoryPageCallback = std::function<void(EitherError<PageData>)>;
using ListDirectoryCallback =
std::function<void(EitherError<std::vector<IItem::Pointer>>)>;
......
......@@ -40,10 +40,12 @@ RenameItemRequest::RenameItemRequest(std::shared_ptr<CloudProvider> p,
return p->renameItemRequest(*item, name, *stream);
},
[=](EitherError<util::Output> e) {
if (e.left())
request->done(e.left());
else
request->done(nullptr);
if (e.left()) return request->done(e.left());
try {
request->done(p->renameItemResponse(*item, name, *output));
} catch (std::exception e) {
request->done(Error{IHttpRequest::Failure, output->str()});
}
},
output);
},
......
......@@ -28,7 +28,7 @@
namespace cloudstorage {
class RenameItemRequest : public Request<EitherError<void>> {
class RenameItemRequest : public Request<EitherError<IItem>> {
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