Manually backport from master, commit 6dabf50 and its fixes. Original author Ivan Sorokin.

This commit is contained in:
sledgehammer999 2014-07-06 22:20:12 +03:00
parent 077006d4d6
commit e09d75f68e
3 changed files with 160 additions and 43 deletions

View file

@ -83,6 +83,7 @@
//initialize static member variables
QHash<QString, TorrentTempData::TorrentData> TorrentTempData::data = QHash<QString, TorrentTempData::TorrentData>();
QHash<QString, TorrentTempData::TorrentMoveState> TorrentTempData::torrentMoveStates = QHash<QString, TorrentTempData::TorrentMoveState>();
QHash<QString, bool> HiddenData::data = QHash<QString, bool>();
unsigned int HiddenData::metadata_counter = 0;
@ -2415,22 +2416,74 @@ void QBtSession::readAlerts() {
}
else if (storage_moved_alert* p = dynamic_cast<storage_moved_alert*>(a.get())) {
QTorrentHandle h(p->handle);
if (h.is_valid()) {
// Attempt to remove old folder if empty
const QString old_save_path = TorrentPersistentData::getPreviousPath(h.hash());
const QString new_save_path = misc::toQStringU(p->path.c_str());
qDebug("Torrent moved from %s to %s", qPrintable(old_save_path), qPrintable(new_save_path));
QDir old_save_dir(old_save_path);
if (old_save_dir != QDir(defaultSavePath) && old_save_dir != QDir(defaultTempPath)) {
qDebug("Attempting to remove %s", qPrintable(old_save_path));
QDir().rmpath(old_save_path);
}
if (defaultTempPath.isEmpty() || !new_save_path.startsWith(defaultTempPath)) {
qDebug("Storage has been moved, updating save path to %s", qPrintable(new_save_path));
TorrentPersistentData::saveSavePath(h.hash(), new_save_path);
}
emit savePathChanged(h);
//h.force_recheck();
if (!h.is_valid()) {
qWarning("invalid handle received in storage_moved_alert");
break;
}
QString hash = h.hash();
if (!TorrentTempData::isMoveInProgress(hash)) {
qWarning("unexpected storage_moved_alert received");
break;
}
QString new_save_path = misc::toQStringU(p->path.c_str());
if (new_save_path != TorrentTempData::getNewPath(hash)) {
qWarning("new path received in handleStorageMovedAlert() doesn't match a path in a queue");
break;
}
QString oldPath = TorrentTempData::getOldPath(hash);
qDebug("Torrent is successfully moved from %s to %s", qPrintable(oldPath), qPrintable(new_save_path));
// Attempt to remove old folder if empty
QDir old_save_dir(oldPath);
if (old_save_dir != QDir(defaultSavePath) && old_save_dir != QDir(defaultTempPath)) {
qDebug("Attempting to remove %s", qPrintable(oldPath));
QDir().rmpath(oldPath);
}
if (defaultTempPath.isEmpty() || !new_save_path.startsWith(defaultTempPath)) {
qDebug("Storage has been moved, updating save path to %s", qPrintable(new_save_path));
TorrentPersistentData::saveSavePath(h.hash(), new_save_path);
}
emit savePathChanged(h);
//h.force_recheck();
QString queued = TorrentTempData::getQueuedPath(hash);
if (!queued.isEmpty()) {
TorrentTempData::finishMove(hash);
h.move_storage(queued);
}
else {
TorrentTempData::finishMove(hash);
}
}
else if (storage_moved_failed_alert* p = dynamic_cast<storage_moved_failed_alert*>(a.get())) {
QTorrentHandle h(p->handle);
if (!h.is_valid()) {
qWarning("invalid handle received in storage_moved_failed_alert");
break;
}
QString hash = h.hash();
if (!TorrentTempData::isMoveInProgress(hash)) {
qWarning("unexpected storage_moved_alert received");
break;
}
addConsoleMessage(tr("Could not move torrent: '%1'. Reason: %2").arg(h.name()).arg(misc::toQStringU(p->message())), "red");
QString queued = TorrentTempData::getQueuedPath(hash);
if (!queued.isEmpty()) {
TorrentTempData::finishMove(hash);
addConsoleMessage(tr("Attempting to move torrent: '%1' to path: '%2'.").arg(h.name()).arg(queued));
h.move_storage(queued);
}
else {
TorrentTempData::finishMove(hash);
}
}
else if (metadata_received_alert* p = dynamic_cast<metadata_received_alert*>(a.get())) {
@ -2988,7 +3041,6 @@ void QBtSession::recoverPersistentData(const QString &hash, const std::vector<ch
QString savePath = QString::fromUtf8(fast.dict_find_string_value("qBt-savePath").c_str());
qreal ratioLimit = QString::fromUtf8(fast.dict_find_string_value("qBt-ratioLimit").c_str()).toDouble();
QDateTime addedDate = QDateTime::fromTime_t(fast.dict_find_int_value("added_time"));
QString previousSavePath = QString::fromUtf8(fast.dict_find_string_value("qBt-previousSavePath").c_str());
QDateTime seedDate = QDateTime::fromTime_t(fast.dict_find_int_value("qBt-seedDate"));
QString label = QString::fromUtf8(fast.dict_find_string_value("qBt-label").c_str());
int priority = fast.dict_find_int_value("qBt-queuePosition");
@ -2997,7 +3049,6 @@ void QBtSession::recoverPersistentData(const QString &hash, const std::vector<ch
TorrentPersistentData::saveSavePath(hash, savePath);
TorrentPersistentData::setRatioLimit(hash, ratioLimit);
TorrentPersistentData::setAddedDate(hash, addedDate);
TorrentPersistentData::setPreviousSavePath(hash, previousSavePath);
TorrentPersistentData::saveSeedDate(hash, seedDate);
TorrentPersistentData::saveLabel(hash, label);
TorrentPersistentData::savePriority(hash, priority);
@ -3007,7 +3058,6 @@ void QBtSession::recoverPersistentData(const QString &hash, const std::vector<ch
void QBtSession::backupPersistentData(const QString &hash, boost::shared_ptr<libtorrent::entry> data) {
(*data)["qBt-savePath"] = TorrentPersistentData::getSavePath(hash).toUtf8().constData();
(*data)["qBt-ratioLimit"] = QString::number(TorrentPersistentData::getRatioLimit(hash)).toUtf8().constData();
(*data)["qBt-previousSavePath"] = TorrentPersistentData::getPreviousPath(hash).toUtf8().constData();
(*data)["qBt-seedDate"] = TorrentPersistentData::getSeedDate(hash).toTime_t();
(*data)["qBt-label"] = TorrentPersistentData::getLabel(hash).toUtf8().constData();
(*data)["qBt-queuePosition"] = TorrentPersistentData::getPriority(hash);

View file

@ -679,15 +679,26 @@ void QTorrentHandle::set_tracker_login(const QString& username, const QString& p
}
void QTorrentHandle::move_storage(const QString& new_path) const {
if (QDir(save_path()) == QDir(new_path))
return;
QString hashstr = hash();
TorrentPersistentData::setPreviousSavePath(hash(), save_path());
// Create destination directory if necessary
// or move_storage() will fail...
QDir().mkpath(new_path);
// Actually move the storage
torrent_handle::move_storage(new_path.toUtf8().constData());
if (TorrentTempData::isMoveInProgress(hashstr)) {
qDebug("enqueue move storage to %s", qPrintable(new_path));
TorrentTempData::enqueueMove(hashstr, new_path);
}
else {
QString old_path = save_path();
qDebug("move storage: %s to %s", qPrintable(old_path), qPrintable(new_path));
if (QDir(old_path) == QDir(new_path))
return;
TorrentTempData::startMove(hashstr, old_path, new_path);
// Create destination directory if necessary
// or move_storage() will fail...
QDir().mkpath(new_path);
// Actually move the storage
torrent_handle::move_storage(new_path.toUtf8().constData());
}
}
bool QTorrentHandle::save_torrent_file(const QString& path) const {

View file

@ -100,6 +100,64 @@ public:
fp = data.value(hash).files_priority;
}
static bool isMoveInProgress(const QString &hash) {
return torrentMoveStates.find(hash) != torrentMoveStates.end();
}
static void enqueueMove(const QString &hash, const QString &queuedPath) {
QHash<QString, TorrentMoveState>::iterator i = torrentMoveStates.find(hash);
if (i == torrentMoveStates.end()) {
Q_ASSERT(false);
return;
}
i->queuedPath = queuedPath;
}
static void startMove(const QString &hash, const QString &oldPath, const QString& newPath) {
QHash<QString, TorrentMoveState>::iterator i = torrentMoveStates.find(hash);
if (i != torrentMoveStates.end()) {
Q_ASSERT(false);
return;
}
torrentMoveStates.insert(hash, TorrentMoveState(oldPath, newPath));
}
static void finishMove(const QString &hash) {
QHash<QString, TorrentMoveState>::iterator i = torrentMoveStates.find(hash);
if (i == torrentMoveStates.end()) {
Q_ASSERT(false);
return;
}
torrentMoveStates.erase(i);
}
static QString getOldPath(const QString &hash) {
QHash<QString, TorrentMoveState>::iterator i = torrentMoveStates.find(hash);
if (i == torrentMoveStates.end()) {
Q_ASSERT(false);
return QString();
}
return i->oldPath;
}
static QString getNewPath(const QString &hash) {
QHash<QString, TorrentMoveState>::iterator i = torrentMoveStates.find(hash);
if (i == torrentMoveStates.end()) {
Q_ASSERT(false);
return QString();
}
return i->newPath;
}
static QString getQueuedPath(const QString &hash) {
QHash<QString, TorrentMoveState>::iterator i = torrentMoveStates.find(hash);
if (i == torrentMoveStates.end()) {
Q_ASSERT(false);
return QString();
}
return i->queuedPath;
}
private:
struct TorrentData {
TorrentData(): sequential(false), seed(false) {}
@ -111,7 +169,21 @@ private:
bool seed;
};
struct TorrentMoveState {
TorrentMoveState(QString oldPath, QString newPath)
: oldPath(oldPath)
, newPath(newPath)
{}
// the moving occurs from oldPath to newPath
// queuedPath is where files should be moved to, when current moving is completed
QString oldPath;
QString newPath;
QString queuedPath;
};
static QHash<QString, TorrentData> data;
static QHash<QString, TorrentMoveState> torrentMoveStates;
};
class HiddenData {
@ -238,22 +310,6 @@ public:
return data.value("has_error", false).toBool();
}
static void setPreviousSavePath(const QString &hash, const QString &previous_path) {
QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume"));
QHash<QString, QVariant> all_data = settings.value("torrents").toHash();
QHash<QString, QVariant> data = all_data.value(hash).toHash();
data["previous_path"] = previous_path;
all_data[hash] = data;
settings.setValue("torrents", all_data);
}
static QString getPreviousPath(const QString &hash) {
QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume"));
const QHash<QString, QVariant> all_data = settings.value("torrents").toHash();
const QHash<QString, QVariant> data = all_data.value(hash).toHash();
return data.value("previous_path").toString();
}
static void saveSeedDate(const QTorrentHandle &h) {
QIniSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent-resume"));
QHash<QString, QVariant> all_data = settings.value("torrents").toHash();