Browse Source

- Huge code refactoring (qBittorrent no longer store torrents and access them using libtorrent API)

adaptive-webui-19844
Christophe Dumez 16 years ago
parent
commit
4f2a2dfab9
  1. 44
      src/FinishedTorrents.cpp
  2. 3
      src/FinishedTorrents.h
  3. 145
      src/GUI.cpp
  4. 4
      src/GUI.h
  5. 124
      src/bittorrent.cpp
  6. 9
      src/bittorrent.h
  7. 64
      src/downloadingTorrents.cpp
  8. 6
      src/downloadingTorrents.h
  9. 33
      src/httpserver.cpp

44
src/FinishedTorrents.cpp

@ -99,9 +99,6 @@ void FinishedTorrents::notifyTorrentDoubleClicked(const QModelIndex& index) {
} }
void FinishedTorrents::addTorrent(QString hash){ void FinishedTorrents::addTorrent(QString hash){
if(!BTSession->isFinished(hash)){
BTSession->setFinishedTorrent(hash);
}
int row = getRowFromHash(hash); int row = getRowFromHash(hash);
if(row != -1) return; if(row != -1) return;
row = finishedListModel->rowCount(); row = finishedListModel->rowCount();
@ -126,13 +123,6 @@ void FinishedTorrents::addTorrent(QString hash){
emit finishedTorrentsNumberChanged(nbFinished); emit finishedTorrentsNumberChanged(nbFinished);
} }
void FinishedTorrents::torrentAdded(QTorrentHandle& h) {
QString hash = h.hash();
if(BTSession->isFinished(hash)) {
addTorrent(hash);
}
}
// Set the color of a row in data model // Set the color of a row in data model
void FinishedTorrents::setRowColor(int row, QString color){ void FinishedTorrents::setRowColor(int row, QString color){
unsigned int nbColumns = finishedListModel->columnCount()-1; unsigned int nbColumns = finishedListModel->columnCount()-1;
@ -239,15 +229,8 @@ void FinishedTorrents::on_actionSet_upload_limit_triggered(){
new BandwidthAllocationDialog(this, true, BTSession, hashes); new BandwidthAllocationDialog(this, true, BTSession, hashes);
} }
void FinishedTorrents::updateFinishedList(){ void FinishedTorrents::updateTorrent(QTorrentHandle h) {
QString hash; QString hash = h.hash();
QStringList finishedSHAs = BTSession->getFinishedTorrents();
foreach(hash, finishedSHAs){
QTorrentHandle h = BTSession->getTorrentHandle(hash);
if(!h.is_valid()){
qDebug("Problem: This torrent is not valid in finished list");
continue;
}
int row = getRowFromHash(hash); int row = getRowFromHash(hash);
if(row == -1){ if(row == -1){
qDebug("Cannot find torrent in finished list, adding it"); qDebug("Cannot find torrent in finished list, adding it");
@ -256,7 +239,7 @@ void FinishedTorrents::updateFinishedList(){
} }
Q_ASSERT(row != -1); Q_ASSERT(row != -1);
// Update queued torrent // Update queued torrent
if(BTSession->isQueueingEnabled() && BTSession->isTorrentQueued(hash)) { if(BTSession->isQueueingEnabled() && h.is_queued()) {
if(h.state() == torrent_status::checking_files || h.state() == torrent_status::queued_for_checking){ if(h.state() == torrent_status::checking_files || h.state() == torrent_status::queued_for_checking){
finishedListModel->setData(finishedListModel->index(row, F_NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/time.png"))), Qt::DecorationRole); finishedListModel->setData(finishedListModel->index(row, F_NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/time.png"))), Qt::DecorationRole);
} else { } else {
@ -266,27 +249,13 @@ void FinishedTorrents::updateFinishedList(){
finishedListModel->setData(finishedListModel->index(row, F_UPSPEED), 0.); finishedListModel->setData(finishedListModel->index(row, F_UPSPEED), 0.);
finishedListModel->setData(finishedListModel->index(row, F_LEECH), "0"); finishedListModel->setData(finishedListModel->index(row, F_LEECH), "0");
setRowColor(row, QString::fromUtf8("grey")); setRowColor(row, QString::fromUtf8("grey"));
return;
} }
if(h.is_paused() || h.is_queued()) continue; if(h.is_paused()) return;
if(h.state() == torrent_status::downloading || (h.state() != torrent_status::checking_files && h.state() != torrent_status::queued_for_checking && h.progress() < 1.)) {
// What are you doing here? go back to download tab!
int reponse = QMessageBox::question(this, tr("Incomplete torrent in seeding list"), tr("It appears that the state of '%1' torrent changed from 'seeding' to 'downloading'. Would you like to move it back to download list? (otherwise the torrent will simply be deleted)").arg(h.name()), QMessageBox::Yes | QMessageBox::No);
if (reponse == QMessageBox::Yes) {
qDebug("Info: a torrent was moved from finished to download tab");
deleteTorrent(hash);
BTSession->setUnfinishedTorrent(hash);
emit torrentMovedFromFinishedList(hash);
}
else if (reponse == QMessageBox::No) {
qDebug("Deleted from the finished");
BTSession->deleteTorrent(hash, false);
}
continue;
}
if(h.state() == torrent_status::checking_files || h.state() == torrent_status::queued_for_checking){ if(h.state() == torrent_status::checking_files || h.state() == torrent_status::queued_for_checking){
finishedListModel->setData(finishedListModel->index(row, F_NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/time.png"))), Qt::DecorationRole); finishedListModel->setData(finishedListModel->index(row, F_NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/time.png"))), Qt::DecorationRole);
setRowColor(row, QString::fromUtf8("grey")); setRowColor(row, QString::fromUtf8("grey"));
continue; return;
} }
setRowColor(row, QString::fromUtf8("orange")); setRowColor(row, QString::fromUtf8("orange"));
finishedListModel->setData(finishedListModel->index(row, F_NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/seeding.png"))), Qt::DecorationRole); finishedListModel->setData(finishedListModel->index(row, F_NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/seeding.png"))), Qt::DecorationRole);
@ -300,7 +269,6 @@ void FinishedTorrents::updateFinishedList(){
finishedListModel->setData(finishedListModel->index(row, F_RATIO), QVariant(misc::toQString(BTSession->getRealRatio(hash)))); finishedListModel->setData(finishedListModel->index(row, F_RATIO), QVariant(misc::toQString(BTSession->getRealRatio(hash))));
} }
} }
}
int FinishedTorrents::getRowFromHash(QString hash) const{ int FinishedTorrents::getRowFromHash(QString hash) const{
unsigned int nbRows = finishedListModel->rowCount(); unsigned int nbRows = finishedListModel->rowCount();

3
src/FinishedTorrents.h

@ -65,7 +65,6 @@ class FinishedTorrents : public QWidget, public Ui::seeding {
void sortFinishedListFloat(int index, Qt::SortOrder sortOrder); void sortFinishedListFloat(int index, Qt::SortOrder sortOrder);
void sortFinishedListString(int index, Qt::SortOrder sortOrder); void sortFinishedListString(int index, Qt::SortOrder sortOrder);
void updateFileSize(QString hash); void updateFileSize(QString hash);
void torrentAdded(QTorrentHandle& h);
void on_actionSet_upload_limit_triggered(); void on_actionSet_upload_limit_triggered();
void notifyTorrentDoubleClicked(const QModelIndex& index); void notifyTorrentDoubleClicked(const QModelIndex& index);
void hideOrShowColumnName(); void hideOrShowColumnName();
@ -77,7 +76,7 @@ class FinishedTorrents : public QWidget, public Ui::seeding {
public slots: public slots:
void addTorrent(QString hash); void addTorrent(QString hash);
void updateFinishedList(); void updateTorrent(QTorrentHandle h);
void pauseTorrent(QString hash); void pauseTorrent(QString hash);
void resumeTorrent(QString hash); void resumeTorrent(QString hash);
void propertiesSelection(); void propertiesSelection();

145
src/GUI.cpp

@ -121,13 +121,13 @@ GUI::GUI(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent), dis
BTSession = new bittorrent(); BTSession = new bittorrent();
connect(BTSession, SIGNAL(fullDiskError(QTorrentHandle&)), this, SLOT(fullDiskError(QTorrentHandle&))); connect(BTSession, SIGNAL(fullDiskError(QTorrentHandle&)), this, SLOT(fullDiskError(QTorrentHandle&)));
connect(BTSession, SIGNAL(finishedTorrent(QTorrentHandle&)), this, SLOT(finishedTorrent(QTorrentHandle&))); connect(BTSession, SIGNAL(finishedTorrent(QTorrentHandle&)), this, SLOT(finishedTorrent(QTorrentHandle&)));
connect(BTSession, SIGNAL(addedTorrent(QTorrentHandle&)), this, SLOT(addedTorrent(QTorrentHandle&)));
connect(BTSession, SIGNAL(torrentFinishedChecking(QTorrentHandle&)), this, SLOT(checkedTorrent(QTorrentHandle&)));
connect(BTSession, SIGNAL(trackerAuthenticationRequired(QTorrentHandle&)), this, SLOT(trackerAuthenticationRequired(QTorrentHandle&))); connect(BTSession, SIGNAL(trackerAuthenticationRequired(QTorrentHandle&)), this, SLOT(trackerAuthenticationRequired(QTorrentHandle&)));
connect(BTSession, SIGNAL(newDownloadedTorrent(QString, QString)), this, SLOT(processDownloadedFiles(QString, QString))); connect(BTSession, SIGNAL(newDownloadedTorrent(QString, QString)), this, SLOT(processDownloadedFiles(QString, QString)));
connect(BTSession, SIGNAL(downloadFromUrlFailure(QString, QString)), this, SLOT(handleDownloadFromUrlFailure(QString, QString))); connect(BTSession, SIGNAL(downloadFromUrlFailure(QString, QString)), this, SLOT(handleDownloadFromUrlFailure(QString, QString)));
connect(BTSession, SIGNAL(deletedTorrent(QString)), this, SLOT(deleteTorrent(QString))); connect(BTSession, SIGNAL(deletedTorrent(QString)), this, SLOT(deleteTorrent(QString)));
connect(BTSession, SIGNAL(pausedTorrent(QString)), this, SLOT(pauseTorrent(QString))); connect(BTSession, SIGNAL(pausedTorrent(QString)), this, SLOT(pauseTorrent(QString)));
connect(BTSession, SIGNAL(updateUnfinishedTorrentNumber()), this, SLOT(updateUnfinishedTorrentNumberCalc()));
connect(BTSession, SIGNAL(updateFinishedTorrentNumber()), this, SLOT(updateFinishedTorrentNumberCalc()));
qDebug("create tabWidget"); qDebug("create tabWidget");
tabs = new QTabWidget(); tabs = new QTabWidget();
// Download torrents tab // Download torrents tab
@ -348,14 +348,12 @@ void GUI::finishedTorrent(QTorrentHandle& h) const {
qDebug("In GUI, a torrent has finished"); qDebug("In GUI, a torrent has finished");
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
bool show_msg = true; bool show_msg = true;
if(QFile::exists(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+h.hash()+".finished"))
show_msg = false;
QString fileName = h.name(); QString fileName = h.name();
bool useNotificationBalloons = settings.value(QString::fromUtf8("Preferences/General/NotificationBaloons"), true).toBool(); bool useNotificationBalloons = settings.value(QString::fromUtf8("Preferences/General/NotificationBaloons"), true).toBool();
// Add it to finished tab // Add it to finished tab
QString hash = h.hash(); QString hash = h.hash();
if(QFile::exists(misc::qBittorrentPath()+QString::fromUtf8("BT_backup")+QDir::separator()+hash+QString::fromUtf8(".finished"))) {
show_msg = false;
qDebug("We received a finished signal for torrent %s, but it already has a .finished file", hash.toUtf8().data());
}
if(show_msg) if(show_msg)
BTSession->addConsoleMessage(tr("%1 has finished downloading.", "e.g: xxx.avi has finished downloading.").arg(fileName)); BTSession->addConsoleMessage(tr("%1 has finished downloading.", "e.g: xxx.avi has finished downloading.").arg(fileName));
downloadingTorrentTab->deleteTorrent(hash); downloadingTorrentTab->deleteTorrent(hash);
@ -365,6 +363,22 @@ void GUI::finishedTorrent(QTorrentHandle& h) const {
} }
} }
void GUI::addedTorrent(QTorrentHandle& h) const {
if(h.is_seed()) {
finishedTorrentTab->addTorrent(h.hash());
} else {
downloadingTorrentTab->addTorrent(h.hash());
}
}
void GUI::checkedTorrent(QTorrentHandle& h) const {
if(h.is_seed()) {
// Move torrent to finished tab
downloadingTorrentTab->deleteTorrent(h.hash());
finishedTorrentTab->addTorrent(h.hash());
}
}
// Notification when disk is full // Notification when disk is full
void GUI::fullDiskError(QTorrentHandle& h) const { void GUI::fullDiskError(QTorrentHandle& h) const {
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
@ -1117,23 +1131,11 @@ void GUI::updateUnfinishedTorrentNumber(unsigned int nb) {
tabs->setTabText(0, tr("Downloads") +QString::fromUtf8(" (")+misc::toQString(nb-paused)+"/"+misc::toQString(nb)+QString::fromUtf8(")")); tabs->setTabText(0, tr("Downloads") +QString::fromUtf8(" (")+misc::toQString(nb-paused)+"/"+misc::toQString(nb)+QString::fromUtf8(")"));
} }
void GUI::updateUnfinishedTorrentNumberCalc() {
unsigned int paused = BTSession->getUnfinishedPausedTorrentsNb();
unsigned int nb = BTSession->getUnfinishedTorrents().size();
tabs->setTabText(0, tr("Downloads") +QString::fromUtf8(" (")+misc::toQString(nb-paused)+"/"+misc::toQString(nb)+QString::fromUtf8(")"));
}
void GUI::updateFinishedTorrentNumber(unsigned int nb) { void GUI::updateFinishedTorrentNumber(unsigned int nb) {
unsigned int paused = BTSession->getFinishedPausedTorrentsNb(); unsigned int paused = BTSession->getFinishedPausedTorrentsNb();
tabs->setTabText(1, tr("Finished") +QString::fromUtf8(" (")+misc::toQString(nb-paused)+"/"+misc::toQString(nb)+QString::fromUtf8(")")); tabs->setTabText(1, tr("Finished") +QString::fromUtf8(" (")+misc::toQString(nb-paused)+"/"+misc::toQString(nb)+QString::fromUtf8(")"));
} }
void GUI::updateFinishedTorrentNumberCalc() {
unsigned int paused = BTSession->getFinishedPausedTorrentsNb();
unsigned int nb = BTSession->getFinishedTorrents().size();
tabs->setTabText(1, tr("Finished") +QString::fromUtf8(" (")+misc::toQString(nb-paused)+"/"+misc::toQString(nb)+QString::fromUtf8(")"));
}
// Allow to change action on double-click // Allow to change action on double-click
void GUI::torrentDoubleClicked(QString hash, bool finished) { void GUI::torrentDoubleClicked(QString hash, bool finished) {
int action; int action;
@ -1197,19 +1199,18 @@ void GUI::togglePausedState(QString hash) {
// Pause All Downloads in DL list // Pause All Downloads in DL list
void GUI::on_actionPause_All_triggered() { void GUI::on_actionPause_All_triggered() {
bool change = false; bool change = false;
QStringList DL_hashes = BTSession->getUnfinishedTorrents(); std::vector<torrent_handle> torrents = BTSession->getTorrents();
QStringList F_hashes = BTSession->getFinishedTorrents(); std::vector<torrent_handle>::iterator torrentIT;
QString hash; for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) {
foreach(hash, DL_hashes) { QTorrentHandle h = QTorrentHandle(*torrentIT);
if(BTSession->pauseTorrent(hash)){ if(!h.is_valid() || h.is_paused()) continue;
change = true; change = true;
downloadingTorrentTab->pauseTorrent(hash); if(h.is_seed()) {
} // Update in finished list
} finishedTorrentTab->pauseTorrent(h.hash());
foreach(hash, F_hashes) { } else {
if(BTSession->pauseTorrent(hash)){ // Update in download list
change = true; downloadingTorrentTab->pauseTorrent(h.hash());
finishedTorrentTab->pauseTorrent(hash);
} }
} }
if(change) { if(change) {
@ -1219,42 +1220,21 @@ void GUI::on_actionPause_All_triggered() {
} }
void GUI::on_actionIncreasePriority_triggered() { void GUI::on_actionIncreasePriority_triggered() {
bool inDownloadList = true; Q_ASSERT(tabs->currentIndex() == 0);
if(tabs->currentIndex() > 1) return; QStringList hashes = downloadingTorrentTab->getSelectedTorrents();
if(tabs->currentIndex() == 1)
inDownloadList = false;
QStringList hashes;
if(inDownloadList) {
hashes = downloadingTorrentTab->getSelectedTorrents();
} else {
hashes = finishedTorrentTab->getSelectedTorrents();
}
foreach(QString hash, hashes) { foreach(QString hash, hashes) {
if(inDownloadList) {
BTSession->increaseDlTorrentPriority(hash); BTSession->increaseDlTorrentPriority(hash);
downloadingTorrentTab->updateDlList();
}
} }
updateLists();
} }
void GUI::on_actionDecreasePriority_triggered() { void GUI::on_actionDecreasePriority_triggered() {
bool inDownloadList = true; Q_ASSERT(tabs->currentIndex() == 0);
if(tabs->currentIndex() > 1) return; QStringList hashes = downloadingTorrentTab->getSelectedTorrents();
if(tabs->currentIndex() == 1)
inDownloadList = false;
QStringList hashes;
if(inDownloadList) {
hashes = downloadingTorrentTab->getSelectedTorrents();
} else {
hashes = finishedTorrentTab->getSelectedTorrents();
}
QString hash;
foreach(QString hash, hashes) { foreach(QString hash, hashes) {
if(inDownloadList) {
BTSession->decreaseDlTorrentPriority(hash); BTSession->decreaseDlTorrentPriority(hash);
downloadingTorrentTab->updateDlList();
}
} }
updateLists();
} }
// pause selected items in the list // pause selected items in the list
@ -1293,19 +1273,18 @@ void GUI::pauseTorrent(QString hash) {
// Resume All Downloads in DL list // Resume All Downloads in DL list
void GUI::on_actionStart_All_triggered() { void GUI::on_actionStart_All_triggered() {
bool change = false; bool change = false;
QStringList DL_hashes = BTSession->getUnfinishedTorrents(); std::vector<torrent_handle> torrents = BTSession->getTorrents();
QStringList F_hashes = BTSession->getFinishedTorrents(); std::vector<torrent_handle>::iterator torrentIT;
QString hash; for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) {
foreach(hash, DL_hashes) { QTorrentHandle h = QTorrentHandle(*torrentIT);
if(BTSession->resumeTorrent(hash)){ if(!h.is_valid() || !h.is_paused()) continue;
change = true; change = true;
downloadingTorrentTab->resumeTorrent(hash); if(h.is_seed()) {
} // Update in finished list
} finishedTorrentTab->resumeTorrent(h.hash());
foreach(hash, F_hashes) { } else {
if(BTSession->resumeTorrent(hash)){ // Update in download list
change = true; downloadingTorrentTab->resumeTorrent(h.hash());
finishedTorrentTab->resumeTorrent(hash);
} }
} }
if(change) { if(change) {
@ -1363,15 +1342,25 @@ void GUI::updateLists() {
// update global informations // update global informations
dlSpeedLbl->setText(tr("DL: %1 KiB/s").arg(QString(QByteArray::number(BTSession->getPayloadDownloadRate()/1024., 'f', 1)))); dlSpeedLbl->setText(tr("DL: %1 KiB/s").arg(QString(QByteArray::number(BTSession->getPayloadDownloadRate()/1024., 'f', 1))));
upSpeedLbl->setText(tr("UP: %1 KiB/s").arg(QString(QByteArray::number(BTSession->getPayloadUploadRate()/1024., 'f', 1)))); upSpeedLbl->setText(tr("UP: %1 KiB/s").arg(QString(QByteArray::number(BTSession->getPayloadUploadRate()/1024., 'f', 1))));
switch(getCurrentTabIndex()){ std::vector<torrent_handle> torrents = BTSession->getTorrents();
case 0: std::vector<torrent_handle>::iterator torrentIT;
downloadingTorrentTab->updateDlList(); for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) {
break; QTorrentHandle h = QTorrentHandle(*torrentIT);
case 1: if(!h.is_valid()) continue;
finishedTorrentTab->updateFinishedList(); if(h.is_seed()) {
break; // Update in finished list
default: finishedTorrentTab->updateTorrent(h);
return; } else {
// Delete from finished list, if it moved back
if(QFile::exists(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+h.hash()+".finished")) {
if(h.state() != torrent_status::checking_files && h.state() != torrent_status::queued_for_checking) {
finishedTorrentTab->deleteTorrent(h.hash());
QFile::remove(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+h.hash()+".finished");
}
}
// Update in download list
downloadingTorrentTab->updateTorrent(h);
}
} }
if(displaySpeedInTitle) { if(displaySpeedInTitle) {
QString dl_rate = QByteArray::number(BTSession->getSessionStatus().payload_download_rate/1024, 'f', 1); QString dl_rate = QByteArray::number(BTSession->getSessionStatus().payload_download_rate/1024, 'f', 1);

4
src/GUI.h

@ -126,8 +126,6 @@ class GUI : public QMainWindow, private Ui::MainWindow{
void readSettings(); void readSettings();
void on_actionExit_triggered(); void on_actionExit_triggered();
void createTrayIcon(); void createTrayIcon();
void updateUnfinishedTorrentNumberCalc();
void updateFinishedTorrentNumberCalc();
void updateUnfinishedTorrentNumber(unsigned int nb); void updateUnfinishedTorrentNumber(unsigned int nb);
void updateFinishedTorrentNumber(unsigned int nb); void updateFinishedTorrentNumber(unsigned int nb);
void fullDiskError(QTorrentHandle& h) const; void fullDiskError(QTorrentHandle& h) const;
@ -160,6 +158,8 @@ class GUI : public QMainWindow, private Ui::MainWindow{
void downloadFromURLList(const QStringList& urls); void downloadFromURLList(const QStringList& urls);
void deleteTorrent(QString hash); void deleteTorrent(QString hash);
void finishedTorrent(QTorrentHandle& h) const; void finishedTorrent(QTorrentHandle& h) const;
void addedTorrent(QTorrentHandle& h) const;
void checkedTorrent(QTorrentHandle& h) const;
void updateLists(); void updateLists();
bool initWebUi(QString username, QString password, int port); bool initWebUi(QString username, QString password, int port);
void pauseTorrent(QString hash); void pauseTorrent(QString hash);

124
src/bittorrent.cpp

@ -124,13 +124,12 @@ void bittorrent::preAllocateAllFiles(bool b) {
void bittorrent::deleteBigRatios() { void bittorrent::deleteBigRatios() {
if(max_ratio == -1) return; if(max_ratio == -1) return;
QString hash; std::vector<torrent_handle> torrents = getTorrents();
foreach(hash, finishedTorrents) { std::vector<torrent_handle>::iterator torrentIT;
QTorrentHandle h = getTorrentHandle(hash); for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) {
if(!h.is_valid()) { QTorrentHandle h = QTorrentHandle(*torrentIT);
qDebug("/!\\ Error: Invalid handle"); if(!h.is_valid()) continue;
continue; if(h.is_seed()) {
}
QString hash = h.hash(); QString hash = h.hash();
if(getRealRatio(hash) > max_ratio) { if(getRealRatio(hash) > max_ratio) {
QString fileName = h.name(); QString fileName = h.name();
@ -140,6 +139,7 @@ void bittorrent::deleteBigRatios() {
} }
} }
} }
}
void bittorrent::setDownloadLimit(QString hash, long val) { void bittorrent::setDownloadLimit(QString hash, long val) {
QTorrentHandle h = getTorrentHandle(hash); QTorrentHandle h = getTorrentHandle(hash);
@ -222,6 +222,10 @@ qlonglong bittorrent::getETA(QString hash) const {
} }
} }
std::vector<torrent_handle> bittorrent::getTorrents() const {
return s->get_torrents();
}
// Return the torrent handle, given its hash // Return the torrent handle, given its hash
QTorrentHandle bittorrent::getTorrentHandle(QString hash) const{ QTorrentHandle bittorrent::getTorrentHandle(QString hash) const{
return QTorrentHandle(s->find_torrent(misc::fromString<sha1_hash>((hash.toStdString())))); return QTorrentHandle(s->find_torrent(misc::fromString<sha1_hash>((hash.toStdString()))));
@ -240,8 +244,12 @@ bool bittorrent::isPaused(QString hash) const{
unsigned int bittorrent::getFinishedPausedTorrentsNb() const { unsigned int bittorrent::getFinishedPausedTorrentsNb() const {
unsigned int nbPaused = 0; unsigned int nbPaused = 0;
foreach(QString hash, finishedTorrents) { std::vector<torrent_handle> torrents = getTorrents();
if(isPaused(hash)) { std::vector<torrent_handle>::iterator torrentIT;
for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) {
QTorrentHandle h = QTorrentHandle(*torrentIT);
if(!h.is_valid()) continue;
if(h.is_seed() && h.is_paused()) {
++nbPaused; ++nbPaused;
} }
} }
@ -250,8 +258,12 @@ unsigned int bittorrent::getFinishedPausedTorrentsNb() const {
unsigned int bittorrent::getUnfinishedPausedTorrentsNb() const { unsigned int bittorrent::getUnfinishedPausedTorrentsNb() const {
unsigned int nbPaused = 0; unsigned int nbPaused = 0;
foreach(QString hash, unfinishedTorrents) { std::vector<torrent_handle> torrents = getTorrents();
if(isPaused(hash)) { std::vector<torrent_handle>::iterator torrentIT;
for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) {
QTorrentHandle h = QTorrentHandle(*torrentIT);
if(!h.is_valid()) continue;
if(!h.is_seed() && h.is_paused()) {
++nbPaused; ++nbPaused;
} }
} }
@ -285,17 +297,6 @@ void bittorrent::deleteTorrent(QString hash, bool permanent) {
} }
// Remove tracker errors // Remove tracker errors
trackersErrors.remove(hash); trackersErrors.remove(hash);
int 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) if(permanent)
addConsoleMessage(tr("'%1' was removed permanently.", "'xxx.avi' was removed permanently.").arg(fileName)); addConsoleMessage(tr("'%1' was removed permanently.", "'xxx.avi' was removed permanently.").arg(fileName));
else else
@ -303,50 +304,8 @@ void bittorrent::deleteTorrent(QString hash, bool permanent) {
emit deletedTorrent(hash); emit deletedTorrent(hash);
} }
// 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 { bool bittorrent::isFinished(QString hash) const {
return finishedTorrents.contains(hash); return getTorrentHandle(hash).is_seed();
}
// Remove the given hash from the list of finished torrents
void bittorrent::setUnfinishedTorrent(QString hash) {
if(QFile::exists(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".finished")){
QFile::remove(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".finished");
}
int index = finishedTorrents.indexOf(hash);
if(index != -1) {
finishedTorrents.removeAt(index);
}
if(!unfinishedTorrents.contains(hash)) {
unfinishedTorrents << hash;
QTorrentHandle h = getTorrentHandle(hash);
}
//emit torrentSwitchedtoUnfinished(hash);
}
// Add the given hash to the list of finished torrents
void bittorrent::setFinishedTorrent(QString hash) {
if(!QFile::exists(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".finished")) {
QFile finished_file(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".finished");
finished_file.open(QIODevice::WriteOnly | QIODevice::Text);
finished_file.close();
}
if(!finishedTorrents.contains(hash)) {
finishedTorrents << hash;
}
int index = unfinishedTorrents.indexOf(hash);
if(index != -1) {
unfinishedTorrents.removeAt(index);
}
//emit torrentSwitchedtoFinished(hash);
} }
// Pause a running torrent // Pause a running torrent
@ -397,15 +356,27 @@ bool bittorrent::resumeTorrent(QString hash) {
} }
void bittorrent::pauseAllTorrents() { void bittorrent::pauseAllTorrents() {
QStringList list = getUnfinishedTorrents() + getFinishedTorrents(); std::vector<torrent_handle> torrents = getTorrents();
foreach(QString hash, list) std::vector<torrent_handle>::iterator torrentIT;
pauseTorrent(hash); for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) {
QTorrentHandle h = QTorrentHandle(*torrentIT);
if(!h.is_valid()) continue;
if(!h.is_paused()) {
h.pause();
}
}
} }
void bittorrent::resumeAllTorrents() { void bittorrent::resumeAllTorrents() {
QStringList list = getUnfinishedTorrents() + getFinishedTorrents(); std::vector<torrent_handle> torrents = getTorrents();
foreach(QString hash, list) std::vector<torrent_handle>::iterator torrentIT;
resumeTorrent(hash); for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) {
QTorrentHandle h = QTorrentHandle(*torrentIT);
if(!h.is_valid()) continue;
if(h.is_paused()) {
h.resume();
}
}
} }
void bittorrent::loadWebSeeds(QString hash) { void bittorrent::loadWebSeeds(QString hash) {
@ -583,11 +554,6 @@ void bittorrent::addTorrent(QString path, bool fromScanDir, QString from_url, bo
// Start torrent because it was added in paused state // Start torrent because it was added in paused state
h.resume(); h.resume();
} }
if(QFile::exists(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".finished")) {
finishedTorrents << hash;
}else{
unfinishedTorrents << hash;
}
// If download from url, remove temp file // If download from url, remove temp file
if(!from_url.isNull()) QFile::remove(file); if(!from_url.isNull()) QFile::remove(file);
// Delete from scan dir to avoid trying to download it again // Delete from scan dir to avoid trying to download it again
@ -1197,9 +1163,13 @@ void bittorrent::readAlerts() {
QTorrentHandle h(p->handle); QTorrentHandle h(p->handle);
if(h.is_valid()){ if(h.is_valid()){
QString hash = h.hash(); QString hash = h.hash();
// Create .paused file if necessary
QFile finished_file(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".finished");
finished_file.open(QIODevice::WriteOnly | QIODevice::Text);
finished_file.write(" ");
finished_file.close();
h.save_resume_data(); h.save_resume_data();
qDebug("Received finished alert for %s", h.name().toUtf8().data()); qDebug("Received finished alert for %s", h.name().toUtf8().data());
setFinishedTorrent(hash);
emit finishedTorrent(h); emit finishedTorrent(h);
} }
} }

9
src/bittorrent.h

@ -54,8 +54,6 @@ class bittorrent : public QObject {
QHash<QString, QHash<QString, QString> > trackersErrors; QHash<QString, QHash<QString, QString> > trackersErrors;
QStringList consoleMessages; QStringList consoleMessages;
QStringList peerBanMessages; QStringList peerBanMessages;
QStringList finishedTorrents;
QStringList unfinishedTorrents;
bool preAllocateAll; bool preAllocateAll;
bool addInPause; bool addInPause;
int maxConnecsPerTorrent; int maxConnecsPerTorrent;
@ -77,6 +75,7 @@ class bittorrent : public QObject {
bittorrent(); bittorrent();
~bittorrent(); ~bittorrent();
QTorrentHandle getTorrentHandle(QString hash) const; QTorrentHandle getTorrentHandle(QString hash) const;
std::vector<torrent_handle> getTorrents() const;
bool isPaused(QString hash) const; bool isPaused(QString hash) const;
bool isFilePreviewPossible(QString fileHash) const; bool isFilePreviewPossible(QString fileHash) const;
bool isDHTEnabled() const; bool isDHTEnabled() const;
@ -87,8 +86,6 @@ class bittorrent : public QObject {
float getRealRatio(QString hash) const; float getRealRatio(QString hash) const;
session* getSession() const; session* getSession() const;
QHash<QString, QString> getTrackersErrors(QString hash) const; QHash<QString, QString> getTrackersErrors(QString hash) const;
QStringList getFinishedTorrents() const;
QStringList getUnfinishedTorrents() const;
bool isFinished(QString hash) const; bool isFinished(QString hash) const;
bool has_filtered_files(QString hash) const; bool has_filtered_files(QString hash) const;
unsigned int getFinishedPausedTorrentsNb() const; unsigned int getFinishedPausedTorrentsNb() const;
@ -152,8 +149,6 @@ class bittorrent : public QObject {
void loadFilesPriorities(QTorrentHandle& h); void loadFilesPriorities(QTorrentHandle& h);
void setDownloadLimit(QString hash, long val); void setDownloadLimit(QString hash, long val);
void setUploadLimit(QString hash, long val); void setUploadLimit(QString hash, long val);
void setUnfinishedTorrent(QString hash);
void setFinishedTorrent(QString hash);
void enableUPnP(bool b); void enableUPnP(bool b);
void enableNATPMP(bool b); void enableNATPMP(bool b);
void enableLSD(bool b); void enableLSD(bool b);
@ -182,8 +177,6 @@ class bittorrent : public QObject {
void updateFileSize(QString hash); void updateFileSize(QString hash);
void downloadFromUrlFailure(QString url, QString reason); void downloadFromUrlFailure(QString url, QString reason);
void torrentFinishedChecking(QString hash); void torrentFinishedChecking(QString hash);
void updateFinishedTorrentNumber();
void updateUnfinishedTorrentNumber();
void forceUnfinishedListUpdate(); void forceUnfinishedListUpdate();
void forceFinishedListUpdate(); void forceFinishedListUpdate();
}; };

64
src/downloadingTorrents.cpp

@ -67,8 +67,6 @@ DownloadingTorrents::DownloadingTorrents(QObject *parent, bittorrent *BTSession)
downloadList->hideColumn(HASH); downloadList->hideColumn(HASH);
loadHiddenColumns(); loadHiddenColumns();
connect(BTSession, SIGNAL(addedTorrent(QTorrentHandle&)), this, SLOT(torrentAdded(QTorrentHandle&)));
connect(BTSession, SIGNAL(forceUnfinishedListUpdate()), this, SLOT(updateDlList()));
connect(BTSession, SIGNAL(torrentFinishedChecking(QString)), this, SLOT(sortProgressColumn(QString))); connect(BTSession, SIGNAL(torrentFinishedChecking(QString)), this, SLOT(sortProgressColumn(QString)));
// Load last columns width for download list // Load last columns width for download list
@ -486,16 +484,7 @@ QStringList DownloadingTorrents::getSelectedTorrents(bool only_one) const{
// get information from torrent handles and // get information from torrent handles and
// update download list accordingly // update download list accordingly
void DownloadingTorrents::updateDlList() { void DownloadingTorrents::updateTorrent(QTorrentHandle h) {
// browse handles
QStringList unfinishedTorrents = BTSession->getUnfinishedTorrents();
QString hash;
foreach(hash, unfinishedTorrents) {
QTorrentHandle h = BTSession->getTorrentHandle(hash);
if(!h.is_valid()){
qDebug("We have an invalid handle for: %s", qPrintable(hash));
continue;
}
try{ try{
QString hash = h.hash(); QString hash = h.hash();
int row = getRowFromHash(hash); int row = getRowFromHash(hash);
@ -508,7 +497,7 @@ void DownloadingTorrents::updateDlList() {
// Update Priority // Update Priority
if(BTSession->isQueueingEnabled()) { if(BTSession->isQueueingEnabled()) {
DLListModel->setData(DLListModel->index(row, PRIORITY), QVariant((int)BTSession->getDlTorrentPriority(hash))); DLListModel->setData(DLListModel->index(row, PRIORITY), QVariant((int)BTSession->getDlTorrentPriority(hash)));
if(BTSession->isTorrentQueued(hash)) { if(h.is_queued()) {
if(h.state() == torrent_status::checking_files || h.state() == torrent_status::queued_for_checking) { if(h.state() == torrent_status::checking_files || h.state() == torrent_status::queued_for_checking) {
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/time.png"))), Qt::DecorationRole); DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/time.png"))), Qt::DecorationRole);
if(!downloadList->isColumnHidden(PROGRESS)) { if(!downloadList->isColumnHidden(PROGRESS)) {
@ -525,20 +514,14 @@ void DownloadingTorrents::updateDlList() {
DLListModel->setData(DLListModel->index(row, UPSPEED), QVariant((double)0.)); DLListModel->setData(DLListModel->index(row, UPSPEED), QVariant((double)0.));
DLListModel->setData(DLListModel->index(row, SEEDSLEECH), QVariant("0/0")); DLListModel->setData(DLListModel->index(row, SEEDSLEECH), QVariant("0/0"));
setRowColor(row, QString::fromUtf8("grey")); setRowColor(row, QString::fromUtf8("grey"));
return;
} }
} }
// No need to update a paused torrent // No need to update a paused torrent
if(h.is_paused() || h.is_queued()) continue; if(h.is_paused()) return;
// Parse download state // Parse download state
// Setting download state // Setting download state
switch(h.state()) { switch(h.state()) {
case torrent_status::finished:
case torrent_status::seeding:
qDebug("A torrent that was in download tab just finished, moving it to finished tab");
BTSession->setUnfinishedTorrent(hash);
emit torrentFinished(hash);
deleteTorrent(hash);
continue;
case torrent_status::checking_files: case torrent_status::checking_files:
case torrent_status::queued_for_checking: case torrent_status::queued_for_checking:
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/time.png"))), Qt::DecorationRole); DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/time.png"))), Qt::DecorationRole);
@ -583,16 +566,10 @@ void DownloadingTorrents::updateDlList() {
if(!downloadList->isColumnHidden(RATIO)) { if(!downloadList->isColumnHidden(RATIO)) {
DLListModel->setData(DLListModel->index(row, RATIO), QVariant(misc::toQString(BTSession->getRealRatio(hash)))); DLListModel->setData(DLListModel->index(row, RATIO), QVariant(misc::toQString(BTSession->getRealRatio(hash))));
} }
}catch(invalid_handle e) { }catch(invalid_handle e) {}
continue;
}
}
} }
void DownloadingTorrents::addTorrent(QString hash) { void DownloadingTorrents::addTorrent(QString hash) {
if(BTSession->isFinished(hash)){
BTSession->setUnfinishedTorrent(hash);
}
QTorrentHandle h = BTSession->getTorrentHandle(hash); QTorrentHandle h = BTSession->getTorrentHandle(hash);
int row = getRowFromHash(hash); int row = getRowFromHash(hash);
qDebug("DL: addTorrent(): %s, row: %d", (const char*)hash.toUtf8(), row); qDebug("DL: addTorrent(): %s, row: %d", (const char*)hash.toUtf8(), row);
@ -797,37 +774,6 @@ void DownloadingTorrents::loadLastSortedColumn() {
} }
} }
// Called when a torrent is added
void DownloadingTorrents::torrentAdded(QTorrentHandle& h) {
QString hash = h.hash();
if(BTSession->isFinished(hash)) {
return;
}
if(getRowFromHash(hash) != -1) return;
int row = DLListModel->rowCount();
// Adding torrent to download list
DLListModel->insertRow(row);
DLListModel->setData(DLListModel->index(row, NAME), QVariant(h.name()));
DLListModel->setData(DLListModel->index(row, SIZE), QVariant((qlonglong)h.actual_size()));
DLListModel->setData(DLListModel->index(row, DLSPEED), QVariant((double)0.));
DLListModel->setData(DLListModel->index(row, UPSPEED), QVariant((double)0.));
DLListModel->setData(DLListModel->index(row, SEEDSLEECH), QVariant(QString::fromUtf8("0/0")));
DLListModel->setData(DLListModel->index(row, RATIO), QVariant(misc::toQString(BTSession->getRealRatio(hash))));
DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)-1));
DLListModel->setData(DLListModel->index(row, HASH), QVariant(hash));
// Pause torrent if it was paused last time
if(h.is_paused()) {
DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)BTSession->getUncheckedTorrentProgress(hash)));
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/paused.png"))), Qt::DecorationRole);
setRowColor(row, QString::fromUtf8("red"));
}else{
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/stalled.png"))), Qt::DecorationRole);
setRowColor(row, QString::fromUtf8("grey"));
}
++nbTorrents;
emit unfinishedTorrentsNumberChanged(nbTorrents);
}
void DownloadingTorrents::updateFileSizeAndProgress(QString hash) { void DownloadingTorrents::updateFileSizeAndProgress(QString hash) {
int row = getRowFromHash(hash); int row = getRowFromHash(hash);
Q_ASSERT(row != -1); Q_ASSERT(row != -1);

6
src/downloadingTorrents.h

@ -58,7 +58,6 @@ class DownloadingTorrents : public QWidget, public Ui::downloading{
signals: signals:
void unfinishedTorrentsNumberChanged(unsigned int); void unfinishedTorrentsNumberChanged(unsigned int);
void torrentDoubleClicked(QString hash, bool finished); void torrentDoubleClicked(QString hash, bool finished);
void torrentFinished(QString hash);
protected slots: protected slots:
void on_actionSet_download_limit_triggered(); void on_actionSet_download_limit_triggered();
@ -66,13 +65,11 @@ class DownloadingTorrents : public QWidget, public Ui::downloading{
void on_actionSet_upload_limit_triggered(); void on_actionSet_upload_limit_triggered();
void displayDLListMenu(const QPoint& pos); void displayDLListMenu(const QPoint& pos);
void displayDLHoSMenu(const QPoint&); void displayDLHoSMenu(const QPoint&);
void addTorrent(QString hash);
void sortDownloadList(int index=-1, Qt::SortOrder startSortOrder=Qt::AscendingOrder); void sortDownloadList(int index=-1, Qt::SortOrder startSortOrder=Qt::AscendingOrder);
void toggleDownloadListSortOrder(int index); void toggleDownloadListSortOrder(int index);
void sortDownloadListFloat(int index, Qt::SortOrder sortOrder); void sortDownloadListFloat(int index, Qt::SortOrder sortOrder);
void sortDownloadListString(int index, Qt::SortOrder sortOrder); void sortDownloadListString(int index, Qt::SortOrder sortOrder);
void saveColWidthDLList() const; void saveColWidthDLList() const;
void torrentAdded(QTorrentHandle& h);
void setRowColor(int row, QColor color); void setRowColor(int row, QColor color);
void showProperties(const QModelIndex &index); void showProperties(const QModelIndex &index);
void hideOrShowColumnName(); void hideOrShowColumnName();
@ -87,7 +84,7 @@ class DownloadingTorrents : public QWidget, public Ui::downloading{
void forceRecheck(); void forceRecheck();
public slots: public slots:
void updateDlList(); void updateTorrent(QTorrentHandle h);
void pauseTorrent(QString hash); void pauseTorrent(QString hash);
void resumeTorrent(QString hash); void resumeTorrent(QString hash);
void deleteTorrent(QString hash); void deleteTorrent(QString hash);
@ -97,6 +94,7 @@ class DownloadingTorrents : public QWidget, public Ui::downloading{
void hidePriorityColumn(bool hide); void hidePriorityColumn(bool hide);
void sortProgressColumn(QString hash); void sortProgressColumn(QString hash);
void loadLastSortedColumn(); void loadLastSortedColumn();
void addTorrent(QString hash);
}; };

33
src/httpserver.cpp

@ -32,15 +32,12 @@ HttpServer::HttpServer(bittorrent *_BTSession, int msec, QObject* parent) : QTcp
BTSession = _BTSession; BTSession = _BTSession;
manager = new EventManager(this, BTSession); manager = new EventManager(this, BTSession);
//add torrents //add torrents
QStringList list = BTSession->getUnfinishedTorrents(); std::vector<torrent_handle> torrents = BTSession->getTorrents();
foreach(QString hash, list) { std::vector<torrent_handle>::iterator torrentIT;
QTorrentHandle h = BTSession->getTorrentHandle(hash); for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) {
if(h.is_valid()) manager->addedTorrent(h); QTorrentHandle h = QTorrentHandle(*torrentIT);
} if(h.is_valid())
list = BTSession->getFinishedTorrents(); manager->addedTorrent(h);
foreach(QString hash, list) {
QTorrentHandle h = BTSession->getTorrentHandle(hash);
if(h.is_valid()) manager->addedTorrent(h);
} }
//connect BTSession to manager //connect BTSession to manager
connect(BTSession, SIGNAL(addedTorrent(QTorrentHandle&)), manager, SLOT(addedTorrent(QTorrentHandle&))); connect(BTSession, SIGNAL(addedTorrent(QTorrentHandle&)), manager, SLOT(addedTorrent(QTorrentHandle&)));
@ -74,17 +71,13 @@ void HttpServer::newHttpConnection()
} }
} }
void HttpServer::onTimer() void HttpServer::onTimer() {
{ std::vector<torrent_handle> torrents = BTSession->getTorrents();
QStringList list = BTSession->getUnfinishedTorrents(); std::vector<torrent_handle>::iterator torrentIT;
foreach(QString hash, list) { for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) {
QTorrentHandle h = BTSession->getTorrentHandle(hash); QTorrentHandle h = QTorrentHandle(*torrentIT);
if(h.is_valid()) manager->modifiedTorrent(h); if(h.is_valid())
} manager->modifiedTorrent(h);
list = BTSession->getFinishedTorrents();
foreach(QString hash, list) {
QTorrentHandle h = BTSession->getTorrentHandle(hash);
if(h.is_valid()) manager->modifiedTorrent(h);
} }
} }

Loading…
Cancel
Save