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

ICloudProvider: added listDirectoryPageAsync.

parent 02b938e8
......@@ -101,6 +101,12 @@ ICloudProvider::RenameItemRequest::Pointer MockProvider::renameItemAsync(
return util::make_unique<MockMoveItemRequest>();
}
ICloudProvider::ListDirectoryPageRequest::Pointer
MockProvider::listDirectoryPageAsync(IItem::Pointer, const std::string&,
ListDirectoryPageCallback) {
return nullptr;
}
ICloudProvider::ListDirectoryRequest::Pointer MockProvider::listDirectoryAsync(
IItem::Pointer, ListDirectoryCallback) {
return nullptr;
......
......@@ -168,6 +168,8 @@ class MockProvider : public ICloudProvider {
RenameItemCallback) override;
ListDirectoryRequest::Pointer listDirectoryAsync(
IItem::Pointer, ListDirectoryCallback) override;
ListDirectoryPageRequest::Pointer listDirectoryPageAsync(
IItem::Pointer, const std::string&, ListDirectoryPageCallback) override;
DownloadFileRequest::Pointer downloadFileAsync(IItem::Pointer,
const std::string&,
DownloadFileCallback) override;
......
......@@ -37,6 +37,7 @@
#include "Request/ExchangeCodeRequest.h"
#include "Request/GetItemDataRequest.h"
#include "Request/GetItemRequest.h"
#include "Request/ListDirectoryPageRequest.h"
#include "Request/ListDirectoryRequest.h"
#include "Request/MoveItemRequest.h"
#include "Request/RenameItemRequest.h"
......@@ -391,6 +392,15 @@ ICloudProvider::RenameItemRequest::Pointer CloudProvider::renameItemAsync(
->run();
}
ICloudProvider::ListDirectoryPageRequest::Pointer
CloudProvider::listDirectoryPageAsync(IItem::Pointer directory,
const std::string& token,
ListDirectoryPageCallback completed) {
return std::make_shared<cloudstorage::ListDirectoryPageRequest>(
shared_from_this(), directory, token, completed)
->run();
}
ICloudProvider::ListDirectoryRequest::Pointer CloudProvider::listDirectoryAsync(
IItem::Pointer item, ListDirectoryCallback callback) {
return listDirectoryAsync(
......
......@@ -83,6 +83,8 @@ class CloudProvider : public ICloudProvider,
RenameItemRequest::Pointer renameItemAsync(IItem::Pointer item,
const std::string&,
RenameItemCallback) override;
ListDirectoryPageRequest::Pointer listDirectoryPageAsync(
IItem::Pointer, const std::string&, ListDirectoryPageCallback) override;
ListDirectoryRequest::Pointer listDirectoryAsync(
IItem::Pointer item, ListDirectoryCallback callback) override;
DownloadFileRequest::Pointer downloadFileAsync(IItem::Pointer item,
......
......@@ -753,6 +753,35 @@ ICloudProvider::RenameItemRequest::Pointer MegaNz::renameItemAsync(
return r->run();
}
ICloudProvider::ListDirectoryPageRequest::Pointer
MegaNz::listDirectoryPageAsync(IItem::Pointer item, const std::string&,
ListDirectoryPageCallback complete) {
auto r = std::make_shared<Request<EitherError<PageData>>>(shared_from_this());
r->set([=](Request<EitherError<PageData>>::Ptr r) {
ensureAuthorized<EitherError<PageData>>(r, complete, [=] {
std::unique_ptr<mega::MegaNode> node(
mega_->getNodeByPath(item->id().c_str()));
if (node) {
std::vector<IItem::Pointer> result;
std::unique_ptr<mega::MegaNodeList> lst(mega_->getChildren(node.get()));
if (lst) {
for (int i = 0; i < lst->size(); i++) {
auto item = toItem(lst->get(i));
result.push_back(item);
}
}
complete(PageData{result, ""});
r->done(PageData{result, ""});
} else {
Error e{IHttpRequest::NotFound, "node not found"};
complete(e);
r->done(e);
}
});
});
return r->run();
}
std::function<void(Request<EitherError<void>>::Ptr)> MegaNz::downloadResolver(
IItem::Pointer item, IDownloadFileCallback::Pointer callback, int64_t start,
int64_t size) {
......
......@@ -86,6 +86,8 @@ class MegaNz : public CloudProvider {
RenameItemRequest::Pointer renameItemAsync(IItem::Pointer item,
const std::string& name,
RenameItemCallback) override;
ListDirectoryPageRequest::Pointer listDirectoryPageAsync(
IItem::Pointer, const std::string&, ListDirectoryPageCallback) override;
std::function<void(Request<EitherError<void>>::Ptr)> downloadResolver(
IItem::Pointer item, IDownloadFileCallback::Pointer, int64_t start = 0,
......
......@@ -27,6 +27,7 @@
#include <cstring>
#include "Request/DownloadFileRequest.h"
#include "Request/ListDirectoryPageRequest.h"
#include "Request/ListDirectoryRequest.h"
#include "Request/Request.h"
......@@ -62,6 +63,15 @@ std::string YouTube::name() const { return "youtube"; }
std::string YouTube::endpoint() const { return "https://www.googleapis.com"; }
ListDirectoryPageRequest::Pointer YouTube::listDirectoryPageAsync(
IItem::Pointer directory, const std::string& token,
ListDirectoryPageCallback complete) {
return std::make_shared<cloudstorage::ListDirectoryPageRequest>(
shared_from_this(), directory, token, complete,
[](int code) { return code == IHttpRequest::NotFound; })
->run();
}
ICloudProvider::ListDirectoryRequest::Pointer YouTube::listDirectoryAsync(
IItem::Pointer item, IListDirectoryCallback::Pointer callback) {
return std::make_shared<cloudstorage::ListDirectoryRequest>(
......
......@@ -41,6 +41,8 @@ class YouTube : public CloudProvider {
GetItemDataRequest::Pointer getItemDataAsync(const std::string& id,
GetItemDataCallback f) override;
ListDirectoryPageRequest::Pointer listDirectoryPageAsync(
IItem::Pointer, const std::string&, ListDirectoryPageCallback) override;
ListDirectoryRequest::Pointer listDirectoryAsync(
IItem::Pointer item, IListDirectoryCallback::Pointer callback) override;
DownloadFileRequest::Pointer downloadFileAsync(
......
......@@ -43,6 +43,7 @@ class ICloudProvider {
using Hints = std::unordered_map<std::string, std::string>;
using ExchangeCodeRequest = IRequest<EitherError<Token>>;
using ListDirectoryPageRequest = IRequest<EitherError<PageData>>;
using ListDirectoryRequest =
IRequest<EitherError<std::vector<IItem::Pointer>>>;
using GetItemRequest = IRequest<EitherError<IItem>>;
......@@ -349,6 +350,19 @@ class ICloudProvider {
IItem::Pointer item, const std::string& name,
RenameItemCallback callback = [](EitherError<void>) {}) = 0;
/**
* Lists directory, but returns only one page of items.
*
* @param directory directory to be listed
*
* @param token token denoting the page, empty if querying for the first page
*
* @return object representing the pending request
*/
virtual ListDirectoryPageRequest::Pointer listDirectoryPageAsync(
IItem::Pointer directory, const std::string& token = "",
ListDirectoryPageCallback = [](EitherError<PageData>) {}) = 0;
/**
* Simplified version of listDirectoryAsync.
*
......
......@@ -33,6 +33,7 @@
namespace cloudstorage {
struct Error;
struct PageData;
template <class Left, class Right>
class Either;
......@@ -40,6 +41,11 @@ class Either;
template <class T>
using EitherError = Either<Error, T>;
struct PageData {
std::vector<IItem::Pointer> items_;
std::string next_token_; // empty if no next page
};
struct Token {
std::string token_;
std::string access_token_;
......@@ -207,6 +213,7 @@ 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 ListDirectoryPageCallback = std::function<void(EitherError<PageData>)>;
using ListDirectoryCallback =
std::function<void(EitherError<std::vector<IItem::Pointer>>)>;
using DownloadFileCallback = std::function<void(EitherError<void>)>;
......
......@@ -32,6 +32,7 @@ libcloudstorage_la_SOURCES = \
Request/DownloadFileRequest.cpp \
Request/GetItemRequest.cpp \
Request/ListDirectoryRequest.cpp \
Request/ListDirectoryPageRequest.cpp \
Request/UploadFileRequest.cpp \
Request/GetItemDataRequest.cpp \
Request/DeleteItemRequest.cpp \
......@@ -63,6 +64,7 @@ noinst_HEADERS = \
Request/GetItemRequest.h \
Request/GetItemDataRequest.h \
Request/ListDirectoryRequest.h \
Request/ListDirectoryPageRequest.h \
Request/UploadFileRequest.h \
Request/DeleteItemRequest.h \
Request/CreateDirectoryRequest.h \
......
/*****************************************************************************
* ListDirectoryPageRequest.cpp
*
*****************************************************************************
* Copyright (C) 2016-2016 VideoLAN
*
* Authors: Paweł Wegner <pawel.wegner95@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include "ListDirectoryPageRequest.h"
#include "CloudProvider/CloudProvider.h"
namespace cloudstorage {
ListDirectoryPageRequest::ListDirectoryPageRequest(
std::shared_ptr<CloudProvider> p, IItem::Pointer directory,
const std::string& token, ListDirectoryPageCallback completed,
std::function<bool(int)> fault_tolerant)
: Request(p) {
set([=](Request<EitherError<PageData>>::Ptr r) {
if (directory->type() != IItem::FileType::Directory) {
Error e{IHttpRequest::Bad, "file not a directory"};
completed(e);
return r->done(e);
}
auto output = std::make_shared<std::stringstream>();
r->sendRequest(
[=](util::Output) {
return r->provider()->listDirectoryRequest(*directory, token,
*output);
},
[=](EitherError<util::Output> e) {
if (e.left()) {
if (!fault_tolerant(e.left()->code_)) {
completed(e.left());
return r->done(e.left());
} else {
completed(PageData{{}, ""});
return r->done(PageData{{}, ""});
}
}
std::string next_token;
auto lst = r->provider()->listDirectoryResponse(*directory, *output,
next_token);
PageData result{lst, next_token};
completed(result);
r->done(result);
},
output);
});
}
} // namespace cloudstorage
/*****************************************************************************
* ListDirectoryPageRequest.h
*
*****************************************************************************
* Copyright (C) 2016-2016 VideoLAN
*
* Authors: Paweł Wegner <pawel.wegner95@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef LIST_DIRECTORY_PAGE_REQUEST_H
#define LIST_DIRECTORY_PAGE_REQUEST_H
#include "Request.h"
namespace cloudstorage {
class ListDirectoryPageRequest : public Request<EitherError<PageData>> {
public:
ListDirectoryPageRequest(std::shared_ptr<CloudProvider>, IItem::Pointer,
const std::string&, ListDirectoryPageCallback,
std::function<bool(int)> fault_tolerant = [](int) {
return false;
});
};
} // namespace cloudstorage
#endif // LIST_DIRECTORY_PAGE_REQUEST_H
......@@ -250,6 +250,7 @@ void Request<T>::subrequest(std::shared_ptr<IGenericRequest> request) {
}
}
template class Request<EitherError<PageData>>;
template class Request<EitherError<Token>>;
template class Request<EitherError<std::vector<char>>>;
template class Request<EitherError<std::string>>;
......
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