From e70e995894b81a443fdeb016d00a7086167ec41a Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 16 Jan 2010 15:42:26 +0000 Subject: [PATCH] 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 --- libretroshare/src/ft/ftcontroller.cc | 133 +++++++++-------- libretroshare/src/ft/ftcontroller.h | 3 + libretroshare/src/ft/ftserver.cc | 7 +- libretroshare/src/rsiface/rsfiles.h | 135 +++++++++--------- retroshare-gui/src/gui/ForumsDialog.cpp | 17 ++- .../src/gui/chat/PopupChatDialog.cpp | 73 ++++++---- 6 files changed, 201 insertions(+), 167 deletions(-) diff --git a/libretroshare/src/ft/ftcontroller.cc b/libretroshare/src/ft/ftcontroller.cc index 3a805ff28..8738a0206 100644 --- a/libretroshare/src/ft/ftcontroller.cc +++ b/libretroshare/src/ft/ftcontroller.cc @@ -611,6 +611,20 @@ bool ftController::handleAPendingRequest() 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, 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 */ + + if(alreadyHaveFile(hash)) + return true ; + FileInfo info; std::list::iterator it; std::list::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. */ - { RsStackMutex stack(ctrlMutex); /******* LOCKED ********/ + { + RsStackMutex stack(ctrlMutex); /******* LOCKED ********/ - std::map::iterator dit; - dit = mDownloads.find(hash); - if (dit != mDownloads.end()) - { - /* we already have it! */ - -#ifdef CONTROL_DEBUG - 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++) + std::map::iterator dit; + dit = mDownloads.find(hash); + if (dit != mDownloads.end()) { - uint32_t i, j; - if ((dit->second).mTransfer->getPeerState(*it, i, j)) - { + /* we already have it! */ + #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; #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 - std::cerr << "ftController::FileRequest() Adding Peer: " << *it; - std::cerr << std::endl; + std::cerr << "ftController::FileRequest() WARNING: No Src Peers"; + std::cerr << std::endl; #endif - (dit->second).mTransfer->addFileSource(*it); - setPeerState(dit->second.mTransfer, *it, - rate, mConnMgr->isOnline(*it)); + } - IndicateConfigChanged(); /* new peer for transfer -> save */ + return true; } - - if (srcIds.size() == 0) - { -#ifdef CONTROL_DEBUG - std::cerr << "ftController::FileRequest() WARNING: No Src Peers"; - std::cerr << std::endl; -#endif - } - - return true; - } - } /******* UNLOCKED ********/ + } /******* UNLOCKED ********/ bool doCallback = false; uint32_t callbackCode = 0; @@ -741,19 +760,6 @@ bool ftController::FileRequest(std::string fname, std::string hash, } 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 */ 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 destination; - { RsStackMutex stack(ctrlMutex); /******* LOCKED ********/ + { + RsStackMutex stack(ctrlMutex); /******* LOCKED ********/ - savepath = mPartialsPath + "/" + hash; - destination = dest + "/" + fname; + savepath = mPartialsPath + "/" + hash; + destination = dest + "/" + fname; - /* if no destpath - send to download directory */ - if (dest == "") - { - destination = mDownloadPath + "/" + fname; - } - } /******* UNLOCKED ********/ + /* if no destpath - send to download directory */ + if (dest == "") + { + destination = mDownloadPath + "/" + fname; + } + } /******* UNLOCKED ********/ // 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 diff --git a/libretroshare/src/ft/ftcontroller.h b/libretroshare/src/ft/ftcontroller.h index dbe6b37ad..fb8aed95b 100644 --- a/libretroshare/src/ft/ftcontroller.h +++ b/libretroshare/src/ft/ftcontroller.h @@ -132,6 +132,9 @@ bool FileRequest(std::string fname, std::string hash, uint64_t size, std::string dest, uint32_t flags, std::list &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 FileCancel(std::string hash); diff --git a/libretroshare/src/ft/ftserver.cc b/libretroshare/src/ft/ftserver.cc index e3ef1095e..7e0457f39 100644 --- a/libretroshare/src/ft/ftserver.cc +++ b/libretroshare/src/ft/ftserver.cc @@ -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 srcIds) { 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); mFtDwlQueue->insertDownload(details); + return true ; } diff --git a/libretroshare/src/rsiface/rsfiles.h b/libretroshare/src/rsiface/rsfiles.h index 9fc05af4a..1e01fd918 100644 --- a/libretroshare/src/rsiface/rsfiles.h +++ b/libretroshare/src/rsiface/rsfiles.h @@ -98,92 +98,93 @@ class RsFiles { public: - RsFiles() { return; } -virtual ~RsFiles() { return; } + RsFiles() { return; } + virtual ~RsFiles() { return; } -/****************************************/ - /* download */ + /****************************************/ + /* download */ -/*** - * Control of Downloads. - ***/ -virtual bool FileRequest(std::string fname, std::string hash, uint64_t size, - std::string dest, uint32_t flags, std::list 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; + /*** + * Control of Downloads. + ***/ -/*** - * Control of Downloads Priority. - ***/ -virtual bool changePriority(const std::string hash, int priority) = 0; -virtual bool getPriority(const std::string hash, int & priority) = 0; -virtual bool clearDownload(const std::string hash) = 0; -virtual void clearQueue() = 0; -virtual void getDwlDetails(std::list & details) = 0; + /// Returns false is we already have the file. Otherwise, initiates the dl and returns true. + virtual bool FileRequest(std::string fname, std::string hash, uint64_t size, std::string dest, uint32_t flags, std::list 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; -/*** - * Download / Upload Details. - ***/ -virtual bool FileDownloads(std::list &hashs) = 0; -virtual bool FileUploads(std::list &hashs) = 0; -virtual bool FileDetails(std::string hash, uint32_t hintflags, FileInfo &info) = 0; + /*** + * Control of Downloads Priority. + ***/ + virtual bool changePriority(const std::string hash, int priority) = 0; + virtual bool getPriority(const std::string hash, int & priority) = 0; + virtual bool clearDownload(const std::string hash) = 0; + virtual void clearQueue() = 0; + virtual void getDwlDetails(std::list & 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 &hashs) = 0; + virtual bool FileUploads(std::list &hashs) = 0; + virtual bool FileDetails(std::string hash, uint32_t hintflags, FileInfo &info) = 0; -/// details about the upload with given hash -virtual bool FileUploadChunksDetails(const std::string& hash,const std::string& peer_id,CompressedChunkMap& map) = 0 ; + /// Gives chunk details about the downloaded file with given hash. + virtual bool FileDownloadChunksDetails(const std::string& hash,FileChunksInfo& info) = 0 ; -/*** - * Extra List Access - ***/ -virtual bool ExtraFileAdd(std::string fname, std::string hash, uint64_t size, + /// details about the upload with given hash + virtual bool FileUploadChunksDetails(const std::string& hash,const std::string& peer_id,CompressedChunkMap& map) = 0 ; + + /*** + * Extra List Access + ***/ + virtual bool ExtraFileAdd(std::string fname, std::string hash, uint64_t size, uint32_t period, uint32_t flags) = 0; -virtual bool ExtraFileRemove(std::string hash, uint32_t flags) = 0; -virtual bool ExtraFileHash(std::string localpath, + virtual bool ExtraFileRemove(std::string hash, uint32_t flags) = 0; + virtual bool ExtraFileHash(std::string localpath, uint32_t period, uint32_t flags) = 0; -virtual bool ExtraFileStatus(std::string localpath, FileInfo &info) = 0; -virtual bool ExtraFileMove(std::string fname, std::string hash, uint64_t size, + virtual bool ExtraFileStatus(std::string localpath, FileInfo &info) = 0; + virtual bool ExtraFileMove(std::string fname, std::string hash, uint64_t size, std::string destpath) = 0; -/*** - * Directory Listing / Search Interface - */ -virtual int RequestDirDetails(std::string uid, std::string path, DirDetails &details) = 0; -virtual int RequestDirDetails(void *ref, DirDetails &details, uint32_t flags) = 0; + /*** + * Directory Listing / Search Interface + */ + 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 SearchKeywords(std::list keywords, std::list &results,uint32_t flags) = 0; -virtual int SearchBoolExp(Expression * exp, std::list &results,uint32_t flags) = 0; + virtual int SearchKeywords(std::list keywords, std::list &results,uint32_t flags) = 0; + virtual int SearchBoolExp(Expression * exp, std::list &results,uint32_t flags) = 0; -/*** - * Utility Functions. - ***/ -virtual bool ConvertSharedFilePath(std::string path, std::string &fullpath) = 0; -virtual void ForceDirectoryCheck() = 0; -virtual bool InDirectoryCheck() = 0; + /*** + * Utility Functions. + ***/ + virtual bool ConvertSharedFilePath(std::string path, std::string &fullpath) = 0; + virtual void ForceDirectoryCheck() = 0; + virtual bool InDirectoryCheck() = 0; -/*** - * Directory Control - ***/ -virtual void setDownloadDirectory(std::string path) = 0; -virtual void setPartialsDirectory(std::string path) = 0; -virtual std::string getDownloadDirectory() = 0; -virtual std::string getPartialsDirectory() = 0; + /*** + * Directory Control + ***/ + virtual void setDownloadDirectory(std::string path) = 0; + virtual void setPartialsDirectory(std::string path) = 0; + virtual std::string getDownloadDirectory() = 0; + virtual std::string getPartialsDirectory() = 0; -virtual bool getSharedDirectories(std::list &dirs) = 0; -virtual bool addSharedDirectory(SharedDirInfo dir) = 0; -virtual bool updateShareFlags(const SharedDirInfo& dir) = 0; // updates the flags. The directory should already exist ! -virtual bool removeSharedDirectory(std::string dir) = 0; + virtual bool getSharedDirectories(std::list &dirs) = 0; + virtual bool addSharedDirectory(SharedDirInfo dir) = 0; + virtual bool updateShareFlags(const SharedDirInfo& dir) = 0; // updates the flags. The directory should already exist ! + virtual bool removeSharedDirectory(std::string dir) = 0; -virtual void setShareDownloadDirectory(bool value) = 0; -virtual bool getShareDownloadDirectory() = 0; -virtual bool shareDownloadDirectory() = 0; -virtual bool unshareDownloadDirectory() = 0; + virtual void setShareDownloadDirectory(bool value) = 0; + virtual bool getShareDownloadDirectory() = 0; + virtual bool shareDownloadDirectory() = 0; + virtual bool unshareDownloadDirectory() = 0; }; diff --git a/retroshare-gui/src/gui/ForumsDialog.cpp b/retroshare-gui/src/gui/ForumsDialog.cpp index e974db63e..b3fb05449 100644 --- a/retroshare-gui/src/gui/ForumsDialog.cpp +++ b/retroshare-gui/src/gui/ForumsDialog.cpp @@ -1091,12 +1091,19 @@ void ForumsDialog::anchorClicked (const QUrl& link ) if (fileName != "" && fileHash != "") { std::list 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); - mb.setButtonText( QMessageBox::Ok, "OK" ); - mb.exec(); + if(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); + 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 { diff --git a/retroshare-gui/src/gui/chat/PopupChatDialog.cpp b/retroshare-gui/src/gui/chat/PopupChatDialog.cpp index 2cce1b7fc..0868940a7 100644 --- a/retroshare-gui/src/gui/chat/PopupChatDialog.cpp +++ b/retroshare-gui/src/gui/chat/PopupChatDialog.cpp @@ -795,38 +795,51 @@ void PopupChatDialog::fileHashingFinished(SubFileItem* file) { } void PopupChatDialog::anchorClicked (const QUrl& link ) { - #ifdef CHAT_DEBUG - std::cerr << "PopupChatDialog::anchorClicked link.scheme() : " << link.scheme().toStdString() << std::endl; - #endif +#ifdef CHAT_DEBUG + std::cerr << "PopupChatDialog::anchorClicked link.scheme() : " << link.scheme().toStdString() << std::endl; +#endif if (link.scheme() == "file") { - std::string fileName = link.queryItemValue(QString("fileName")).toStdString(); - std::string fileHash = link.queryItemValue(QString("fileHash")).toStdString(); - uint32_t fileSize = link.queryItemValue(QString("fileSize")).toInt(); - #ifdef CHAT_DEBUG - std::cerr << "PopupChatDialog::anchorClicked FileRequest : fileName : " << fileName << ". fileHash : " << fileHash << ". fileSize : " << fileSize; - std::cerr << ". source id : " << dialogId << std::endl; - #endif - if (fileName != "" && - fileHash != "") { - std::list srcIds; - srcIds.push_front(dialogId); - rsFiles->FileRequest(fileName, fileHash, fileSize, "", RS_FILE_HINTS_ASSUME_AVAILABILITY, srcIds); + std::string fileName = link.queryItemValue(QString("fileName")).toStdString(); + std::string fileHash = link.queryItemValue(QString("fileHash")).toStdString(); + uint32_t fileSize = link.queryItemValue(QString("fileSize")).toInt(); +#ifdef CHAT_DEBUG + std::cerr << "PopupChatDialog::anchorClicked FileRequest : fileName : " << fileName << ". fileHash : " << fileHash << ". fileSize : " << fileSize; + std::cerr << ". source id : " << dialogId << std::endl; +#endif + if (fileName != "" && + fileHash != "") { + std::list srcIds; + srcIds.push_front(dialogId); - 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 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)); + if(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); + 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, or you're already downloading it."),QMessageBox::Information,QMessageBox::Ok,0,0); + mb.setButtonText( QMessageBox::Ok, "OK" ); + mb.exec(); + } + + } + 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)); } }