From 5231f5a22bc75a66d328f797e7721e934bcf448a Mon Sep 17 00:00:00 2001 From: Christophe Dumez Date: Sun, 19 Aug 2007 14:20:54 +0000 Subject: [PATCH] - Rewrote a lot of code concerning finishedTorrents code. It was optimized and should be safer too --- src/FinishedTorrents.cpp | 69 ++++++++++++++++++---------------------- src/FinishedTorrents.h | 4 +-- src/GUI.cpp | 57 ++++++++++++++++++++------------- src/bittorrent.cpp | 59 ++++++++++++++++++++++++++++++++-- src/bittorrent.h | 11 +++++-- 5 files changed, 133 insertions(+), 67 deletions(-) diff --git a/src/FinishedTorrents.cpp b/src/FinishedTorrents.cpp index fad1424e0..dba45eb89 100644 --- a/src/FinishedTorrents.cpp +++ b/src/FinishedTorrents.cpp @@ -74,35 +74,32 @@ FinishedTorrents::~FinishedTorrents(){ delete finishedListModel; } -void FinishedTorrents::addFinishedSHA(QString hash){ - if(finishedSHAs.indexOf(hash) == -1) { - finishedSHAs << hash; - int row = finishedListModel->rowCount(); - torrent_handle h = BTSession->getTorrentHandle(hash); - // Adding torrent to download list - finishedListModel->insertRow(row); - finishedListModel->setData(finishedListModel->index(row, F_NAME), QVariant(h.name().c_str())); - finishedListModel->setData(finishedListModel->index(row, F_SIZE), QVariant((qlonglong)h.get_torrent_info().total_size())); - finishedListModel->setData(finishedListModel->index(row, F_UPSPEED), QVariant((double)0.)); - finishedListModel->setData(finishedListModel->index(row, F_SEEDSLEECH), QVariant("0/0")); - finishedListModel->setData(finishedListModel->index(row, F_RATIO), QVariant(QString(misc::toString(BTSession->getRealRatio(hash)).c_str()))); - finishedListModel->setData(finishedListModel->index(row, F_HASH), QVariant(hash)); - finishedListModel->setData(finishedListModel->index(row, F_PROGRESS), QVariant((double)1.)); - if(h.is_paused()) { - finishedListModel->setData(finishedListModel->index(row, F_NAME), QIcon(":/Icons/skin/paused.png"), Qt::DecorationRole); - setRowColor(row, "red"); - }else{ - finishedListModel->setData(finishedListModel->index(row, F_NAME), QVariant(QIcon(":/Icons/skin/seeding.png")), Qt::DecorationRole); - setRowColor(row, "orange"); - } - // Create .finished file - QFile finished_file(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".finished"); - finished_file.open(QIODevice::WriteOnly | QIODevice::Text); - finished_file.close(); - // Update the number of finished torrents - ++nbFinished; - ((GUI*)parent)->setTabText(1, tr("Finished") +" ("+QString(misc::toString(nbFinished).c_str())+")"); +void FinishedTorrents::addFinishedTorrent(QString hash){ + int row = finishedListModel->rowCount(); + torrent_handle h = BTSession->getTorrentHandle(hash); + // Adding torrent to download list + finishedListModel->insertRow(row); + finishedListModel->setData(finishedListModel->index(row, F_NAME), QVariant(h.name().c_str())); + finishedListModel->setData(finishedListModel->index(row, F_SIZE), QVariant((qlonglong)h.get_torrent_info().total_size())); + finishedListModel->setData(finishedListModel->index(row, F_UPSPEED), QVariant((double)0.)); + finishedListModel->setData(finishedListModel->index(row, F_SEEDSLEECH), QVariant("0/0")); + finishedListModel->setData(finishedListModel->index(row, F_RATIO), QVariant(QString(misc::toString(BTSession->getRealRatio(hash)).c_str()))); + finishedListModel->setData(finishedListModel->index(row, F_HASH), QVariant(hash)); + finishedListModel->setData(finishedListModel->index(row, F_PROGRESS), QVariant((double)1.)); + if(h.is_paused()) { + finishedListModel->setData(finishedListModel->index(row, F_NAME), QIcon(":/Icons/skin/paused.png"), Qt::DecorationRole); + setRowColor(row, "red"); + }else{ + finishedListModel->setData(finishedListModel->index(row, F_NAME), QVariant(QIcon(":/Icons/skin/seeding.png")), Qt::DecorationRole); + setRowColor(row, "orange"); } + // Create .finished file + QFile finished_file(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".finished"); + finished_file.open(QIODevice::WriteOnly | QIODevice::Text); + finished_file.close(); + // Update the number of finished torrents + ++nbFinished; + ((GUI*)parent)->setTabText(1, tr("Finished") +" ("+QString(misc::toString(nbFinished).c_str())+")"); } // Set the color of a row in data model @@ -161,6 +158,7 @@ void FinishedTorrents::on_actionSet_upload_limit_triggered(){ void FinishedTorrents::updateFinishedList(){ Q_ASSERT(((GUI*)parent)->getCurrentTabIndex() == 1); QString hash; + QStringList finishedSHAs = BTSession->getFinishedTorrents(); foreach(hash, finishedSHAs){ torrent_handle h = BTSession->getTorrentHandle(hash); if(!h.is_valid()){ @@ -170,7 +168,8 @@ void FinishedTorrents::updateFinishedList(){ torrent_status torrentStatus = h.status(); int row = getRowFromHash(hash); if(row == -1){ - std::cerr << "ERROR: Can't find torrent in finished list\n"; + qDebug("Cannot find torrent in finished list, adding it"); + addFinishedTorrent(hash); continue; } if(h.is_paused()) continue; @@ -178,6 +177,7 @@ void FinishedTorrents::updateFinishedList(){ // What are you doing here? go back to download tab! qDebug("Info: a torrent was moved from finished to download tab"); deleteFromFinishedList(hash); + BTSession->setFinishedTorrent(hash); emit torrentMovedFromFinishedList(h); continue; } @@ -187,10 +187,6 @@ void FinishedTorrents::updateFinishedList(){ } } -QStringList FinishedTorrents::getFinishedSHAs(){ - return finishedSHAs; -} - int FinishedTorrents::getRowFromHash(QString hash) const{ unsigned int nbRows = finishedListModel->rowCount(); for(unsigned int i=0; iremoveRow(row); QFile::remove(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".finished"); --nbFinished; ((GUI*)parent)->setTabText(1, tr("Finished") +" ("+QString(misc::toString(nbFinished).c_str())+")"); - finishedSHAs.removeAll(hash); + BTSession->setUnfinishedTorrent(hash); } QTreeView* FinishedTorrents::getFinishedList(){ diff --git a/src/FinishedTorrents.h b/src/FinishedTorrents.h index d1e6f16af..529b1f6a7 100644 --- a/src/FinishedTorrents.h +++ b/src/FinishedTorrents.h @@ -38,7 +38,6 @@ class FinishedTorrents : public QWidget, public Ui::seeding{ QObject *parent; bittorrent *BTSession; FinishedListDelegate *finishedListDelegate; - QStringList finishedSHAs; QStandardItemModel *finishedListModel; unsigned int nbFinished; @@ -46,14 +45,13 @@ class FinishedTorrents : public QWidget, public Ui::seeding{ FinishedTorrents(QObject *parent, bittorrent *BTSession); ~FinishedTorrents(); // Methods - QStringList getFinishedSHAs(); QTreeView* getFinishedList(); QStandardItemModel* getFinishedListModel(); bool loadColWidthFinishedList(); int getRowFromHash(QString hash) const; public slots: - void addFinishedSHA(QString sha); + void addFinishedTorrent(QString hash); void updateFinishedList(); void deleteFromFinishedList(QString hash); void showProperties(const QModelIndex &index); diff --git a/src/GUI.cpp b/src/GUI.cpp index e6d8fde02..2be703e3a 100644 --- a/src/GUI.cpp +++ b/src/GUI.cpp @@ -314,7 +314,6 @@ void GUI::addLogPeerBlocked(QString ip){ // Update Info Bar information void GUI::setInfoBar(QString info, QString color){ - qDebug("setInfoBar called"); static unsigned short nbLines = 0; ++nbLines; // Check log size, clear it if too big @@ -548,16 +547,13 @@ void GUI::updateDlList(bool force){ LCD_UpSpeed->display(tmp); // UP LCD LCD_DownSpeed->display(tmp2); // DL LCD // browse handles - std::vector handles = BTSession->getTorrentHandles(); - QStringList finishedSHAs = finishedTorrentTab->getFinishedSHAs(); - unsigned int handlesSize = handles.size(); - for(unsigned int i=0; igetUnfinishedTorrents(); + QString hash; + foreach(hash, unfinishedTorrents){ + torrent_handle h = BTSession->getTorrentHandle(hash); try{ torrent_status torrentStatus = h.status(); QString fileHash = QString(misc::toString(h.info_hash()).c_str()); - // If this is a finished torrent, no need to refresh it here - if(finishedSHAs.indexOf(fileHash) != -1) continue; int row = getRowFromHash(fileHash); if(row == -1){ qDebug("Info: Could not find filename in download list, adding it..."); @@ -574,6 +570,7 @@ void GUI::updateDlList(bool force){ case torrent_status::finished: case torrent_status::seeding: qDebug("A torrent that was in download tab just finished, moving it to finished tab"); + BTSession->setFinishedTorrent(fileHash); finishedTorrent(h); continue; case torrent_status::checking_files: @@ -1112,8 +1109,8 @@ void GUI::on_actionDelete_triggered(){ // Called when a torrent is added void GUI::torrentAdded(QString path, torrent_handle& h, bool fastResume){ QString hash = QString(misc::toString(h.info_hash()).c_str()); - if(QFile::exists(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".finished")){ - finishedTorrentTab->addFinishedSHA(hash); + if(BTSession->isFinished(hash)) { + finishedTorrentTab->addFinishedTorrent(hash); return; } int row = DLListModel->rowCount(); @@ -1585,7 +1582,6 @@ void GUI::finishedTorrent(torrent_handle& h){ } if(show_msg) setInfoBar(tr("%1 has finished downloading.", "e.g: xxx.avi has finished downloading.").arg(fileName)); - finishedTorrentTab->addFinishedSHA(hash); QList items = DLListModel->findItems(hash, Qt::MatchExactly, HASH); Q_ASSERT(items.size() <= 1); if(items.size() != 0){ @@ -1605,32 +1601,39 @@ void GUI::torrentChecked(QString hash){ // Check if the torrent was paused after checking if(BTSession->isPaused(hash)){ // Was paused, change its icon/color - if(finishedTorrentTab->getFinishedSHAs().indexOf(hash) != -1){ + if(BTSession->isFinished(hash)){ // In finished list qDebug("Automatically paused torrent was in finished list"); int row = finishedTorrentTab->getRowFromHash(hash); + if(row == -1){ + finishedTorrentTab->addFinishedTorrent(hash); + row = finishedTorrentTab->getRowFromHash(hash); + } + Q_ASSERT(row != -1); finishedTorrentTab->getFinishedListModel()->setData(finishedTorrentTab->getFinishedListModel()->index(row, F_UPSPEED), QVariant((double)0.0)); finishedTorrentTab->getFinishedListModel()->setData(finishedTorrentTab->getFinishedListModel()->index(row, F_NAME), QIcon(":/Icons/skin/paused.png"), Qt::DecorationRole); finishedTorrentTab->setRowColor(row, "red"); }else{ // In download list int row = getRowFromHash(hash); + torrent_handle h = BTSession->getTorrentHandle(hash); + torrent_status torrentStatus = h.status(); + if(row ==-1){ + restoreInDownloadList(h); + row = getRowFromHash(hash); + } + Q_ASSERT(row != -1); DLListModel->setData(DLListModel->index(row, DLSPEED), QVariant((double)0.0)); DLListModel->setData(DLListModel->index(row, UPSPEED), QVariant((double)0.0)); DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)-1)); DLListModel->setData(DLListModel->index(row, NAME), QIcon(":/Icons/skin/paused.png"), Qt::DecorationRole); setRowColor(row, "red"); + // Update progress in download list + DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)torrentStatus.progress)); + // Delayed Sorting + sortProgressColumnDelayed(); } } - if(finishedTorrentTab->getFinishedSHAs().indexOf(hash) == -1) { - // Update progress in download list - torrent_handle h = BTSession->getTorrentHandle(hash); - torrent_status torrentStatus = h.status(); - int row = getRowFromHash(hash); - DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)torrentStatus.progress)); - // Delayed Sorting - sortProgressColumnDelayed(); - } } // Notification when disk is full @@ -1643,16 +1646,26 @@ void GUI::fullDiskError(torrent_handle& h){ // Download will be paused by libtorrent. Updating GUI information accordingly QString hash = QString(misc::toString(h.info_hash()).c_str()); qDebug("Full disk error, pausing torrent %s", (const char*)hash.toUtf8()); - if(finishedTorrentTab->getFinishedSHAs().indexOf(hash) != -1){ + if(BTSession->isFinished(hash)){ // In finished list qDebug("Automatically paused torrent was in finished list"); int row = finishedTorrentTab->getRowFromHash(hash); + if(row == -1){ + finishedTorrentTab->addFinishedTorrent(hash); + row = finishedTorrentTab->getRowFromHash(hash); + } + Q_ASSERT(row != -1); finishedTorrentTab->getFinishedListModel()->setData(finishedTorrentTab->getFinishedListModel()->index(row, F_UPSPEED), QVariant((double)0.0)); finishedTorrentTab->getFinishedListModel()->setData(finishedTorrentTab->getFinishedListModel()->index(row, F_NAME), QIcon(":/Icons/skin/paused.png"), Qt::DecorationRole); finishedTorrentTab->setRowColor(row, "red"); }else{ // In download list int row = getRowFromHash(hash); + if(row == -1){ + restoreInDownloadList(BTSession->getTorrentHandle(hash)); + row = getRowFromHash(hash); + } + Q_ASSERT(row != -1); DLListModel->setData(DLListModel->index(row, DLSPEED), QVariant((double)0.0)); DLListModel->setData(DLListModel->index(row, UPSPEED), QVariant((double)0.0)); DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)-1)); diff --git a/src/bittorrent.cpp b/src/bittorrent.cpp index ebc627454..8c8b4c4cc 100644 --- a/src/bittorrent.cpp +++ b/src/bittorrent.cpp @@ -187,12 +187,25 @@ void bittorrent::deleteTorrent(QString hash, bool permanent){ // Remove it from ratio table ratioData.remove(hash); int index = fullAllocationModeList.indexOf(hash); - if(index != -1) + if(index != -1){ fullAllocationModeList.removeAt(index); + } // Remove it from pausedTorrents list index = pausedTorrents.indexOf(hash); - if(index != -1) + if(index != -1){ pausedTorrents.removeAt(index); + } + index = finishedTorrents.indexOf(hash); + if(index != -1){ + finishedTorrents.removeAt(index); + }else{ + index = unfinishedTorrents.indexOf(hash); + if(index != -1){ + unfinishedTorrents.removeAt(index); + }else{ + std::cerr << "Error: Torrent " << hash.toStdString() << " is neither in finished or unfinished list\n"; + } + } if(permanent){ // Remove from Hard drive qDebug("Removing this on hard drive: %s", qPrintable(savePath+QDir::separator()+fileName)); @@ -201,6 +214,41 @@ void bittorrent::deleteTorrent(QString hash, bool permanent){ } } +// Return a list of hashes for the finished torrents +QStringList bittorrent::getFinishedTorrents() const { + return finishedTorrents; +} + +QStringList bittorrent::getUnfinishedTorrents() const { + return unfinishedTorrents; +} + +bool bittorrent::isFinished(QString hash) const { + return finishedTorrents.contains(hash); +} + +// Remove the given hash from the list of finished torrents +void bittorrent::setUnfinishedTorrent(QString hash) { + int index = finishedTorrents.indexOf(hash); + if(index != -1){ + finishedTorrents.removeAt(index); + } + if(!unfinishedTorrents.contains(hash)){ + unfinishedTorrents << hash; + } +} + +// Add the given hash to the list of finished torrents +void bittorrent::setFinishedTorrent(QString hash){ + if(!finishedTorrents.contains(hash)){ + finishedTorrents << hash; + } + int index = unfinishedTorrents.indexOf(hash); + if(index != -1){ + unfinishedTorrents.removeAt(index); + } +} + // Pause a running torrent bool bittorrent::pauseTorrent(QString hash){ bool change = false; @@ -406,6 +454,11 @@ void bittorrent::addTorrent(QString path, bool fromScanDir, QString from_url){ qDebug("Incremental download enabled for %s", t.name().c_str()); h.set_sequenced_download_threshold(1); } + if(QFile::exists(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".finished")){ + finishedTorrents << hash; + }else{ + unfinishedTorrents << hash; + } // If download from url, remove temp file if(!from_url.isNull()) QFile::remove(file); // Delete from scan dir to avoid trying to download it again @@ -936,6 +989,8 @@ void bittorrent::readAlerts(){ std::auto_ptr a = s->pop_alert(); while (a.get()){ if (torrent_finished_alert* p = dynamic_cast(a.get())){ + QString hash = QString(misc::toString(p->handle.info_hash()).c_str()); + setFinishedTorrent(hash); emit finishedTorrent(p->handle); } else if (file_error_alert* p = dynamic_cast(a.get())){ diff --git a/src/bittorrent.h b/src/bittorrent.h index 22ef14395..8cd02db79 100644 --- a/src/bittorrent.h +++ b/src/bittorrent.h @@ -53,10 +53,12 @@ class bittorrent : public QObject{ QHash ETAs; QHash > ratioData; QTimer *ETARefresher; - QList fullAllocationModeList; + QStringList fullAllocationModeList; QHash > > trackersErrors; deleteThread *deleter; - QList pausedTorrents; + QStringList pausedTorrents; + QStringList finishedTorrents; + QStringList unfinishedTorrents; protected: QString getSavePath(QString hash); @@ -84,6 +86,9 @@ class bittorrent : public QObject{ QList > getTrackersErrors(QString hash) const; bool receivedPausedAlert(QString hash) const; void printPausedTorrents(); + QStringList getFinishedTorrents() const; + QStringList getUnfinishedTorrents() const; + bool isFinished(QString hash) const; public slots: void addTorrent(QString path, bool fromScanDir = false, QString from_url = QString()); @@ -124,6 +129,8 @@ class bittorrent : public QObject{ void loadFilesPriorities(torrent_handle& h); void setDownloadLimit(QString hash, long val); void setUploadLimit(QString hash, long val); + void setUnfinishedTorrent(QString hash); + void setFinishedTorrent(QString hash); protected slots: void scanDirectory();