Merge pull request #5141 from glassez/recheck

Fix torrent adding with existing data
This commit is contained in:
sledgehammer999
2016-04-24 12:41:50 -05:00
11 changed files with 126 additions and 574 deletions

View File

@@ -28,63 +28,63 @@
* exception statement from your version.
*/
#include "session.h"
#include <QCoreApplication>
#include <QDateTime>
#include <QDebug>
#include <QDir>
#include <QDateTime>
#include <QString>
#include <QStringList>
#include <QNetworkInterface>
#include <QDirIterator>
#include <QHostAddress>
#include <QNetworkAddressEntry>
#include <QTimer>
#include <QNetworkInterface>
#include <QProcess>
#include <QCoreApplication>
#include <QThread>
#include <QRegExp>
#include <QString>
#include <QStringList>
#include <QThread>
#include <QTimer>
#include <queue>
#include <vector>
#include <boost/bind.hpp>
#include <libtorrent/session.hpp>
#include <libtorrent/lazy_entry.hpp>
#include <libtorrent/alert_types.hpp>
#include <libtorrent/bencode.hpp>
#include <libtorrent/error_code.hpp>
#include <libtorrent/identify_client.hpp>
#include <libtorrent/alert_types.hpp>
#include <libtorrent/torrent_info.hpp>
#include <libtorrent/ip_filter.hpp>
#include <libtorrent/magnet_uri.hpp>
#include <libtorrent/extensions/ut_metadata.hpp>
#include <libtorrent/extensions/lt_trackers.hpp>
#include <libtorrent/extensions/ut_pex.hpp>
#include <libtorrent/extensions/smart_ban.hpp>
//#include <libtorrent/extensions/metadata_transfer.hpp>
#include <libtorrent/identify_client.hpp>
#include <libtorrent/ip_filter.hpp>
#include <libtorrent/lazy_entry.hpp>
#include <libtorrent/magnet_uri.hpp>
#include <libtorrent/session.hpp>
#include <libtorrent/torrent_info.hpp>
#include "base/logger.h"
#include "base/net/downloadhandler.h"
#include "base/net/downloadmanager.h"
#include "base/net/portforwarder.h"
#include "base/preferences.h"
#include "base/settingsstorage.h"
#include "base/torrentfilter.h"
#include "base/unicodestrings.h"
#include "base/utils/misc.h"
#include "base/utils/fs.h"
#include "base/utils/string.h"
#include "base/unicodestrings.h"
#include "base/logger.h"
#include "base/settingsstorage.h"
#include "base/preferences.h"
#include "base/torrentfilter.h"
#include "base/net/downloadmanager.h"
#include "base/net/downloadhandler.h"
#include "base/net/portforwarder.h"
#include "base/utils/string.h"
#include "cachestatus.h"
#include "magneturi.h"
#include "private/filterparserthread.h"
#include "private/statistics.h"
#include "private/bandwidthscheduler.h"
#include "private/resumedatasavingmanager.h"
#include "trackerentry.h"
#include "tracker.h"
#include "magneturi.h"
#include "cachestatus.h"
#include "sessionstatus.h"
#include "torrenthandle.h"
#include "session.h"
#include "tracker.h"
#include "trackerentry.h"
static const char PEER_ID[] = "qB";
static const char RESUME_FOLDER[] = "BT_backup";
@@ -155,6 +155,16 @@ namespace
return expanded;
}
QStringList findAllFiles(const QString &dirPath)
{
QStringList files;
QDirIterator it(dirPath, QDir::Files, QDirIterator::Subdirectories);
while (it.hasNext())
files << it.next();
return files;
}
}
// Session
@@ -1225,7 +1235,7 @@ bool Session::addTorrent(const TorrentInfo &torrentInfo, const AddTorrentParams
// Add a torrent to the BitTorrent session
bool Session::addTorrent_impl(AddTorrentData addData, const MagnetUri &magnetUri,
const TorrentInfo &torrentInfo, const QByteArray &fastresumeData)
TorrentInfo torrentInfo, const QByteArray &fastresumeData)
{
addData.savePath = normalizeSavePath(
addData.savePath,
@@ -1243,6 +1253,12 @@ bool Session::addTorrent_impl(AddTorrentData addData, const MagnetUri &magnetUri
std::vector<char> buf(fastresumeData.constData(), fastresumeData.constData() + fastresumeData.size());
std::vector<boost::uint8_t> filePriorities;
QString savePath;
if (addData.savePath.isEmpty()) // using Advanced mode
savePath = categorySavePath(addData.category);
else // using Simple mode
savePath = addData.savePath;
bool fromMagnetUri = magnetUri.isValid();
if (fromMagnetUri) {
hash = magnetUri.hash();
@@ -1271,6 +1287,8 @@ bool Session::addTorrent_impl(AddTorrentData addData, const MagnetUri &magnetUri
}
else if (torrentInfo.isValid()) {
// Metadata
if (!addData.resumed && !addData.hasSeedStatus)
findIncompleteFiles(torrentInfo, savePath);
p.ti = torrentInfo.nativeInfo();
hash = torrentInfo.hash();
}
@@ -1329,16 +1347,6 @@ bool Session::addTorrent_impl(AddTorrentData addData, const MagnetUri &magnetUri
Preferences *const pref = Preferences::instance();
p.max_connections = pref->getMaxConnecsPerTorrent();
p.max_uploads = pref->getMaxUploadsPerTorrent();
QString savePath;
// Set actual save path (e.g. temporary folder)
if (isTempPathEnabled() && !addData.disableTempPath && !addData.hasSeedStatus)
savePath = m_tempPath;
else if (addData.savePath.isEmpty()) // using Advanced mode
savePath = categorySavePath(addData.category);
else // using Simple mode
savePath = addData.savePath;
p.save_path = Utils::String::toStdString(Utils::Fs::toNativePath(savePath));
// Check if save path exists, creating it otherwise
if (!QDir(savePath).exists())
@@ -1350,6 +1358,53 @@ bool Session::addTorrent_impl(AddTorrentData addData, const MagnetUri &magnetUri
return true;
}
bool Session::findIncompleteFiles(TorrentInfo &torrentInfo, QString &savePath) const
{
auto findInDir = [](const QString &dirPath, TorrentInfo &torrentInfo) -> bool
{
bool found = false;
if (torrentInfo.filesCount() == 1) {
const QString filePath = dirPath + torrentInfo.filePath(0);
if (QFile(filePath).exists()) {
found = true;
}
else if (QFile(filePath + QB_EXT).exists()) {
found = true;
torrentInfo.renameFile(0, torrentInfo.filePath(0) + QB_EXT);
}
}
else {
QSet<QString> allFiles;
int dirPathSize = dirPath.size();
foreach (const QString &file, findAllFiles(dirPath + torrentInfo.name()))
allFiles << file.mid(dirPathSize);
for (int i = 0; i < torrentInfo.filesCount(); ++i) {
QString filePath = torrentInfo.filePath(i);
if (allFiles.contains(filePath)) {
found = true;
}
else {
filePath += QB_EXT;
if (allFiles.contains(filePath)) {
found = true;
torrentInfo.renameFile(i, filePath);
}
}
}
}
return found;
};
bool found = findInDir(savePath, torrentInfo);
if (!found && isTempPathEnabled()) {
savePath = m_tempPath;
found = findInDir(savePath, torrentInfo);
}
return found;
}
// Add a torrent to the BitTorrent session in hidden mode
// and force it to load its metadata
bool Session::loadMetadata(const MagnetUri &magnetUri)

View File

@@ -356,8 +356,9 @@ namespace BitTorrent
void startUpTorrents();
bool addTorrent_impl(AddTorrentData addData, const MagnetUri &magnetUri,
const TorrentInfo &torrentInfo = TorrentInfo(),
TorrentInfo torrentInfo = TorrentInfo(),
const QByteArray &fastresumeData = QByteArray());
bool findIncompleteFiles(TorrentInfo &torrentInfo, QString &savePath) const;
void updateRatioTimer();
void exportTorrentFile(TorrentHandle *const torrent, TorrentExportFolder folder = TorrentExportFolder::Regular);

View File

@@ -60,7 +60,7 @@
#include "trackerentry.h"
#include "torrenthandle.h"
static const char QB_EXT[] = ".!qB";
const QString QB_EXT {".!qB"};
namespace libt = libtorrent;
using namespace BitTorrent;
@@ -215,15 +215,9 @@ TorrentHandle::TorrentHandle(Session *session, const libtorrent::torrent_handle
updateStatus();
m_hash = InfoHash(m_nativeStatus.info_hash);
adjustActualSavePath();
if (!data.resumed) {
if (!data.resumed)
setSequentialDownload(data.sequential);
if (hasMetadata()) {
if (m_session->isAppendExtensionEnabled())
appendExtensionsToIncompleteFiles();
}
}
}
TorrentHandle::~TorrentHandle() {}
@@ -1475,6 +1469,7 @@ void TorrentHandle::handleTorrentCheckedAlert(libtorrent::torrent_checked_alert
m_hasSeedStatus = true;
adjustActualSavePath();
appendExtensionsToIncompleteFiles();
if (m_pauseAfterRecheck) {
m_pauseAfterRecheck = false;
@@ -1496,13 +1491,19 @@ void TorrentHandle::handleTorrentFinishedAlert(libtorrent::torrent_finished_aler
m_hasSeedStatus = true;
adjustActualSavePath();
if (Preferences::instance()->recheckTorrentsOnCompletion())
forceRecheck();
appendExtensionsToIncompleteFiles();
if (isMoveInProgress() || m_renameCount > 0)
const bool recheckTorrentsOnCompletion = Preferences::instance()->recheckTorrentsOnCompletion();
if (isMoveInProgress() || m_renameCount > 0) {
if (recheckTorrentsOnCompletion)
m_moveFinishedTriggers.append(boost::bind(&TorrentHandle::forceRecheck, this));
m_moveFinishedTriggers.append(boost::bind(&Session::handleTorrentFinished, m_session, this));
else
}
else {
if (recheckTorrentsOnCompletion)
forceRecheck();
m_session->handleTorrentFinished(this);
}
}
void TorrentHandle::handleTorrentPausedAlert(libtorrent::torrent_paused_alert *p)
@@ -1616,7 +1617,7 @@ void TorrentHandle::handleFileCompletedAlert(libtorrent::file_completed_alert *p
QString name = filePath(p->index);
if (name.endsWith(QB_EXT)) {
const QString oldName = name;
name.chop(QString(QB_EXT).size());
name.chop(QB_EXT.size());
qDebug("Renaming %s to %s", qPrintable(oldName), qPrintable(name));
renameFile(p->index, name);
}
@@ -1727,14 +1728,22 @@ void TorrentHandle::appendExtensionsToIncompleteFiles()
{
QVector<qreal> fp = filesProgress();
for (int i = 0; i < filesCount(); ++i) {
QString name = filePath(i);
if ((fileSize(i) > 0) && (fp[i] < 1)) {
const QString name = filePath(i);
if (!name.endsWith(QB_EXT)) {
const QString newName = name + QB_EXT;
qDebug("Renaming %s to %s", qPrintable(name), qPrintable(newName));
qDebug() << "Renaming" << name << "to" << newName;
renameFile(i, newName);
}
}
else {
if (name.endsWith(QB_EXT)) {
const QString oldName = name;
name.chop(QB_EXT.size());
qDebug() << "Renaming" << oldName << "to" << name;
renameFile(i, name);
}
}
}
}
@@ -1744,7 +1753,7 @@ void TorrentHandle::removeExtensionsFromIncompleteFiles()
QString name = filePath(i);
if (name.endsWith(QB_EXT)) {
const QString oldName = name;
name.chop(QString(QB_EXT).size());
name.chop(QB_EXT.size());
qDebug("Renaming %s to %s", qPrintable(oldName), qPrintable(name));
renameFile(i, name);
}
@@ -1770,7 +1779,7 @@ void TorrentHandle::adjustActualSavePath_impl()
else {
// Moving all downloading torrents to temporary save path
path = m_session->tempPath();
qDebug("Moving torrent to its temp save path: %s", qPrintable(path));
qDebug() << "Moving torrent to its temp save path:" << path;
}
moveStorage(Utils::Fs::toNativePath(path));

View File

@@ -54,6 +54,8 @@ class QBitArray;
class QStringList;
template<typename T, typename U> struct QPair;
extern const QString QB_EXT;
namespace libtorrent
{
class alert;