mirror of
https://github.com/transmission/transmission
synced 2024-12-22 07:42:37 +00:00
fix: only append '.added' suffix to watchdir files (#5705)
This commit is contained in:
parent
089c438512
commit
2c9768bc12
8 changed files with 83 additions and 41 deletions
|
@ -124,3 +124,28 @@ QString AddData::readableShortName() const
|
||||||
return readableName();
|
return readableName();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AddData::disposeSourceFile() const
|
||||||
|
{
|
||||||
|
auto file = QFile{ filename };
|
||||||
|
if (!disposal_ || !file.exists())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (*disposal_)
|
||||||
|
{
|
||||||
|
case FilenameDisposal::Delete:
|
||||||
|
file.setPermissions(QFile::ReadOwner | QFile::WriteOwner);
|
||||||
|
file.remove();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FilenameDisposal::Rename:
|
||||||
|
file.rename(QStringLiteral("%1.added").arg(filename));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// no action
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
23
qt/AddData.h
23
qt/AddData.h
|
@ -14,6 +14,14 @@
|
||||||
class AddData
|
class AddData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
// what to do with the source file after adding the torrent
|
||||||
|
enum class FilenameDisposal
|
||||||
|
{
|
||||||
|
NoAction,
|
||||||
|
Delete,
|
||||||
|
Rename
|
||||||
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
NONE,
|
NONE,
|
||||||
|
@ -36,6 +44,18 @@ public:
|
||||||
QString readableName() const;
|
QString readableName() const;
|
||||||
QString readableShortName() const;
|
QString readableShortName() const;
|
||||||
|
|
||||||
|
void disposeSourceFile() const;
|
||||||
|
|
||||||
|
constexpr void setFileDisposal(FilenameDisposal disposal)
|
||||||
|
{
|
||||||
|
disposal_ = disposal;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr auto& fileDisposal() const noexcept
|
||||||
|
{
|
||||||
|
return disposal_;
|
||||||
|
}
|
||||||
|
|
||||||
static std::optional<AddData> create(QString const& str)
|
static std::optional<AddData> create(QString const& str)
|
||||||
{
|
{
|
||||||
if (auto ret = AddData{ str }; ret.type != NONE)
|
if (auto ret = AddData{ str }; ret.type != NONE)
|
||||||
|
@ -51,4 +71,7 @@ public:
|
||||||
QString filename;
|
QString filename;
|
||||||
QString magnet;
|
QString magnet;
|
||||||
QUrl url;
|
QUrl url;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::optional<FilenameDisposal> disposal_;
|
||||||
};
|
};
|
||||||
|
|
|
@ -286,7 +286,7 @@ Application::Application(int& argc, char** argv)
|
||||||
connect(session_.get(), &Session::sourceChanged, this, &Application::onSessionSourceChanged);
|
connect(session_.get(), &Session::sourceChanged, this, &Application::onSessionSourceChanged);
|
||||||
connect(session_.get(), &Session::torrentsRemoved, model_.get(), &TorrentModel::removeTorrents);
|
connect(session_.get(), &Session::torrentsRemoved, model_.get(), &TorrentModel::removeTorrents);
|
||||||
connect(session_.get(), &Session::torrentsUpdated, model_.get(), &TorrentModel::updateTorrents);
|
connect(session_.get(), &Session::torrentsUpdated, model_.get(), &TorrentModel::updateTorrents);
|
||||||
connect(watch_dir_.get(), &WatchDir::torrentFileAdded, this, qOverload<QString const&>(&Application::addTorrent));
|
connect(watch_dir_.get(), &WatchDir::torrentFileAdded, this, qOverload<QString const&>(&Application::addWatchdirTorrent));
|
||||||
|
|
||||||
// init from preferences
|
// init from preferences
|
||||||
for (auto const key : { Prefs::DIR_WATCH })
|
for (auto const key : { Prefs::DIR_WATCH })
|
||||||
|
@ -343,9 +343,10 @@ Application::Application(int& argc, char** argv)
|
||||||
dialog->show();
|
dialog->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// torrent files passed in on the command line
|
||||||
for (QString const& filename : filenames)
|
for (QString const& filename : filenames)
|
||||||
{
|
{
|
||||||
addTorrent(filename);
|
addTorrent(AddData{ filename });
|
||||||
}
|
}
|
||||||
|
|
||||||
InteropHelper::registerObject(this);
|
InteropHelper::registerObject(this);
|
||||||
|
@ -571,18 +572,29 @@ void Application::refreshTorrents()
|
||||||
****
|
****
|
||||||
***/
|
***/
|
||||||
|
|
||||||
void Application::addTorrent(QString const& addme) const
|
void Application::addWatchdirTorrent(QString const& filename) const
|
||||||
{
|
{
|
||||||
addTorrent(AddData(addme));
|
auto add_data = AddData{ filename };
|
||||||
|
auto const disposal = prefs_->getBool(Prefs::TRASH_ORIGINAL) ? AddData::FilenameDisposal::Delete :
|
||||||
|
AddData::FilenameDisposal::Rename;
|
||||||
|
add_data.setFileDisposal(disposal);
|
||||||
|
addTorrent(std::move(add_data));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::addTorrent(AddData const& addme) const
|
void Application::addTorrent(AddData addme) const
|
||||||
{
|
{
|
||||||
if (addme.type == addme.NONE)
|
if (addme.type == addme.NONE)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if there's not already a disposal action set,
|
||||||
|
// then honor the `trash original` preference setting
|
||||||
|
if (!addme.fileDisposal() && prefs_->getBool(Prefs::TRASH_ORIGINAL))
|
||||||
|
{
|
||||||
|
addme.setFileDisposal(AddData::FilenameDisposal::Delete);
|
||||||
|
}
|
||||||
|
|
||||||
if (!prefs_->getBool(Prefs::OPTIONS_PROMPT))
|
if (!prefs_->getBool(Prefs::OPTIONS_PROMPT))
|
||||||
{
|
{
|
||||||
session_->addTorrent(addme);
|
session_->addTorrent(addme);
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include <libtransmission/tr-macros.h>
|
#include <libtransmission/tr-macros.h>
|
||||||
#include <libtransmission/favicon-cache.h>
|
#include <libtransmission/favicon-cache.h>
|
||||||
|
|
||||||
|
#include "AddData.h"
|
||||||
#include "Typedefs.h"
|
#include "Typedefs.h"
|
||||||
#include "Utils.h" // std::hash<QString>
|
#include "Utils.h" // std::hash<QString>
|
||||||
|
|
||||||
|
@ -71,8 +72,8 @@ signals:
|
||||||
void faviconsChanged();
|
void faviconsChanged();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void addTorrent(AddData const&) const;
|
void addTorrent(AddData) const;
|
||||||
void addTorrent(QString const&) const;
|
void addWatchdirTorrent(QString const& filename) const;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void consentGiven(int result) const;
|
void consentGiven(int result) const;
|
||||||
|
|
|
@ -1315,9 +1315,7 @@ void MainWindow::addTorrents(QStringList const& filenames)
|
||||||
|
|
||||||
if (auto const* const file_dialog = qobject_cast<QFileDialog const*>(sender()); file_dialog != nullptr)
|
if (auto const* const file_dialog = qobject_cast<QFileDialog const*>(sender()); file_dialog != nullptr)
|
||||||
{
|
{
|
||||||
auto const* const b = file_dialog->findChild<QCheckBox const*>(show_options_checkbox_name_);
|
if (auto const* const b = file_dialog->findChild<QCheckBox const*>(show_options_checkbox_name_); b != nullptr)
|
||||||
|
|
||||||
if (b != nullptr)
|
|
||||||
{
|
{
|
||||||
show_options = b->isChecked();
|
show_options = b->isChecked();
|
||||||
}
|
}
|
||||||
|
@ -1325,7 +1323,7 @@ void MainWindow::addTorrents(QStringList const& filenames)
|
||||||
|
|
||||||
for (QString const& filename : filenames)
|
for (QString const& filename : filenames)
|
||||||
{
|
{
|
||||||
addTorrent(AddData(filename), show_options);
|
addTorrent(AddData{ filename }, show_options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1594,7 +1592,7 @@ void MainWindow::dropEvent(QDropEvent* event)
|
||||||
key = url.toLocalFile();
|
key = url.toLocalFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
trApp->addTorrent(AddData(key));
|
trApp->addTorrent(AddData{ key });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1625,7 +1623,7 @@ bool MainWindow::event(QEvent* e)
|
||||||
if (!clipboard_processed_keys_.contains(key))
|
if (!clipboard_processed_keys_.contains(key))
|
||||||
{
|
{
|
||||||
clipboard_processed_keys_.append(key);
|
clipboard_processed_keys_.append(key);
|
||||||
trApp->addTorrent(AddData(key));
|
trApp->addTorrent(AddData{ key });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -297,7 +297,10 @@ void OptionsDialog::onAccepted()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
session_.addTorrent(add_, &args, ui_.trashCheck->isChecked());
|
auto const disposal = ui_.trashCheck->isChecked() ? AddData::FilenameDisposal::Delete : AddData::FilenameDisposal::NoAction;
|
||||||
|
add_.setFileDisposal(disposal);
|
||||||
|
|
||||||
|
session_.addTorrent(add_, &args);
|
||||||
|
|
||||||
deleteLater();
|
deleteLater();
|
||||||
}
|
}
|
||||||
|
|
|
@ -990,7 +990,7 @@ void Session::setBlocklistSize(int64_t i)
|
||||||
emit blocklistUpdated(i);
|
emit blocklistUpdated(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::addTorrent(AddData add_me, tr_variant* args_dict, bool trash_original)
|
void Session::addTorrent(AddData add_me, tr_variant* args_dict)
|
||||||
{
|
{
|
||||||
assert(tr_variantDictFind(args_dict, TR_KEY_filename) == nullptr);
|
assert(tr_variantDictFind(args_dict, TR_KEY_filename) == nullptr);
|
||||||
assert(tr_variantDictFind(args_dict, TR_KEY_metainfo) == nullptr);
|
assert(tr_variantDictFind(args_dict, TR_KEY_metainfo) == nullptr);
|
||||||
|
@ -1037,41 +1037,22 @@ void Session::addTorrent(AddData add_me, tr_variant* args_dict, bool trash_origi
|
||||||
});
|
});
|
||||||
|
|
||||||
q->add(
|
q->add(
|
||||||
[this, add_me, trash_original](RpcResponse const& r)
|
[this, add_me](RpcResponse const& r)
|
||||||
{
|
{
|
||||||
bool session_has_torrent = false;
|
|
||||||
|
|
||||||
if (tr_variant* dup = nullptr; tr_variantDictFindDict(r.args.get(), TR_KEY_torrent_added, &dup))
|
if (tr_variant* dup = nullptr; tr_variantDictFindDict(r.args.get(), TR_KEY_torrent_added, &dup))
|
||||||
{
|
{
|
||||||
session_has_torrent = true;
|
add_me.disposeSourceFile();
|
||||||
}
|
}
|
||||||
else if (tr_variantDictFindDict(r.args.get(), TR_KEY_torrent_duplicate, &dup))
|
else if (tr_variantDictFindDict(r.args.get(), TR_KEY_torrent_duplicate, &dup))
|
||||||
{
|
{
|
||||||
session_has_torrent = true;
|
add_me.disposeSourceFile();
|
||||||
|
|
||||||
auto const hash = dictFind<QString>(dup, TR_KEY_hashString);
|
if (auto const hash = dictFind<QString>(dup, TR_KEY_hashString); hash)
|
||||||
if (hash)
|
|
||||||
{
|
{
|
||||||
duplicates_.try_emplace(add_me.readableShortName(), *hash);
|
duplicates_.try_emplace(add_me.readableShortName(), *hash);
|
||||||
duplicates_timer_.start(1000);
|
duplicates_timer_.start(1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto const& filename = add_me.filename;
|
|
||||||
session_has_torrent && !filename.isEmpty() && add_me.type == AddData::FILENAME)
|
|
||||||
{
|
|
||||||
auto file = QFile{ filename };
|
|
||||||
|
|
||||||
if (trash_original)
|
|
||||||
{
|
|
||||||
file.setPermissions(QFile::ReadOwner | QFile::WriteOwner);
|
|
||||||
file.remove();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
file.rename(QStringLiteral("%1.added").arg(filename));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
q->run();
|
q->run();
|
||||||
|
@ -1112,8 +1093,7 @@ void Session::addTorrent(AddData add_me)
|
||||||
{
|
{
|
||||||
tr_variant args;
|
tr_variant args;
|
||||||
tr_variantInitDict(&args, 3);
|
tr_variantInitDict(&args, 3);
|
||||||
|
addTorrent(std::move(add_me), &args);
|
||||||
addTorrent(std::move(add_me), &args, prefs_.getBool(Prefs::TRASH_ORIGINAL));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::addNewlyCreatedTorrent(QString const& filename, QString const& local_path)
|
void Session::addNewlyCreatedTorrent(QString const& filename, QString const& local_path)
|
||||||
|
|
|
@ -93,7 +93,7 @@ public:
|
||||||
|
|
||||||
void torrentSetLocation(torrent_ids_t const& torrent_ids, QString const& path, bool do_move);
|
void torrentSetLocation(torrent_ids_t const& torrent_ids, QString const& path, bool do_move);
|
||||||
void torrentRenamePath(torrent_ids_t const& torrent_ids, QString const& oldpath, QString const& newname);
|
void torrentRenamePath(torrent_ids_t const& torrent_ids, QString const& oldpath, QString const& newname);
|
||||||
void addTorrent(AddData add_me, tr_variant* args_dict, bool trash_original);
|
void addTorrent(AddData add_me, tr_variant* args_dict);
|
||||||
void initTorrents(torrent_ids_t const& ids = {});
|
void initTorrents(torrent_ids_t const& ids = {});
|
||||||
void pauseTorrents(torrent_ids_t const& torrent_ids = {});
|
void pauseTorrents(torrent_ids_t const& torrent_ids = {});
|
||||||
void startTorrents(torrent_ids_t const& torrent_ids = {});
|
void startTorrents(torrent_ids_t const& torrent_ids = {});
|
||||||
|
|
Loading…
Reference in a new issue