mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-02-04 09:05:34 -05:00
Merge pull request #1066 from Emotyco/libresapi_filesharing
Added a few filesharing handlers in libresapi
This commit is contained in:
commit
0c3fc05491
@ -236,7 +236,8 @@ public:
|
|||||||
mForumHandler(ifaces.mGxsForums),
|
mForumHandler(ifaces.mGxsForums),
|
||||||
mServiceControlHandler(ifaces.mServiceControl),
|
mServiceControlHandler(ifaces.mServiceControl),
|
||||||
mFileSearchHandler(sts, ifaces.mNotify, ifaces.mTurtle, ifaces.mFiles),
|
mFileSearchHandler(sts, ifaces.mNotify, ifaces.mTurtle, ifaces.mFiles),
|
||||||
mTransfersHandler(sts, ifaces.mFiles),
|
mFileSharingHandler(sts, ifaces.mFiles),
|
||||||
|
mTransfersHandler(sts, ifaces.mFiles, ifaces.mPeers),
|
||||||
mChatHandler(sts, ifaces.mNotify, ifaces.mMsgs, ifaces.mPeers, ifaces.mIdentity, &mPeersHandler),
|
mChatHandler(sts, ifaces.mNotify, ifaces.mMsgs, ifaces.mPeers, ifaces.mIdentity, &mPeersHandler),
|
||||||
mApiPluginHandler(sts, ifaces),
|
mApiPluginHandler(sts, ifaces),
|
||||||
mChannelsHandler(ifaces.mGxsChannels),
|
mChannelsHandler(ifaces.mGxsChannels),
|
||||||
@ -259,6 +260,8 @@ public:
|
|||||||
&ServiceControlHandler::handleRequest);
|
&ServiceControlHandler::handleRequest);
|
||||||
router.addResourceHandler("filesearch", dynamic_cast<ResourceRouter*>(&mFileSearchHandler),
|
router.addResourceHandler("filesearch", dynamic_cast<ResourceRouter*>(&mFileSearchHandler),
|
||||||
&FileSearchHandler::handleRequest);
|
&FileSearchHandler::handleRequest);
|
||||||
|
router.addResourceHandler("filesharing", dynamic_cast<ResourceRouter*>(&mFileSharingHandler),
|
||||||
|
&FileSharingHandler::handleRequest);
|
||||||
router.addResourceHandler("transfers", dynamic_cast<ResourceRouter*>(&mTransfersHandler),
|
router.addResourceHandler("transfers", dynamic_cast<ResourceRouter*>(&mTransfersHandler),
|
||||||
&TransfersHandler::handleRequest);
|
&TransfersHandler::handleRequest);
|
||||||
router.addResourceHandler("chat", dynamic_cast<ResourceRouter*>(&mChatHandler),
|
router.addResourceHandler("chat", dynamic_cast<ResourceRouter*>(&mChatHandler),
|
||||||
@ -280,6 +283,7 @@ public:
|
|||||||
ForumHandler mForumHandler;
|
ForumHandler mForumHandler;
|
||||||
ServiceControlHandler mServiceControlHandler;
|
ServiceControlHandler mServiceControlHandler;
|
||||||
FileSearchHandler mFileSearchHandler;
|
FileSearchHandler mFileSearchHandler;
|
||||||
|
FileSharingHandler mFileSharingHandler;
|
||||||
TransfersHandler mTransfersHandler;
|
TransfersHandler mTransfersHandler;
|
||||||
ChatHandler mChatHandler;
|
ChatHandler mChatHandler;
|
||||||
ApiPluginHandler mApiPluginHandler;
|
ApiPluginHandler mApiPluginHandler;
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "ServiceControlHandler.h"
|
#include "ServiceControlHandler.h"
|
||||||
#include "StateTokenServer.h"
|
#include "StateTokenServer.h"
|
||||||
#include "FileSearchHandler.h"
|
#include "FileSearchHandler.h"
|
||||||
|
#include "FileSharingHandler.h"
|
||||||
#include "TransfersHandler.h"
|
#include "TransfersHandler.h"
|
||||||
#include "LivereloadHandler.h"
|
#include "LivereloadHandler.h"
|
||||||
#include "TmpBlobStore.h"
|
#include "TmpBlobStore.h"
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "FileSearchHandler.h"
|
#include "FileSearchHandler.h"
|
||||||
|
|
||||||
|
#include <retroshare/rspeers.h>
|
||||||
#include <retroshare/rsexpr.h>
|
#include <retroshare/rsexpr.h>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
@ -10,13 +11,14 @@
|
|||||||
namespace resource_api
|
namespace resource_api
|
||||||
{
|
{
|
||||||
|
|
||||||
FileSearchHandler::FileSearchHandler(StateTokenServer *sts, RsNotify *notify, RsTurtle *turtle, RsFiles */*files*/):
|
FileSearchHandler::FileSearchHandler(StateTokenServer *sts, RsNotify *notify, RsTurtle *turtle, RsFiles *files):
|
||||||
mStateTokenServer(sts), mNotify(notify), mTurtle(turtle),// mFiles(files),
|
mStateTokenServer(sts), mNotify(notify), mTurtle(turtle), mRsFiles(files),
|
||||||
mMtx("FileSearchHandler")
|
mMtx("FileSearchHandler")
|
||||||
{
|
{
|
||||||
mNotify->registerNotifyClient(this);
|
mNotify->registerNotifyClient(this);
|
||||||
addResourceHandler("*", this, &FileSearchHandler::handleWildcard);
|
addResourceHandler("*", this, &FileSearchHandler::handleWildcard);
|
||||||
addResourceHandler("create_search", this, &FileSearchHandler::handleCreateSearch);
|
addResourceHandler("create_search", this, &FileSearchHandler::handleCreateSearch);
|
||||||
|
addResourceHandler("get_search_result", this, &FileSearchHandler::handleGetSearchResult);
|
||||||
|
|
||||||
mSearchesStateToken = mStateTokenServer->getNewToken();
|
mSearchesStateToken = mStateTokenServer->getNewToken();
|
||||||
}
|
}
|
||||||
@ -102,8 +104,11 @@ void FileSearchHandler::handleWildcard(Request &req, Response &resp)
|
|||||||
<< makeKeyValueReference("id", fd.hash)
|
<< makeKeyValueReference("id", fd.hash)
|
||||||
<< makeKeyValueReference("name", fd.name)
|
<< makeKeyValueReference("name", fd.name)
|
||||||
<< makeKeyValueReference("hash", fd.hash)
|
<< makeKeyValueReference("hash", fd.hash)
|
||||||
|
<< makeKeyValueReference("path", fd.path)
|
||||||
|
<< makeKeyValue("peer_id", fd.id.toStdString())
|
||||||
<< makeKeyValueReference("size", size)
|
<< makeKeyValueReference("size", size)
|
||||||
<< makeKeyValueReference("rank", fd.rank);
|
<< makeKeyValueReference("rank", fd.rank)
|
||||||
|
<< makeKeyValueReference("age", fd.age);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -194,7 +199,7 @@ void FileSearchHandler::handleCreateSearch(Request &req, Response &resp)
|
|||||||
if(local)
|
if(local)
|
||||||
{
|
{
|
||||||
std::list<DirDetails> local_results;
|
std::list<DirDetails> local_results;
|
||||||
rsFiles->SearchBoolExp(&exprs, local_results, RS_FILE_HINTS_LOCAL);
|
mRsFiles->SearchBoolExp(&exprs, local_results, RS_FILE_HINTS_LOCAL);
|
||||||
|
|
||||||
for(std::list<DirDetails>::iterator lit = local_results.begin(); lit != local_results.end(); ++lit)
|
for(std::list<DirDetails>::iterator lit = local_results.begin(); lit != local_results.end(); ++lit)
|
||||||
{
|
{
|
||||||
@ -206,7 +211,7 @@ void FileSearchHandler::handleCreateSearch(Request &req, Response &resp)
|
|||||||
if(remote)
|
if(remote)
|
||||||
{
|
{
|
||||||
std::list<DirDetails> remote_results;
|
std::list<DirDetails> remote_results;
|
||||||
rsFiles->SearchBoolExp(&exprs, remote_results, RS_FILE_HINTS_REMOTE);
|
mRsFiles->SearchBoolExp(&exprs, remote_results, RS_FILE_HINTS_REMOTE);
|
||||||
for(std::list<DirDetails>::iterator lit = remote_results.begin(); lit != remote_results.end(); ++lit)
|
for(std::list<DirDetails>::iterator lit = remote_results.begin(); lit != remote_results.end(); ++lit)
|
||||||
{
|
{
|
||||||
FileDetail fd;
|
FileDetail fd;
|
||||||
@ -239,4 +244,60 @@ void FileSearchHandler::handleCreateSearch(Request &req, Response &resp)
|
|||||||
resp.setOk();
|
resp.setOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FileSearchHandler::handleGetSearchResult(Request& req, Response& resp)
|
||||||
|
{
|
||||||
|
std::string search_id;
|
||||||
|
req.mStream << makeKeyValueReference("search_id", search_id);
|
||||||
|
|
||||||
|
if(search_id.size() != 8)
|
||||||
|
{
|
||||||
|
resp.setFail("Error: id has wrong size, should be 8 characters");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t id = 0;
|
||||||
|
for(uint8_t i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
id += (uint32_t(search_id[i]-'A')) << (i*4);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
RsStackMutex stackMtx(mMtx); // ********** STACK LOCKED MTX **********
|
||||||
|
std::map<uint32_t, Search>::iterator mit = mSearches.find(id);
|
||||||
|
if(mit == mSearches.end())
|
||||||
|
{
|
||||||
|
resp.setFail("Error: search id invalid");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Search& search = mit->second;
|
||||||
|
resp.mStateToken = search.mStateToken;
|
||||||
|
resp.mDataStream.getStreamToMember();
|
||||||
|
|
||||||
|
RsPgpId ownId = rsPeers->getGPGOwnId();
|
||||||
|
for(std::list<FileDetail>::iterator lit = search.mResults.begin(); lit != search.mResults.end(); ++lit)
|
||||||
|
{
|
||||||
|
FileDetail& fd = *lit;
|
||||||
|
bool isFriend = rsPeers->isFriend(fd.id);
|
||||||
|
bool isOwn = false;
|
||||||
|
if(ownId == rsPeers->getGPGId(fd.id))
|
||||||
|
isOwn = true;
|
||||||
|
|
||||||
|
double size = fd.size;
|
||||||
|
resp.mDataStream.getStreamToMember()
|
||||||
|
<< makeKeyValueReference("id", fd.hash)
|
||||||
|
<< makeKeyValueReference("name", fd.name)
|
||||||
|
<< makeKeyValueReference("hash", fd.hash)
|
||||||
|
<< makeKeyValueReference("path", fd.path)
|
||||||
|
<< makeKeyValue("peer_id", fd.id.toStdString())
|
||||||
|
<< makeKeyValueReference("is_friends", isFriend)
|
||||||
|
<< makeKeyValueReference("is_own", isOwn)
|
||||||
|
<< makeKeyValueReference("size", size)
|
||||||
|
<< makeKeyValueReference("rank", fd.rank)
|
||||||
|
<< makeKeyValueReference("age", fd.age);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resp.setOk();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace resource_api
|
} // namespace resource_api
|
||||||
|
@ -19,12 +19,13 @@ public:
|
|||||||
virtual void notifyTurtleSearchResult(uint32_t search_id, const std::list<TurtleFileInfo>& files);
|
virtual void notifyTurtleSearchResult(uint32_t search_id, const std::list<TurtleFileInfo>& files);
|
||||||
private:
|
private:
|
||||||
void handleWildcard(Request& req, Response& resp);
|
void handleWildcard(Request& req, Response& resp);
|
||||||
void handleCreateSearch(Request& req, Response& resp);
|
void handleCreateSearch(Request& req, Response& resp);
|
||||||
|
void handleGetSearchResult(Request& req, Response& resp);
|
||||||
|
|
||||||
StateTokenServer* mStateTokenServer;
|
StateTokenServer* mStateTokenServer;
|
||||||
RsNotify* mNotify;
|
RsNotify* mNotify;
|
||||||
RsTurtle* mTurtle;
|
RsTurtle* mTurtle;
|
||||||
//RsFiles* mFiles;
|
RsFiles* mRsFiles;
|
||||||
|
|
||||||
class Search{
|
class Search{
|
||||||
public:
|
public:
|
||||||
|
474
libresapi/src/api/FileSharingHandler.cpp
Normal file
474
libresapi/src/api/FileSharingHandler.cpp
Normal file
@ -0,0 +1,474 @@
|
|||||||
|
/*
|
||||||
|
* libresapi
|
||||||
|
*
|
||||||
|
* Copyright (C) 2017, Konrad Dębiec <konradd@tutanota.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#include "FileSharingHandler.h"
|
||||||
|
|
||||||
|
namespace resource_api
|
||||||
|
{
|
||||||
|
|
||||||
|
FileSharingHandler::FileSharingHandler(StateTokenServer *sts, RsFiles *files):
|
||||||
|
mStateTokenServer(sts), mRsFiles(files)
|
||||||
|
{
|
||||||
|
addResourceHandler("*", this, &FileSharingHandler::handleWildcard);
|
||||||
|
addResourceHandler("force_check", this, &FileSharingHandler::handleForceCheck);
|
||||||
|
|
||||||
|
addResourceHandler("get_shared_dirs", this, &FileSharingHandler::handleGetSharedDir);
|
||||||
|
addResourceHandler("set_shared_dir", this, &FileSharingHandler::handleSetSharedDir);
|
||||||
|
addResourceHandler("update_shared_dir", this, &FileSharingHandler::handleUpdateSharedDir);
|
||||||
|
addResourceHandler("remove_shared_dir", this, &FileSharingHandler::handleRemoveSharedDir);
|
||||||
|
|
||||||
|
addResourceHandler("get_dir_parent", this, &FileSharingHandler::handleGetDirectoryParent);
|
||||||
|
addResourceHandler("get_dir_childs", this, &FileSharingHandler::handleGetDirectoryChilds);
|
||||||
|
|
||||||
|
addResourceHandler("is_dl_dir_shared", this, &FileSharingHandler::handleIsDownloadDirShared);
|
||||||
|
addResourceHandler("share_dl_dir", this, &FileSharingHandler::handleShareDownloadDirectory);
|
||||||
|
|
||||||
|
addResourceHandler("download", this, &FileSharingHandler::handleDownload);
|
||||||
|
|
||||||
|
mStateToken = mStateTokenServer->getNewToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileSharingHandler::handleWildcard(Request & /*req*/, Response & /*resp*/)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileSharingHandler::handleForceCheck(Request&, Response& resp)
|
||||||
|
{
|
||||||
|
mRsFiles->ForceDirectoryCheck();
|
||||||
|
resp.setOk();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileSharingHandler::handleGetSharedDir(Request& req, Response& resp)
|
||||||
|
{
|
||||||
|
DirDetails dirDetails;
|
||||||
|
mRsFiles->RequestDirDetails(NULL, dirDetails, RS_FILE_HINTS_LOCAL);
|
||||||
|
|
||||||
|
resp.mDataStream << makeKeyValue("parent_reference", *reinterpret_cast<int*>(&dirDetails.ref));
|
||||||
|
resp.mDataStream << makeKeyValue("path", dirDetails.path);
|
||||||
|
StreamBase &childsStream = resp.mDataStream.getStreamToMember("childs");
|
||||||
|
|
||||||
|
for(std::vector<DirStub>::iterator it = dirDetails.children.begin(); it != dirDetails.children.end(); ++it)
|
||||||
|
{
|
||||||
|
DirDetails dirDetails;
|
||||||
|
mRsFiles->RequestDirDetails((*it).ref, dirDetails, RS_FILE_HINTS_LOCAL);
|
||||||
|
|
||||||
|
for(std::vector<DirStub>::iterator vit = dirDetails.children.begin(); vit != dirDetails.children.end(); ++vit)
|
||||||
|
{
|
||||||
|
DirDetails dirDetails;
|
||||||
|
mRsFiles->RequestDirDetails((*vit).ref, dirDetails, RS_FILE_HINTS_LOCAL);
|
||||||
|
|
||||||
|
std::string type;
|
||||||
|
switch(dirDetails.type)
|
||||||
|
{
|
||||||
|
case DIR_TYPE_PERSON:
|
||||||
|
type = "person";
|
||||||
|
break;
|
||||||
|
case DIR_TYPE_DIR:
|
||||||
|
type = "folder";
|
||||||
|
break;
|
||||||
|
case DIR_TYPE_FILE:
|
||||||
|
type = "file";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool browsable = false;
|
||||||
|
bool anon_dl = false;
|
||||||
|
bool anon_search = false;
|
||||||
|
|
||||||
|
if(dirDetails.flags & DIR_FLAGS_BROWSABLE)
|
||||||
|
browsable = true;
|
||||||
|
|
||||||
|
if(dirDetails.flags & DIR_FLAGS_ANONYMOUS_DOWNLOAD)
|
||||||
|
anon_dl = true;
|
||||||
|
|
||||||
|
if(dirDetails.flags & DIR_FLAGS_ANONYMOUS_SEARCH)
|
||||||
|
anon_search = true;
|
||||||
|
|
||||||
|
StreamBase &streamBase = childsStream.getStreamToMember()
|
||||||
|
<< makeKeyValue("name", dirDetails.name)
|
||||||
|
<< makeKeyValue("path", dirDetails.path)
|
||||||
|
<< makeKeyValue("hash", dirDetails.hash.toStdString())
|
||||||
|
<< makeKeyValue("parent_reference", *reinterpret_cast<int*>(&dirDetails.parent))
|
||||||
|
<< makeKeyValue("reference", *reinterpret_cast<int*>(&dirDetails.ref))
|
||||||
|
<< makeKeyValue("count", static_cast<int>(dirDetails.count))
|
||||||
|
<< makeKeyValueReference("type", type)
|
||||||
|
<< makeKeyValueReference("browsable", browsable)
|
||||||
|
<< makeKeyValueReference("anon_dl", anon_dl)
|
||||||
|
<< makeKeyValueReference("anon_search", anon_search);
|
||||||
|
|
||||||
|
|
||||||
|
int contain_files = 0;
|
||||||
|
int contain_folders = 0;
|
||||||
|
|
||||||
|
if(dirDetails.count != 0)
|
||||||
|
{
|
||||||
|
for(std::vector<DirStub>::iterator vit = dirDetails.children.begin(); vit != dirDetails.children.end(); ++vit)
|
||||||
|
{
|
||||||
|
DirDetails dirDetails;
|
||||||
|
mRsFiles->RequestDirDetails((*vit).ref, dirDetails, RS_FILE_HINTS_LOCAL);
|
||||||
|
|
||||||
|
switch(dirDetails.type)
|
||||||
|
{
|
||||||
|
case DIR_TYPE_DIR:
|
||||||
|
contain_folders++;
|
||||||
|
break;
|
||||||
|
case DIR_TYPE_FILE:
|
||||||
|
contain_files++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
streamBase
|
||||||
|
<< makeKeyValueReference("contain_files", contain_files)
|
||||||
|
<< makeKeyValueReference("contain_folders", contain_folders);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileSharingHandler::handleSetSharedDir(Request& req, Response& resp)
|
||||||
|
{
|
||||||
|
std::string dir;
|
||||||
|
bool browsable = false;
|
||||||
|
bool anon_dl = false;
|
||||||
|
bool anon_search = false;
|
||||||
|
req.mStream << makeKeyValueReference("directory", dir);
|
||||||
|
req.mStream << makeKeyValueReference("browsable", browsable);
|
||||||
|
req.mStream << makeKeyValueReference("anon_dl", anon_dl);
|
||||||
|
req.mStream << makeKeyValueReference("anon_search", anon_search);
|
||||||
|
|
||||||
|
SharedDirInfo sDI;
|
||||||
|
sDI.filename = dir;
|
||||||
|
sDI.virtualname.clear();
|
||||||
|
sDI.shareflags.clear();
|
||||||
|
|
||||||
|
if(browsable)
|
||||||
|
sDI.shareflags |= DIR_FLAGS_BROWSABLE;
|
||||||
|
|
||||||
|
if(anon_dl)
|
||||||
|
sDI.shareflags |= DIR_FLAGS_ANONYMOUS_DOWNLOAD;
|
||||||
|
|
||||||
|
if(anon_search)
|
||||||
|
sDI.shareflags |= DIR_FLAGS_ANONYMOUS_SEARCH;
|
||||||
|
|
||||||
|
if(mRsFiles->addSharedDirectory(sDI))
|
||||||
|
resp.setOk();
|
||||||
|
else
|
||||||
|
resp.setFail("Couldn't share folder");
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileSharingHandler::handleUpdateSharedDir(Request& req, Response& resp)
|
||||||
|
{
|
||||||
|
std::string dir;
|
||||||
|
std::string virtualname;
|
||||||
|
bool browsable = false;
|
||||||
|
bool anon_dl = false;
|
||||||
|
bool anon_search = false;
|
||||||
|
req.mStream << makeKeyValueReference("directory", dir);
|
||||||
|
req.mStream << makeKeyValueReference("virtualname", virtualname);
|
||||||
|
req.mStream << makeKeyValueReference("browsable", browsable);
|
||||||
|
req.mStream << makeKeyValueReference("anon_dl", anon_dl);
|
||||||
|
req.mStream << makeKeyValueReference("anon_search", anon_search);
|
||||||
|
|
||||||
|
SharedDirInfo sDI;
|
||||||
|
sDI.filename = dir;
|
||||||
|
sDI.virtualname = virtualname;
|
||||||
|
sDI.shareflags.clear();
|
||||||
|
|
||||||
|
if(browsable)
|
||||||
|
sDI.shareflags |= DIR_FLAGS_BROWSABLE;
|
||||||
|
|
||||||
|
if(anon_dl)
|
||||||
|
sDI.shareflags |= DIR_FLAGS_ANONYMOUS_DOWNLOAD;
|
||||||
|
|
||||||
|
if(anon_search)
|
||||||
|
sDI.shareflags |= DIR_FLAGS_ANONYMOUS_SEARCH;
|
||||||
|
|
||||||
|
if(mRsFiles->updateShareFlags(sDI))
|
||||||
|
resp.setOk();
|
||||||
|
else
|
||||||
|
resp.setFail("Couldn't update shared folder's flags");
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileSharingHandler::handleRemoveSharedDir(Request& req, Response& resp)
|
||||||
|
{
|
||||||
|
std::string dir;
|
||||||
|
req.mStream << makeKeyValueReference("directory", dir);
|
||||||
|
|
||||||
|
if(mRsFiles->removeSharedDirectory(dir))
|
||||||
|
resp.setOk();
|
||||||
|
else
|
||||||
|
resp.setFail("Couldn't remove shared directory.");
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileSharingHandler::handleGetDirectoryParent(Request& req, Response& resp)
|
||||||
|
{
|
||||||
|
int reference;
|
||||||
|
bool remote = false;
|
||||||
|
bool local = true;
|
||||||
|
|
||||||
|
req.mStream << makeKeyValueReference("reference", reference);
|
||||||
|
req.mStream << makeKeyValueReference("remote", remote);
|
||||||
|
req.mStream << makeKeyValueReference("local", local);
|
||||||
|
|
||||||
|
void *ref = reinterpret_cast<void*>(reference);
|
||||||
|
|
||||||
|
FileSearchFlags flags;
|
||||||
|
if(remote)
|
||||||
|
flags |= RS_FILE_HINTS_REMOTE;
|
||||||
|
|
||||||
|
if(local)
|
||||||
|
flags |= RS_FILE_HINTS_LOCAL;
|
||||||
|
|
||||||
|
DirDetails dirDetails;
|
||||||
|
mRsFiles->RequestDirDetails(ref, dirDetails, flags);
|
||||||
|
mRsFiles->RequestDirDetails(dirDetails.parent, dirDetails, flags);
|
||||||
|
|
||||||
|
resp.mDataStream << makeKeyValue("parent_reference", *reinterpret_cast<int*>(&dirDetails.ref));
|
||||||
|
resp.mDataStream << makeKeyValue("path", dirDetails.path);
|
||||||
|
StreamBase &childsStream = resp.mDataStream.getStreamToMember("childs");
|
||||||
|
|
||||||
|
if(dirDetails.count != 0)
|
||||||
|
{
|
||||||
|
for(std::vector<DirStub>::iterator vit = dirDetails.children.begin(); vit != dirDetails.children.end(); ++vit)
|
||||||
|
{
|
||||||
|
DirDetails dirDetails;
|
||||||
|
mRsFiles->RequestDirDetails((*vit).ref, dirDetails, flags);
|
||||||
|
|
||||||
|
std::string type;
|
||||||
|
switch(dirDetails.type)
|
||||||
|
{
|
||||||
|
case DIR_TYPE_PERSON:
|
||||||
|
type = "person";
|
||||||
|
break;
|
||||||
|
case DIR_TYPE_DIR:
|
||||||
|
type = "folder";
|
||||||
|
break;
|
||||||
|
case DIR_TYPE_FILE:
|
||||||
|
type = "file";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool browsable = false;
|
||||||
|
bool anon_dl = false;
|
||||||
|
bool anon_search = false;
|
||||||
|
|
||||||
|
if(dirDetails.flags & DIR_FLAGS_BROWSABLE)
|
||||||
|
browsable = true;
|
||||||
|
|
||||||
|
if(dirDetails.flags & DIR_FLAGS_ANONYMOUS_DOWNLOAD)
|
||||||
|
anon_dl = true;
|
||||||
|
|
||||||
|
if(dirDetails.flags & DIR_FLAGS_ANONYMOUS_SEARCH)
|
||||||
|
anon_search = true;
|
||||||
|
|
||||||
|
StreamBase &streamBase = childsStream.getStreamToMember()
|
||||||
|
<< makeKeyValue("name", dirDetails.name)
|
||||||
|
<< makeKeyValue("path", dirDetails.path)
|
||||||
|
<< makeKeyValue("hash", dirDetails.hash.toStdString())
|
||||||
|
<< makeKeyValue("parent_reference", *reinterpret_cast<int*>(&dirDetails.parent))
|
||||||
|
<< makeKeyValue("reference", *reinterpret_cast<int*>(&dirDetails.ref))
|
||||||
|
<< makeKeyValue("count", static_cast<int>(dirDetails.count))
|
||||||
|
<< makeKeyValueReference("type", type)
|
||||||
|
<< makeKeyValueReference("browsable", browsable)
|
||||||
|
<< makeKeyValueReference("anon_dl", anon_dl)
|
||||||
|
<< makeKeyValueReference("anon_search", anon_search);
|
||||||
|
|
||||||
|
|
||||||
|
int contain_files = 0;
|
||||||
|
int contain_folders = 0;
|
||||||
|
|
||||||
|
if(dirDetails.count != 0)
|
||||||
|
{
|
||||||
|
for(std::vector<DirStub>::iterator vit = dirDetails.children.begin(); vit != dirDetails.children.end(); ++vit)
|
||||||
|
{
|
||||||
|
DirDetails dirDetails;
|
||||||
|
mRsFiles->RequestDirDetails((*vit).ref, dirDetails, flags);
|
||||||
|
|
||||||
|
switch(dirDetails.type)
|
||||||
|
{
|
||||||
|
case DIR_TYPE_DIR:
|
||||||
|
contain_folders++;
|
||||||
|
break;
|
||||||
|
case DIR_TYPE_FILE:
|
||||||
|
contain_files++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
streamBase
|
||||||
|
<< makeKeyValueReference("contain_files", contain_files)
|
||||||
|
<< makeKeyValueReference("contain_folders", contain_folders);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileSharingHandler::handleGetDirectoryChilds(Request& req, Response& resp)
|
||||||
|
{
|
||||||
|
int reference = 0;
|
||||||
|
bool remote = false;
|
||||||
|
bool local = true;
|
||||||
|
|
||||||
|
req.mStream << makeKeyValueReference("reference", reference);
|
||||||
|
req.mStream << makeKeyValueReference("remote", remote);
|
||||||
|
req.mStream << makeKeyValueReference("local", local);
|
||||||
|
|
||||||
|
void *ref = reinterpret_cast<void*>(reference);
|
||||||
|
|
||||||
|
FileSearchFlags flags;
|
||||||
|
if(remote)
|
||||||
|
flags |= RS_FILE_HINTS_REMOTE;
|
||||||
|
|
||||||
|
if(local)
|
||||||
|
flags |= RS_FILE_HINTS_LOCAL;
|
||||||
|
|
||||||
|
DirDetails dirDetails;
|
||||||
|
mRsFiles->RequestDirDetails(ref, dirDetails, flags);
|
||||||
|
|
||||||
|
resp.mDataStream << makeKeyValue("parent_reference", *reinterpret_cast<int*>(&dirDetails.ref));
|
||||||
|
resp.mDataStream << makeKeyValue("path", dirDetails.path);
|
||||||
|
resp.mDataStream << makeKeyValue("hash", dirDetails.hash.toStdString());
|
||||||
|
StreamBase &childsStream = resp.mDataStream.getStreamToMember("childs");
|
||||||
|
|
||||||
|
if(dirDetails.count != 0)
|
||||||
|
{
|
||||||
|
for(std::vector<DirStub>::iterator vit = dirDetails.children.begin(); vit != dirDetails.children.end(); ++vit)
|
||||||
|
{
|
||||||
|
DirDetails dirDetails;
|
||||||
|
mRsFiles->RequestDirDetails((*vit).ref, dirDetails, flags);
|
||||||
|
|
||||||
|
std::string type;
|
||||||
|
switch(dirDetails.type)
|
||||||
|
{
|
||||||
|
case DIR_TYPE_PERSON:
|
||||||
|
type = "person";
|
||||||
|
break;
|
||||||
|
case DIR_TYPE_DIR:
|
||||||
|
type = "folder";
|
||||||
|
break;
|
||||||
|
case DIR_TYPE_FILE:
|
||||||
|
type = "file";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool browsable = false;
|
||||||
|
bool anon_dl = false;
|
||||||
|
bool anon_search = false;
|
||||||
|
|
||||||
|
if(dirDetails.flags & DIR_FLAGS_BROWSABLE)
|
||||||
|
browsable = true;
|
||||||
|
|
||||||
|
if(dirDetails.flags & DIR_FLAGS_ANONYMOUS_DOWNLOAD)
|
||||||
|
anon_dl = true;
|
||||||
|
|
||||||
|
if(dirDetails.flags & DIR_FLAGS_ANONYMOUS_SEARCH)
|
||||||
|
anon_search = true;
|
||||||
|
|
||||||
|
StreamBase &streamBase = childsStream.getStreamToMember()
|
||||||
|
<< makeKeyValue("name", dirDetails.name)
|
||||||
|
<< makeKeyValue("path", dirDetails.path)
|
||||||
|
<< makeKeyValue("hash", dirDetails.hash.toStdString())
|
||||||
|
<< makeKeyValue("parent_reference", *reinterpret_cast<int*>(&dirDetails.parent))
|
||||||
|
<< makeKeyValue("reference", *reinterpret_cast<int*>(&dirDetails.ref))
|
||||||
|
<< makeKeyValue("count", static_cast<int>(dirDetails.count))
|
||||||
|
<< makeKeyValueReference("type", type)
|
||||||
|
<< makeKeyValueReference("browsable", browsable)
|
||||||
|
<< makeKeyValueReference("anon_dl", anon_dl)
|
||||||
|
<< makeKeyValueReference("anon_search", anon_search);
|
||||||
|
|
||||||
|
|
||||||
|
int contain_files = 0;
|
||||||
|
int contain_folders = 0;
|
||||||
|
|
||||||
|
if(dirDetails.count != 0)
|
||||||
|
{
|
||||||
|
for(std::vector<DirStub>::iterator vit = dirDetails.children.begin(); vit != dirDetails.children.end(); ++vit)
|
||||||
|
{
|
||||||
|
DirDetails dirDetails;
|
||||||
|
mRsFiles->RequestDirDetails((*vit).ref, dirDetails, flags);
|
||||||
|
|
||||||
|
switch(dirDetails.type)
|
||||||
|
{
|
||||||
|
case DIR_TYPE_DIR:
|
||||||
|
contain_folders++;
|
||||||
|
break;
|
||||||
|
case DIR_TYPE_FILE:
|
||||||
|
contain_files++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
streamBase
|
||||||
|
<< makeKeyValueReference("contain_files", contain_files)
|
||||||
|
<< makeKeyValueReference("contain_folders", contain_folders);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileSharingHandler::handleIsDownloadDirShared(Request&, Response& resp)
|
||||||
|
{
|
||||||
|
bool shared = mRsFiles->getShareDownloadDirectory();
|
||||||
|
|
||||||
|
resp.mDataStream.getStreamToMember()
|
||||||
|
<< makeKeyValueReference("shared", shared);
|
||||||
|
|
||||||
|
resp.setOk();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileSharingHandler::handleShareDownloadDirectory(Request& req, Response& resp)
|
||||||
|
{
|
||||||
|
bool share;
|
||||||
|
req.mStream << makeKeyValueReference("share", share);
|
||||||
|
|
||||||
|
if(mRsFiles->shareDownloadDirectory(share))
|
||||||
|
resp.setOk();
|
||||||
|
else
|
||||||
|
resp.setFail("Couldn't share/unshare download directory.");
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileSharingHandler::handleDownload(Request& req, Response& resp)
|
||||||
|
{
|
||||||
|
int size;
|
||||||
|
std::string hashString;
|
||||||
|
std::string name;
|
||||||
|
req.mStream << makeKeyValueReference("hash", hashString);
|
||||||
|
req.mStream << makeKeyValueReference("name", name);
|
||||||
|
req.mStream << makeKeyValueReference("size", size);
|
||||||
|
|
||||||
|
std::list<RsPeerId> srcIds;
|
||||||
|
RsFileHash hash(hashString);
|
||||||
|
FileInfo finfo;
|
||||||
|
mRsFiles->FileDetails(hash, RS_FILE_HINTS_REMOTE, finfo);
|
||||||
|
|
||||||
|
for(std::list<TransferInfo>::const_iterator it(finfo.peers.begin());it!=finfo.peers.end();++it)
|
||||||
|
srcIds.push_back((*it).peerId);
|
||||||
|
|
||||||
|
if(!mRsFiles->FileRequest(name, hash, static_cast<uint64_t>(size), "",
|
||||||
|
RS_FILE_REQ_ANONYMOUS_ROUTING, srcIds))
|
||||||
|
{
|
||||||
|
resp.setOk();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
resp.setFail("Couldn't download file");
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace resource_api
|
57
libresapi/src/api/FileSharingHandler.h
Normal file
57
libresapi/src/api/FileSharingHandler.h
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* libresapi
|
||||||
|
*
|
||||||
|
* Copyright (C) 2017, Konrad Dębiec <konradd@tutanota.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ResourceRouter.h"
|
||||||
|
#include "StateTokenServer.h"
|
||||||
|
|
||||||
|
#include <retroshare/rsfiles.h>
|
||||||
|
|
||||||
|
namespace resource_api
|
||||||
|
{
|
||||||
|
|
||||||
|
class FileSharingHandler: public ResourceRouter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FileSharingHandler(StateTokenServer* sts, RsFiles* files);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void handleWildcard(Request& req, Response& resp);
|
||||||
|
void handleForceCheck(Request& req, Response& resp);
|
||||||
|
|
||||||
|
void handleGetSharedDir(Request& req, Response& resp);
|
||||||
|
void handleSetSharedDir(Request& req, Response& resp);
|
||||||
|
void handleUpdateSharedDir(Request& req, Response& resp);
|
||||||
|
void handleRemoveSharedDir(Request& req, Response& resp);
|
||||||
|
|
||||||
|
void handleGetDirectoryParent(Request& req, Response& resp);
|
||||||
|
void handleGetDirectoryChilds(Request& req, Response& resp);
|
||||||
|
|
||||||
|
void handleIsDownloadDirShared(Request& req, Response& resp);
|
||||||
|
void handleShareDownloadDirectory(Request& req, Response& resp);
|
||||||
|
|
||||||
|
void handleDownload(Request& req, Response& resp);
|
||||||
|
|
||||||
|
StateToken mStateToken;
|
||||||
|
StateTokenServer* mStateTokenServer;
|
||||||
|
|
||||||
|
RsFiles* mRsFiles;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace resource_api
|
@ -6,14 +6,15 @@
|
|||||||
namespace resource_api
|
namespace resource_api
|
||||||
{
|
{
|
||||||
|
|
||||||
TransfersHandler::TransfersHandler(StateTokenServer *sts, RsFiles *files):
|
TransfersHandler::TransfersHandler(StateTokenServer *sts, RsFiles *files, RsPeers *peers):
|
||||||
mStateTokenServer(sts), mFiles(files), mLastUpdateTS(0)
|
mStateTokenServer(sts), mFiles(files), mRsPeers(peers), mLastUpdateTS(0)
|
||||||
{
|
{
|
||||||
addResourceHandler("*", this, &TransfersHandler::handleWildcard);
|
addResourceHandler("*", this, &TransfersHandler::handleWildcard);
|
||||||
addResourceHandler("downloads", this, &TransfersHandler::handleDownloads);
|
addResourceHandler("downloads", this, &TransfersHandler::handleDownloads);
|
||||||
addResourceHandler("control_download", this, &TransfersHandler::handleControlDownload);
|
addResourceHandler("uploads", this, &TransfersHandler::handleUploads);
|
||||||
mStateToken = mStateTokenServer->getNewToken();
|
addResourceHandler("control_download", this, &TransfersHandler::handleControlDownload);
|
||||||
mStateTokenServer->registerTickClient(this);
|
mStateToken = mStateTokenServer->getNewToken();
|
||||||
|
mStateTokenServer->registerTickClient(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
TransfersHandler::~TransfersHandler()
|
TransfersHandler::~TransfersHandler()
|
||||||
@ -28,6 +29,7 @@ void TransfersHandler::tick()
|
|||||||
if(time(0) > (mLastUpdateTS + UPDATE_PERIOD_SECONDS))
|
if(time(0) > (mLastUpdateTS + UPDATE_PERIOD_SECONDS))
|
||||||
mStateTokenServer->replaceToken(mStateToken);
|
mStateTokenServer->replaceToken(mStateToken);
|
||||||
|
|
||||||
|
bool replace = false;
|
||||||
// extra check: was the list of files changed?
|
// extra check: was the list of files changed?
|
||||||
// if yes, replace state token immediately
|
// if yes, replace state token immediately
|
||||||
std::list<RsFileHash> dls;
|
std::list<RsFileHash> dls;
|
||||||
@ -35,11 +37,18 @@ void TransfersHandler::tick()
|
|||||||
// there is no guarantee of the order
|
// there is no guarantee of the order
|
||||||
// so have to sort before comparing the lists
|
// so have to sort before comparing the lists
|
||||||
dls.sort();
|
dls.sort();
|
||||||
if(!std::equal(dls.begin(), dls.end(), mDownloadsAtLastCheck.begin()))
|
if(!std::equal(dls.begin(), dls.end(), mDownloadsAtLastCheck.begin()))
|
||||||
{
|
mDownloadsAtLastCheck.swap(dls);
|
||||||
mDownloadsAtLastCheck.swap(dls);
|
|
||||||
mStateTokenServer->replaceToken(mStateToken);
|
std::list<RsFileHash> upls;
|
||||||
}
|
mFiles->FileUploads(upls);
|
||||||
|
|
||||||
|
upls.sort();
|
||||||
|
if(!std::equal(upls.begin(), upls.end(), mUploadsAtLastCheck.begin()))
|
||||||
|
mUploadsAtLastCheck.swap(upls);
|
||||||
|
|
||||||
|
if(replace)
|
||||||
|
mStateTokenServer->replaceToken(mStateToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TransfersHandler::handleWildcard(Request & /*req*/, Response & /*resp*/)
|
void TransfersHandler::handleWildcard(Request & /*req*/, Response & /*resp*/)
|
||||||
@ -50,20 +59,30 @@ void TransfersHandler::handleWildcard(Request & /*req*/, Response & /*resp*/)
|
|||||||
void TransfersHandler::handleControlDownload(Request &req, Response &resp)
|
void TransfersHandler::handleControlDownload(Request &req, Response &resp)
|
||||||
{
|
{
|
||||||
mStateTokenServer->replaceToken(mStateToken);
|
mStateTokenServer->replaceToken(mStateToken);
|
||||||
RsFileHash hash;
|
|
||||||
|
std::string hashString;
|
||||||
std::string action;
|
std::string action;
|
||||||
req.mStream << makeKeyValueReference("action", action);
|
req.mStream << makeKeyValueReference("action", action);
|
||||||
|
req.mStream << makeKeyValueReference("hash", hashString);
|
||||||
|
RsFileHash hash(hashString);
|
||||||
|
|
||||||
if(action == "begin")
|
if(action == "begin")
|
||||||
{
|
{
|
||||||
std::string fname;
|
std::string fname;
|
||||||
double size;
|
double size;
|
||||||
req.mStream << makeKeyValueReference("name", fname);
|
req.mStream << makeKeyValueReference("name", fname);
|
||||||
req.mStream << makeKeyValueReference("size", size);
|
req.mStream << makeKeyValueReference("size", size);
|
||||||
req.mStream << makeKeyValueReference("hash", hash);
|
|
||||||
std::list<RsPeerId> scrIds;
|
std::list<RsPeerId> srcIds;
|
||||||
|
FileInfo finfo;
|
||||||
|
mFiles->FileDetails(hash, RS_FILE_HINTS_REMOTE, finfo);
|
||||||
|
|
||||||
|
for(std::list<TransferInfo>::const_iterator it(finfo.peers.begin());it!=finfo.peers.end();++it)
|
||||||
|
srcIds.push_back((*it).peerId);
|
||||||
|
|
||||||
bool ok = req.mStream.isOK();
|
bool ok = req.mStream.isOK();
|
||||||
if(ok)
|
if(ok)
|
||||||
ok = mFiles->FileRequest(fname, hash, size, "", RS_FILE_REQ_ANONYMOUS_ROUTING, scrIds);
|
ok = mFiles->FileRequest(fname, hash, size, "", RS_FILE_REQ_ANONYMOUS_ROUTING, srcIds);
|
||||||
if(ok)
|
if(ok)
|
||||||
resp.setOk();
|
resp.setOk();
|
||||||
else
|
else
|
||||||
@ -71,7 +90,6 @@ void TransfersHandler::handleControlDownload(Request &req, Response &resp)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
req.mStream << makeKeyValueReference("id", hash);
|
|
||||||
if(!req.mStream.isOK())
|
if(!req.mStream.isOK())
|
||||||
{
|
{
|
||||||
resp.setFail("error: could not deserialise the request");
|
resp.setFail("error: could not deserialise the request");
|
||||||
@ -126,20 +144,11 @@ void TransfersHandler::handleDownloads(Request & /* req */, Response &resp)
|
|||||||
double size = fi.size;
|
double size = fi.size;
|
||||||
double transfered = fi.transfered;
|
double transfered = fi.transfered;
|
||||||
stream << makeKeyValueReference("size", size)
|
stream << makeKeyValueReference("size", size)
|
||||||
<< makeKeyValueReference("transfered", transfered)
|
<< makeKeyValueReference("transferred", transfered)
|
||||||
<< makeKeyValue("transfer_rate", fi.tfRate);
|
<< makeKeyValue("transfer_rate", fi.tfRate);
|
||||||
|
|
||||||
std::string dl_status;
|
std::string dl_status;
|
||||||
/*
|
|
||||||
const uint32_t FT_STATE_FAILED = 0x0000 ;
|
|
||||||
const uint32_t FT_STATE_OKAY = 0x0001 ;
|
|
||||||
const uint32_t FT_STATE_WAITING = 0x0002 ;
|
|
||||||
const uint32_t FT_STATE_DOWNLOADING = 0x0003 ;
|
|
||||||
const uint32_t FT_STATE_COMPLETE = 0x0004 ;
|
|
||||||
const uint32_t FT_STATE_QUEUED = 0x0005 ;
|
|
||||||
const uint32_t FT_STATE_PAUSED = 0x0006 ;
|
|
||||||
const uint32_t FT_STATE_CHECKING_HASH = 0x0007 ;
|
|
||||||
*/
|
|
||||||
switch(fi.downloadStatus)
|
switch(fi.downloadStatus)
|
||||||
{
|
{
|
||||||
case FT_STATE_FAILED:
|
case FT_STATE_FAILED:
|
||||||
@ -176,4 +185,94 @@ void TransfersHandler::handleDownloads(Request & /* req */, Response &resp)
|
|||||||
resp.setOk();
|
resp.setOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TransfersHandler::handleUploads(Request & /* req */, Response &resp)
|
||||||
|
{
|
||||||
|
tick();
|
||||||
|
resp.mStateToken = mStateToken;
|
||||||
|
resp.mDataStream.getStreamToMember();
|
||||||
|
|
||||||
|
RsPeerId ownId = mRsPeers->getOwnId();
|
||||||
|
|
||||||
|
for(std::list<RsFileHash>::iterator lit = mUploadsAtLastCheck.begin();
|
||||||
|
lit != mUploadsAtLastCheck.end(); ++lit)
|
||||||
|
{
|
||||||
|
FileInfo fi;
|
||||||
|
if(mFiles->FileDetails(*lit, RS_FILE_HINTS_UPLOAD, fi))
|
||||||
|
{
|
||||||
|
std::list<TransferInfo>::iterator pit;
|
||||||
|
for(pit = fi.peers.begin(); pit != fi.peers.end(); ++pit)
|
||||||
|
{
|
||||||
|
if (pit->peerId == ownId) //don't display transfer to ourselves
|
||||||
|
continue ;
|
||||||
|
|
||||||
|
std::string sourceName = mRsPeers->getPeerName(pit->peerId);
|
||||||
|
bool isAnon = false;
|
||||||
|
bool isEncryptedE2E = false;
|
||||||
|
|
||||||
|
if(sourceName == "")
|
||||||
|
{
|
||||||
|
isAnon = true;
|
||||||
|
sourceName = pit->peerId.toStdString();
|
||||||
|
|
||||||
|
if(rsFiles->isEncryptedSource(pit->peerId))
|
||||||
|
isEncryptedE2E = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string status;
|
||||||
|
switch(pit->status)
|
||||||
|
{
|
||||||
|
case FT_STATE_FAILED:
|
||||||
|
status = "Failed";
|
||||||
|
break;
|
||||||
|
case FT_STATE_OKAY:
|
||||||
|
status = "Okay";
|
||||||
|
break;
|
||||||
|
case FT_STATE_WAITING:
|
||||||
|
status = "Waiting";
|
||||||
|
break;
|
||||||
|
case FT_STATE_DOWNLOADING:
|
||||||
|
status = "Uploading";
|
||||||
|
break;
|
||||||
|
case FT_STATE_COMPLETE:
|
||||||
|
status = "Complete";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
status = "Complete";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
CompressedChunkMap cChunkMap;
|
||||||
|
|
||||||
|
if(!rsFiles->FileUploadChunksDetails(*lit, pit->peerId, cChunkMap))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
double dlspeed = pit->tfRate;
|
||||||
|
double fileSize = fi.size;
|
||||||
|
double completed = pit->transfered;
|
||||||
|
|
||||||
|
uint32_t chunk_size = 1024*1024;
|
||||||
|
uint32_t nb_chunks = (uint32_t)((fi.size + (uint64_t)chunk_size - 1) / (uint64_t)(chunk_size));
|
||||||
|
uint32_t filled_chunks = cChunkMap.filledChunks(nb_chunks);
|
||||||
|
|
||||||
|
if(filled_chunks > 0 && nb_chunks > 0)
|
||||||
|
completed = cChunkMap.computeProgress(fi.size, chunk_size);
|
||||||
|
else
|
||||||
|
completed = pit->transfered % chunk_size;
|
||||||
|
|
||||||
|
resp.mDataStream.getStreamToMember()
|
||||||
|
<< makeKeyValueReference("hash", fi.hash)
|
||||||
|
<< makeKeyValueReference("name", fi.fname)
|
||||||
|
<< makeKeyValueReference("source", sourceName)
|
||||||
|
<< makeKeyValueReference("size", fileSize)
|
||||||
|
<< makeKeyValueReference("transferred", completed)
|
||||||
|
<< makeKeyValueReference("is_anonymous", isAnon)
|
||||||
|
<< makeKeyValueReference("is_encrypted_e2e", isEncryptedE2E)
|
||||||
|
<< makeKeyValueReference("transfer_rate", dlspeed)
|
||||||
|
<< makeKeyValueReference("status", status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resp.setOk();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace resource_api
|
} // namespace resource_api
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include "ResourceRouter.h"
|
#include "ResourceRouter.h"
|
||||||
#include "StateTokenServer.h"
|
#include "StateTokenServer.h"
|
||||||
|
|
||||||
#include <retroshare/rsfiles.h>
|
#include <retroshare/rsfiles.h>
|
||||||
|
#include <retroshare/rspeers.h>
|
||||||
|
|
||||||
namespace resource_api
|
namespace resource_api
|
||||||
{
|
{
|
||||||
@ -12,7 +12,7 @@ namespace resource_api
|
|||||||
class TransfersHandler: public ResourceRouter, Tickable
|
class TransfersHandler: public ResourceRouter, Tickable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TransfersHandler(StateTokenServer* sts, RsFiles* files);
|
TransfersHandler(StateTokenServer* sts, RsFiles* files, RsPeers *peers);
|
||||||
virtual ~TransfersHandler();
|
virtual ~TransfersHandler();
|
||||||
|
|
||||||
// from Tickable
|
// from Tickable
|
||||||
@ -21,14 +21,17 @@ private:
|
|||||||
void handleWildcard(Request& req, Response& resp);
|
void handleWildcard(Request& req, Response& resp);
|
||||||
void handleControlDownload(Request& req, Response& resp);
|
void handleControlDownload(Request& req, Response& resp);
|
||||||
void handleDownloads(Request& req, Response& resp);
|
void handleDownloads(Request& req, Response& resp);
|
||||||
|
void handleUploads(Request& req, Response& resp);
|
||||||
|
|
||||||
StateTokenServer* mStateTokenServer;
|
StateTokenServer* mStateTokenServer;
|
||||||
RsFiles* mFiles;
|
RsFiles* mFiles;
|
||||||
|
RsPeers* mRsPeers;
|
||||||
|
|
||||||
StateToken mStateToken;
|
StateToken mStateToken;
|
||||||
time_t mLastUpdateTS;
|
time_t mLastUpdateTS;
|
||||||
|
|
||||||
std::list<RsFileHash> mDownloadsAtLastCheck;
|
std::list<RsFileHash> mDownloadsAtLastCheck;
|
||||||
|
std::list<RsFileHash> mUploadsAtLastCheck;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace resource_api
|
} // namespace resource_api
|
||||||
|
@ -182,7 +182,8 @@ SOURCES += \
|
|||||||
util/ContentTypes.cpp \
|
util/ContentTypes.cpp \
|
||||||
api/ApiPluginHandler.cpp \
|
api/ApiPluginHandler.cpp \
|
||||||
api/ChannelsHandler.cpp \
|
api/ChannelsHandler.cpp \
|
||||||
api/StatsHandler.cpp
|
api/StatsHandler.cpp \
|
||||||
|
api/FileSharingHandler.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
api/ApiServer.h \
|
api/ApiServer.h \
|
||||||
@ -209,7 +210,8 @@ HEADERS += \
|
|||||||
util/ContentTypes.h \
|
util/ContentTypes.h \
|
||||||
api/ApiPluginHandler.h \
|
api/ApiPluginHandler.h \
|
||||||
api/ChannelsHandler.h \
|
api/ChannelsHandler.h \
|
||||||
api/StatsHandler.h
|
api/StatsHandler.h \
|
||||||
|
api/FileSharingHandler.h
|
||||||
|
|
||||||
libresapilocalserver {
|
libresapilocalserver {
|
||||||
CONFIG *= qt
|
CONFIG *= qt
|
||||||
|
Loading…
x
Reference in New Issue
Block a user