From 806ab07865fb82a81571b7097ebdc525cf75583f Mon Sep 17 00:00:00 2001 From: Christophe Dumez Date: Sun, 23 Sep 2012 11:09:01 +0300 Subject: [PATCH] Import new trackers from magnet link in case of duplicate torrent (closes #111) --- src/misc.cpp | 20 ++++++++++++++++++-- src/misc.h | 6 ++++-- src/qtlibtorrent/qbtsession.cpp | 28 ++++++++++++++++++++++++++++ src/qtlibtorrent/qbtsession.h | 3 ++- 4 files changed, 52 insertions(+), 5 deletions(-) diff --git a/src/misc.cpp b/src/misc.cpp index 6173543ae..379239706 100644 --- a/src/misc.cpp +++ b/src/misc.cpp @@ -309,7 +309,7 @@ QString misc::bcLinkToMagnet(QString bc_link) { return magnet; } -QString misc::magnetUriToName(QString magnet_uri) { +QString misc::magnetUriToName(const QString& magnet_uri) { QString name = ""; QRegExp regHex("dn=([^&]+)"); const int pos = regHex.indexIn(magnet_uri); @@ -321,7 +321,23 @@ QString misc::magnetUriToName(QString magnet_uri) { return name; } -QString misc::magnetUriToHash(QString magnet_uri) { +QList misc::magnetUriToTrackers(const QString& magnet_uri) +{ + QList trackers; + QRegExp rx("tr=([^&]+)"); + int pos = 0; + + while ((pos = rx.indexIn(magnet_uri, pos)) != -1) { + const QUrl tracker = QUrl::fromEncoded(rx.cap(1).toUtf8()); + qDebug() << Q_FUNC_INFO << "Found tracker: " << tracker.toString(); + trackers << tracker; + pos += rx.matchedLength(); + } + + return trackers; +} + +QString misc::magnetUriToHash(const QString& magnet_uri) { QString hash = ""; QRegExp regHex("urn:btih:([0-9A-Za-z]+)"); // Hex diff --git a/src/misc.h b/src/misc.h index 098b1bebb..18725333f 100644 --- a/src/misc.h +++ b/src/misc.h @@ -42,6 +42,7 @@ #include #include #include +#include #include #ifndef DISABLE_GUI #include @@ -99,8 +100,9 @@ public: // value must be given in bytes static QString friendlyUnit(qreal val, bool is_speed = false); static bool isPreviewable(QString extension); - static QString magnetUriToName(QString magnet_uri); - static QString magnetUriToHash(QString magnet_uri); + static QString magnetUriToName(const QString& magnet_uri); + static QString magnetUriToHash(const QString& magnet_uri); + static QList magnetUriToTrackers(const QString& magnet_uri); static QString bcLinkToMagnet(QString bc_link); // Take a number of seconds and return an user-friendly // time duration like "1d 2h 10m". diff --git a/src/qtlibtorrent/qbtsession.cpp b/src/qtlibtorrent/qbtsession.cpp index fedf9c533..1fc79ce85 100755 --- a/src/qtlibtorrent/qbtsession.cpp +++ b/src/qtlibtorrent/qbtsession.cpp @@ -921,6 +921,11 @@ QTorrentHandle QBtSession::addMagnetUri(QString magnet_uri, bool resumed, bool f if (s->find_torrent(QStringToSha1(hash)).is_valid()) { qDebug("/!\\ Torrent is already in download list"); addConsoleMessage(tr("'%1' is already in download list.", "e.g: 'xxx.avi' is already in download list.").arg(magnet_uri)); + // Check if the torrent contains trackers or url seeds we don't know about + // and add them + QTorrentHandle h_ex = getTorrentHandle(hash); + mergeTorrents(h_ex, magnet_uri); + return h; } @@ -1301,6 +1306,29 @@ void QBtSession::loadTorrentTempData(QTorrentHandle &h, QString savePath, bool m TorrentPersistentData::saveTorrentPersistentData(h, savePath, magnet); } +void QBtSession::mergeTorrents(QTorrentHandle& h_ex, const QString& magnet_uri) +{ + QList new_trackers = misc::magnetUriToTrackers(magnet_uri); + bool trackers_added = false; + foreach (const QUrl& new_tracker, new_trackers) { + bool found = false; + std::vector existing_trackers = h_ex.trackers(); + foreach (const announce_entry& existing_tracker, existing_trackers) { + if (new_tracker == QUrl(existing_tracker.url.c_str())) { + found = true; + break; + } + } + + if (!found) { + h_ex.add_tracker(announce_entry(new_tracker.toString().toStdString())); + trackers_added = true; + } + } + if (trackers_added) + addConsoleMessage(tr("Note: new trackers were added to the existing torrent.")); +} + void QBtSession::mergeTorrents(QTorrentHandle &h_ex, boost::intrusive_ptr t) { // Check if the torrent contains trackers or url seeds we don't know about // and add them diff --git a/src/qtlibtorrent/qbtsession.h b/src/qtlibtorrent/qbtsession.h index 35b5aaf99..67aac09da 100755 --- a/src/qtlibtorrent/qbtsession.h +++ b/src/qtlibtorrent/qbtsession.h @@ -191,7 +191,8 @@ private slots: void sendNotificationEmail(const QTorrentHandle &h); void autoRunExternalProgram(const QTorrentHandle &h, bool async=true); void cleanUpAutoRunProcess(int); - void mergeTorrents(QTorrentHandle &h_ex, boost::intrusive_ptr t); + void mergeTorrents(QTorrentHandle& h_ex, boost::intrusive_ptr t); + void mergeTorrents(QTorrentHandle& h_ex, const QString& magnet_uri); void exportTorrentFile(const QTorrentHandle &h, TorrentExportFolder folder = RegularTorrentExportFolder); void initWebUi(); void handleIPFilterParsed(int ruleCount);