added functionnality to complain when a download is initiated over a file already in download, or in the HD

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@2055 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
csoler 2010-01-16 15:42:26 +00:00
parent fee083e6b8
commit e70e995894
6 changed files with 201 additions and 167 deletions

View File

@ -611,6 +611,20 @@ bool ftController::handleAPendingRequest()
return true ; return true ;
} }
bool ftController::alreadyHaveFile(const std::string& hash)
{
FileInfo info ;
// check for downloads
if(FileDetails(hash, info))
return true ;
// check for file lists
if (mSearch->search(hash, RS_FILE_HINTS_LOCAL | RS_FILE_HINTS_EXTRA, info))
return true ;
return false ;
}
bool ftController::FileRequest(std::string fname, std::string hash, bool ftController::FileRequest(std::string fname, std::string hash,
uint64_t size, std::string dest, uint32_t flags, uint64_t size, std::string dest, uint32_t flags,
@ -634,6 +648,10 @@ bool ftController::FileRequest(std::string fname, std::string hash,
} }
/* check if we have the file */ /* check if we have the file */
if(alreadyHaveFile(hash))
return true ;
FileInfo info; FileInfo info;
std::list<std::string>::iterator it; std::list<std::string>::iterator it;
std::list<TransferInfo>::iterator pit; std::list<TransferInfo>::iterator pit;
@ -666,58 +684,59 @@ bool ftController::FileRequest(std::string fname, std::string hash,
* This is important as some guis request duplicate files regularly. * This is important as some guis request duplicate files regularly.
*/ */
{ RsStackMutex stack(ctrlMutex); /******* LOCKED ********/
std::map<std::string, ftFileControl>::iterator dit;
dit = mDownloads.find(hash);
if (dit != mDownloads.end())
{ {
/* we already have it! */ RsStackMutex stack(ctrlMutex); /******* LOCKED ********/
#ifdef CONTROL_DEBUG std::map<std::string, ftFileControl>::iterator dit;
std::cerr << "ftController::FileRequest() Already Downloading File"; dit = mDownloads.find(hash);
std::cerr << std::endl; if (dit != mDownloads.end())
std::cerr << "\tNo need to download";
std::cerr << std::endl;
#endif
/* but we should add this peer - if they don't exist!
* (needed for channels).
*/
for(it = srcIds.begin(); it != srcIds.end(); it++)
{ {
uint32_t i, j; /* we already have it! */
if ((dit->second).mTransfer->getPeerState(*it, i, j))
{
#ifdef CONTROL_DEBUG #ifdef CONTROL_DEBUG
std::cerr << "ftController::FileRequest() Peer Existing"; std::cerr << "ftController::FileRequest() Already Downloading File";
std::cerr << std::endl;
std::cerr << "\tNo need to download";
std::cerr << std::endl;
#endif
/* but we should add this peer - if they don't exist!
* (needed for channels).
*/
for(it = srcIds.begin(); it != srcIds.end(); it++)
{
uint32_t i, j;
if ((dit->second).mTransfer->getPeerState(*it, i, j))
{
#ifdef CONTROL_DEBUG
std::cerr << "ftController::FileRequest() Peer Existing";
std::cerr << std::endl;
#endif
continue; /* already added peer */
}
#ifdef CONTROL_DEBUG
std::cerr << "ftController::FileRequest() Adding Peer: " << *it;
std::cerr << std::endl; std::cerr << std::endl;
#endif #endif
continue; /* already added peer */ (dit->second).mTransfer->addFileSource(*it);
setPeerState(dit->second.mTransfer, *it,
rate, mConnMgr->isOnline(*it));
IndicateConfigChanged(); /* new peer for transfer -> save */
} }
if (srcIds.size() == 0)
{
#ifdef CONTROL_DEBUG #ifdef CONTROL_DEBUG
std::cerr << "ftController::FileRequest() Adding Peer: " << *it; std::cerr << "ftController::FileRequest() WARNING: No Src Peers";
std::cerr << std::endl; std::cerr << std::endl;
#endif #endif
(dit->second).mTransfer->addFileSource(*it); }
setPeerState(dit->second.mTransfer, *it,
rate, mConnMgr->isOnline(*it));
IndicateConfigChanged(); /* new peer for transfer -> save */ return true;
} }
} /******* UNLOCKED ********/
if (srcIds.size() == 0)
{
#ifdef CONTROL_DEBUG
std::cerr << "ftController::FileRequest() WARNING: No Src Peers";
std::cerr << std::endl;
#endif
}
return true;
}
} /******* UNLOCKED ********/
bool doCallback = false; bool doCallback = false;
uint32_t callbackCode = 0; uint32_t callbackCode = 0;
@ -741,19 +760,6 @@ bool ftController::FileRequest(std::string fname, std::string hash,
} }
else else
{ {
if (mSearch->search(hash, RS_FILE_HINTS_LOCAL | RS_FILE_HINTS_EXTRA | RS_FILE_HINTS_SPEC_ONLY, info))
{
/* have it already */
/* add in as completed transfer */
#ifdef CONTROL_DEBUG
std::cerr << "ftController::FileRequest() Matches Local File";
std::cerr << std::endl;
std::cerr << "\tNo need to download";
std::cerr << std::endl;
#endif
return true;
}
/* do a source search - for any extra sources */ /* do a source search - for any extra sources */
if (mSearch->search(hash, RS_FILE_HINTS_REMOTE | RS_FILE_HINTS_SPEC_ONLY, info)) if (mSearch->search(hash, RS_FILE_HINTS_REMOTE | RS_FILE_HINTS_SPEC_ONLY, info))
{ {
@ -802,17 +808,18 @@ bool ftController::FileRequest(std::string fname, std::string hash,
std::string savepath; std::string savepath;
std::string destination; std::string destination;
{ RsStackMutex stack(ctrlMutex); /******* LOCKED ********/
savepath = mPartialsPath + "/" + hash;
destination = dest + "/" + fname;
/* if no destpath - send to download directory */
if (dest == "")
{ {
destination = mDownloadPath + "/" + fname; RsStackMutex stack(ctrlMutex); /******* LOCKED ********/
}
} /******* UNLOCKED ********/ savepath = mPartialsPath + "/" + hash;
destination = dest + "/" + fname;
/* if no destpath - send to download directory */
if (dest == "")
{
destination = mDownloadPath + "/" + fname;
}
} /******* UNLOCKED ********/
// We check that flags are consistent. In particular, for know // We check that flags are consistent. In particular, for know
// we can't send chunkmaps through normal traffic, so availability must be assumed whenever the traffic is not // we can't send chunkmaps through normal traffic, so availability must be assumed whenever the traffic is not

View File

@ -132,6 +132,9 @@ bool FileRequest(std::string fname, std::string hash,
uint64_t size, std::string dest, uint32_t flags, uint64_t size, std::string dest, uint32_t flags,
std::list<std::string> &sourceIds); std::list<std::string> &sourceIds);
/// Do we already have this file, either in download or in file lists ?
bool alreadyHaveFile(const std::string& hash) ;
bool setChunkStrategy(const std::string& hash,FileChunksInfo::ChunkStrategy s); bool setChunkStrategy(const std::string& hash,FileChunksInfo::ChunkStrategy s);
bool FileCancel(std::string hash); bool FileCancel(std::string hash);

View File

@ -245,10 +245,13 @@ void ftServer::run()
bool ftServer::FileRequest(std::string fname, std::string hash, uint64_t size, std::string dest, uint32_t flags, std::list<std::string> srcIds) bool ftServer::FileRequest(std::string fname, std::string hash, uint64_t size, std::string dest, uint32_t flags, std::list<std::string> srcIds)
{ {
std::cerr << "Requesting " << fname << std::endl ; std::cerr << "Requesting " << fname << std::endl ;
// return mFtController->FileRequest(fname, hash, size,
// dest, flags, srcIds); if(mFtController->alreadyHaveFile(hash))
return false ;
const DwlDetails details(fname, hash, size, dest, flags, srcIds, Normal); const DwlDetails details(fname, hash, size, dest, flags, srcIds, Normal);
mFtDwlQueue->insertDownload(details); mFtDwlQueue->insertDownload(details);
return true ; return true ;
} }

View File

@ -98,92 +98,93 @@ class RsFiles
{ {
public: public:
RsFiles() { return; } RsFiles() { return; }
virtual ~RsFiles() { return; } virtual ~RsFiles() { return; }
/****************************************/ /****************************************/
/* download */ /* download */
/*** /***
* Control of Downloads. * Control of Downloads.
***/ ***/
virtual bool FileRequest(std::string fname, std::string hash, uint64_t size,
std::string dest, uint32_t flags, std::list<std::string> srcIds) = 0;
virtual bool FileCancel(std::string hash) = 0;
virtual bool setChunkStrategy(const std::string& hash,FileChunksInfo::ChunkStrategy) = 0;
virtual bool FileControl(std::string hash, uint32_t flags) = 0;
virtual bool FileClearCompleted() = 0;
/*** /// Returns false is we already have the file. Otherwise, initiates the dl and returns true.
* Control of Downloads Priority. virtual bool FileRequest(std::string fname, std::string hash, uint64_t size, std::string dest, uint32_t flags, std::list<std::string> srcIds) = 0;
***/ virtual bool FileCancel(std::string hash) = 0;
virtual bool changePriority(const std::string hash, int priority) = 0; virtual bool setChunkStrategy(const std::string& hash,FileChunksInfo::ChunkStrategy) = 0;
virtual bool getPriority(const std::string hash, int & priority) = 0; virtual bool FileControl(std::string hash, uint32_t flags) = 0;
virtual bool clearDownload(const std::string hash) = 0; virtual bool FileClearCompleted() = 0;
virtual void clearQueue() = 0;
virtual void getDwlDetails(std::list<DwlDetails> & details) = 0;
/*** /***
* Download / Upload Details. * Control of Downloads Priority.
***/ ***/
virtual bool FileDownloads(std::list<std::string> &hashs) = 0; virtual bool changePriority(const std::string hash, int priority) = 0;
virtual bool FileUploads(std::list<std::string> &hashs) = 0; virtual bool getPriority(const std::string hash, int & priority) = 0;
virtual bool FileDetails(std::string hash, uint32_t hintflags, FileInfo &info) = 0; virtual bool clearDownload(const std::string hash) = 0;
virtual void clearQueue() = 0;
virtual void getDwlDetails(std::list<DwlDetails> & details) = 0;
/// Gives chunk details about the downloaded file with given hash. /***
virtual bool FileDownloadChunksDetails(const std::string& hash,FileChunksInfo& info) = 0 ; * Download / Upload Details.
***/
virtual bool FileDownloads(std::list<std::string> &hashs) = 0;
virtual bool FileUploads(std::list<std::string> &hashs) = 0;
virtual bool FileDetails(std::string hash, uint32_t hintflags, FileInfo &info) = 0;
/// details about the upload with given hash /// Gives chunk details about the downloaded file with given hash.
virtual bool FileUploadChunksDetails(const std::string& hash,const std::string& peer_id,CompressedChunkMap& map) = 0 ; virtual bool FileDownloadChunksDetails(const std::string& hash,FileChunksInfo& info) = 0 ;
/*** /// details about the upload with given hash
* Extra List Access virtual bool FileUploadChunksDetails(const std::string& hash,const std::string& peer_id,CompressedChunkMap& map) = 0 ;
***/
virtual bool ExtraFileAdd(std::string fname, std::string hash, uint64_t size, /***
* Extra List Access
***/
virtual bool ExtraFileAdd(std::string fname, std::string hash, uint64_t size,
uint32_t period, uint32_t flags) = 0; uint32_t period, uint32_t flags) = 0;
virtual bool ExtraFileRemove(std::string hash, uint32_t flags) = 0; virtual bool ExtraFileRemove(std::string hash, uint32_t flags) = 0;
virtual bool ExtraFileHash(std::string localpath, virtual bool ExtraFileHash(std::string localpath,
uint32_t period, uint32_t flags) = 0; uint32_t period, uint32_t flags) = 0;
virtual bool ExtraFileStatus(std::string localpath, FileInfo &info) = 0; virtual bool ExtraFileStatus(std::string localpath, FileInfo &info) = 0;
virtual bool ExtraFileMove(std::string fname, std::string hash, uint64_t size, virtual bool ExtraFileMove(std::string fname, std::string hash, uint64_t size,
std::string destpath) = 0; std::string destpath) = 0;
/*** /***
* Directory Listing / Search Interface * Directory Listing / Search Interface
*/ */
virtual int RequestDirDetails(std::string uid, std::string path, DirDetails &details) = 0; virtual int RequestDirDetails(std::string uid, std::string path, DirDetails &details) = 0;
virtual int RequestDirDetails(void *ref, DirDetails &details, uint32_t flags) = 0; virtual int RequestDirDetails(void *ref, DirDetails &details, uint32_t flags) = 0;
virtual int SearchKeywords(std::list<std::string> keywords, std::list<DirDetails> &results,uint32_t flags) = 0; virtual int SearchKeywords(std::list<std::string> keywords, std::list<DirDetails> &results,uint32_t flags) = 0;
virtual int SearchBoolExp(Expression * exp, std::list<DirDetails> &results,uint32_t flags) = 0; virtual int SearchBoolExp(Expression * exp, std::list<DirDetails> &results,uint32_t flags) = 0;
/*** /***
* Utility Functions. * Utility Functions.
***/ ***/
virtual bool ConvertSharedFilePath(std::string path, std::string &fullpath) = 0; virtual bool ConvertSharedFilePath(std::string path, std::string &fullpath) = 0;
virtual void ForceDirectoryCheck() = 0; virtual void ForceDirectoryCheck() = 0;
virtual bool InDirectoryCheck() = 0; virtual bool InDirectoryCheck() = 0;
/*** /***
* Directory Control * Directory Control
***/ ***/
virtual void setDownloadDirectory(std::string path) = 0; virtual void setDownloadDirectory(std::string path) = 0;
virtual void setPartialsDirectory(std::string path) = 0; virtual void setPartialsDirectory(std::string path) = 0;
virtual std::string getDownloadDirectory() = 0; virtual std::string getDownloadDirectory() = 0;
virtual std::string getPartialsDirectory() = 0; virtual std::string getPartialsDirectory() = 0;
virtual bool getSharedDirectories(std::list<SharedDirInfo> &dirs) = 0; virtual bool getSharedDirectories(std::list<SharedDirInfo> &dirs) = 0;
virtual bool addSharedDirectory(SharedDirInfo dir) = 0; virtual bool addSharedDirectory(SharedDirInfo dir) = 0;
virtual bool updateShareFlags(const SharedDirInfo& dir) = 0; // updates the flags. The directory should already exist ! virtual bool updateShareFlags(const SharedDirInfo& dir) = 0; // updates the flags. The directory should already exist !
virtual bool removeSharedDirectory(std::string dir) = 0; virtual bool removeSharedDirectory(std::string dir) = 0;
virtual void setShareDownloadDirectory(bool value) = 0; virtual void setShareDownloadDirectory(bool value) = 0;
virtual bool getShareDownloadDirectory() = 0; virtual bool getShareDownloadDirectory() = 0;
virtual bool shareDownloadDirectory() = 0; virtual bool shareDownloadDirectory() = 0;
virtual bool unshareDownloadDirectory() = 0; virtual bool unshareDownloadDirectory() = 0;
}; };

View File

@ -1091,12 +1091,19 @@ void ForumsDialog::anchorClicked (const QUrl& link )
if (fileName != "" && fileHash != "") if (fileName != "" && fileHash != "")
{ {
std::list<std::string> srcIds; std::list<std::string> srcIds;
//srcIds.push_front();
rsFiles->FileRequest(fileName, fileHash, fileSize, "", RS_FILE_HINTS_NETWORK_WIDE, srcIds);
QMessageBox mb(tr("File Request Confirmation"), tr("The file has been added to your download list."),QMessageBox::Information,QMessageBox::Ok,0,0); if(rsFiles->FileRequest(fileName, fileHash, fileSize, "", RS_FILE_HINTS_NETWORK_WIDE, srcIds))
mb.setButtonText( QMessageBox::Ok, "OK" ); {
mb.exec(); QMessageBox mb(tr("File Request Confirmation"), tr("The file has been added to your download list."),QMessageBox::Information,QMessageBox::Ok,0,0);
mb.setButtonText( QMessageBox::Ok, "OK" );
mb.exec();
}
else
{
QMessageBox mb(tr("File Request canceled"), tr("The file has not been added to your download list, because you already have it."),QMessageBox::Information,QMessageBox::Ok,0,0);
mb.setButtonText( QMessageBox::Ok, "OK" );
mb.exec();
}
} }
else else
{ {

View File

@ -795,38 +795,51 @@ void PopupChatDialog::fileHashingFinished(SubFileItem* file) {
} }
void PopupChatDialog::anchorClicked (const QUrl& link ) { void PopupChatDialog::anchorClicked (const QUrl& link ) {
#ifdef CHAT_DEBUG #ifdef CHAT_DEBUG
std::cerr << "PopupChatDialog::anchorClicked link.scheme() : " << link.scheme().toStdString() << std::endl; std::cerr << "PopupChatDialog::anchorClicked link.scheme() : " << link.scheme().toStdString() << std::endl;
#endif #endif
if (link.scheme() == "file") { if (link.scheme() == "file") {
std::string fileName = link.queryItemValue(QString("fileName")).toStdString(); std::string fileName = link.queryItemValue(QString("fileName")).toStdString();
std::string fileHash = link.queryItemValue(QString("fileHash")).toStdString(); std::string fileHash = link.queryItemValue(QString("fileHash")).toStdString();
uint32_t fileSize = link.queryItemValue(QString("fileSize")).toInt(); uint32_t fileSize = link.queryItemValue(QString("fileSize")).toInt();
#ifdef CHAT_DEBUG #ifdef CHAT_DEBUG
std::cerr << "PopupChatDialog::anchorClicked FileRequest : fileName : " << fileName << ". fileHash : " << fileHash << ". fileSize : " << fileSize; std::cerr << "PopupChatDialog::anchorClicked FileRequest : fileName : " << fileName << ". fileHash : " << fileHash << ". fileSize : " << fileSize;
std::cerr << ". source id : " << dialogId << std::endl; std::cerr << ". source id : " << dialogId << std::endl;
#endif #endif
if (fileName != "" && if (fileName != "" &&
fileHash != "") { fileHash != "") {
std::list<std::string> srcIds; std::list<std::string> srcIds;
srcIds.push_front(dialogId); srcIds.push_front(dialogId);
rsFiles->FileRequest(fileName, fileHash, fileSize, "", RS_FILE_HINTS_ASSUME_AVAILABILITY, srcIds);
QMessageBox mb(tr("File Request Confirmation"), tr("The file has been added to your download list."),QMessageBox::Information,QMessageBox::Ok,0,0); if(rsFiles->FileRequest(fileName, fileHash, fileSize, "", RS_FILE_HINTS_ASSUME_AVAILABILITY, srcIds))
mb.setButtonText( QMessageBox::Ok, "OK" ); {
mb.exec(); QMessageBox mb(tr("File Request Confirmation"), tr("The file has been added to your download list."),QMessageBox::Information,QMessageBox::Ok,0,0);
} else { mb.setButtonText( QMessageBox::Ok, "OK" );
QMessageBox mb(tr("File Request Error"), tr("The file link is malformed."),QMessageBox::Information,QMessageBox::Ok,0,0); mb.exec();
mb.setButtonText( QMessageBox::Ok, "OK" ); }
mb.exec(); else
} {
} else if (link.scheme() == "http") { QMessageBox mb(tr("File Request canceled"), tr("The file has not been added to your download list, because you already have it, or you're already downloading it."),QMessageBox::Information,QMessageBox::Ok,0,0);
QDesktopServices::openUrl(link); mb.setButtonText( QMessageBox::Ok, "OK" );
} else if (link.scheme() == "") { mb.exec();
//it's probably a web adress, let's add http:// at the beginning of the link }
QString newAddress = link.toString();
newAddress.prepend("http://"); }
QDesktopServices::openUrl(QUrl(newAddress)); else
{
QMessageBox mb(tr("File Request Error"), tr("The file link is malformed."),QMessageBox::Information,QMessageBox::Ok,0,0);
mb.setButtonText( QMessageBox::Ok, "OK" );
mb.exec();
}
}
else if (link.scheme() == "http")
QDesktopServices::openUrl(link);
else if (link.scheme() == "")
{
//it's probably a web adress, let's add http:// at the beginning of the link
QString newAddress = link.toString();
newAddress.prepend("http://");
QDesktopServices::openUrl(QUrl(newAddress));
} }
} }