2023-11-01 21:11:11 +00:00
|
|
|
// This file Copyright © Mnemosyne LLC.
|
2022-02-07 16:25:02 +00:00
|
|
|
// It may be used under GPLv2 (SPDX: GPL-2.0-only), GPLv3 (SPDX: GPL-3.0-only),
|
2022-01-20 18:27:56 +00:00
|
|
|
// or any future license endorsed by Mnemosyne LLC.
|
|
|
|
// License text can be found in the licenses/ folder.
|
2007-12-21 16:51:42 +00:00
|
|
|
|
2023-04-14 19:33:23 +00:00
|
|
|
#include "libtransmission/transmission.h"
|
|
|
|
|
2023-11-26 21:43:37 +00:00
|
|
|
#include "libtransmission/torrent-ctor.h"
|
2023-04-14 19:33:23 +00:00
|
|
|
#include "libtransmission/error.h"
|
2023-11-26 21:43:37 +00:00
|
|
|
#include "libtransmission/utils.h" // for tr_file_read()
|
2007-12-21 16:51:42 +00:00
|
|
|
|
2021-11-05 03:08:38 +00:00
|
|
|
using namespace std::literals;
|
|
|
|
|
2023-11-26 21:43:37 +00:00
|
|
|
tr_ctor::tr_ctor(tr_session* const session)
|
|
|
|
: session_{ session }
|
2007-12-21 16:51:42 +00:00
|
|
|
{
|
2023-11-26 21:43:37 +00:00
|
|
|
set_download_dir(TR_FALLBACK, session->downloadDir());
|
|
|
|
set_paused(TR_FALLBACK, session->shouldPauseAddedTorrents());
|
|
|
|
set_peer_limit(TR_FALLBACK, session->peerLimitPerTorrent());
|
|
|
|
set_should_delete_source_file(session->shouldDeleteSource());
|
2023-10-19 13:39:34 +00:00
|
|
|
}
|
|
|
|
|
2023-11-26 21:43:37 +00:00
|
|
|
bool tr_ctor::set_metainfo_from_file(std::string_view filename, tr_error* error)
|
2008-02-13 02:24:12 +00:00
|
|
|
{
|
2022-01-15 19:33:57 +00:00
|
|
|
if (std::empty(filename))
|
2008-09-23 19:11:04 +00:00
|
|
|
{
|
2023-11-04 16:39:41 +00:00
|
|
|
if (error != nullptr)
|
|
|
|
{
|
|
|
|
error->set(EINVAL, "no filename specified"sv);
|
|
|
|
}
|
|
|
|
|
2021-12-26 16:25:07 +00:00
|
|
|
return false;
|
2007-12-21 16:51:42 +00:00
|
|
|
}
|
2008-02-13 02:24:12 +00:00
|
|
|
|
2023-11-26 21:43:37 +00:00
|
|
|
if (!tr_file_read(filename, contents_, error))
|
2021-12-26 16:25:07 +00:00
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2007-12-21 16:51:42 +00:00
|
|
|
|
2023-11-26 21:43:37 +00:00
|
|
|
torrent_filename_ = filename;
|
|
|
|
auto const contents_sv = std::string_view{ std::data(contents_), std::size(contents_) };
|
|
|
|
return metainfo_.parse_benc(contents_sv, error);
|
2007-12-21 16:51:42 +00:00
|
|
|
}
|
|
|
|
|
2023-11-26 21:43:37 +00:00
|
|
|
bool tr_ctor::save(std::string_view filename, tr_error* error) const
|
2021-12-05 01:32:35 +00:00
|
|
|
{
|
2021-12-24 19:37:34 +00:00
|
|
|
TR_ASSERT(!std::empty(filename));
|
2021-12-05 01:32:35 +00:00
|
|
|
|
2023-11-26 21:43:37 +00:00
|
|
|
if (std::empty(contents_))
|
2021-12-05 01:32:35 +00:00
|
|
|
{
|
2023-11-04 16:39:41 +00:00
|
|
|
if (error != nullptr)
|
|
|
|
{
|
|
|
|
error->set(EINVAL, "torrent ctor has no contents to save"sv);
|
|
|
|
}
|
|
|
|
|
2021-12-05 01:32:35 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2023-11-26 21:43:37 +00:00
|
|
|
return tr_file_save(filename, contents_, error);
|
2021-12-05 01:32:35 +00:00
|
|
|
}
|
|
|
|
|
2023-11-26 21:43:37 +00:00
|
|
|
void tr_ctor::init_torrent_priorities(tr_torrent& tor) const
|
2009-04-02 20:43:42 +00:00
|
|
|
{
|
2023-11-26 21:43:37 +00:00
|
|
|
tor.set_file_priorities(std::data(low_), std::size(low_), TR_PRI_LOW);
|
|
|
|
tor.set_file_priorities(std::data(normal_), std::size(normal_), TR_PRI_NORMAL);
|
|
|
|
tor.set_file_priorities(std::data(high_), std::size(high_), TR_PRI_HIGH);
|
2009-04-02 20:43:42 +00:00
|
|
|
}
|
|
|
|
|
2023-11-26 21:43:37 +00:00
|
|
|
void tr_ctor::init_torrent_wanted(tr_torrent& tor) const
|
2009-04-02 20:43:42 +00:00
|
|
|
{
|
2023-11-26 21:43:37 +00:00
|
|
|
tor.init_files_wanted(std::data(unwanted_), std::size(unwanted_), false);
|
|
|
|
tor.init_files_wanted(std::data(wanted_), std::size(wanted_), true);
|
2009-04-02 20:43:42 +00:00
|
|
|
}
|
|
|
|
|
2023-11-26 21:43:37 +00:00
|
|
|
// --- PUBLIC C API
|
|
|
|
|
|
|
|
tr_ctor* tr_ctorNew(tr_session* session)
|
2009-04-02 20:43:42 +00:00
|
|
|
{
|
2023-11-26 21:43:37 +00:00
|
|
|
return new tr_ctor{ session };
|
2009-04-02 20:43:42 +00:00
|
|
|
}
|
|
|
|
|
2023-11-26 21:43:37 +00:00
|
|
|
void tr_ctorFree(tr_ctor* ctor)
|
2009-04-02 20:43:42 +00:00
|
|
|
{
|
2023-11-26 21:43:37 +00:00
|
|
|
delete ctor;
|
2009-04-02 20:43:42 +00:00
|
|
|
}
|
|
|
|
|
2023-11-26 21:43:37 +00:00
|
|
|
tr_session* tr_ctorGetSession(tr_ctor const* ctor)
|
2008-02-13 02:24:12 +00:00
|
|
|
{
|
2023-11-26 21:43:37 +00:00
|
|
|
return ctor->session();
|
2008-02-13 02:24:12 +00:00
|
|
|
}
|
|
|
|
|
2023-11-26 21:43:37 +00:00
|
|
|
bool tr_ctorSetMetainfoFromFile(tr_ctor* const ctor, char const* const filename, tr_error* const error)
|
2008-02-13 02:24:12 +00:00
|
|
|
{
|
2023-11-26 21:43:37 +00:00
|
|
|
return ctor->set_metainfo_from_file(std::string_view{ filename != nullptr ? filename : "" }, error);
|
2008-02-13 02:24:12 +00:00
|
|
|
}
|
|
|
|
|
2023-11-26 21:43:37 +00:00
|
|
|
bool tr_ctorSetMetainfo(tr_ctor* const ctor, char const* const metainfo, size_t len, tr_error* const error)
|
2007-12-21 16:51:42 +00:00
|
|
|
{
|
2023-11-26 21:43:37 +00:00
|
|
|
auto const metainfo_sv = len == 0 || metainfo == nullptr ? ""sv : std::string_view{ metainfo, len };
|
|
|
|
return ctor->set_metainfo(metainfo_sv, error);
|
2007-12-21 16:51:42 +00:00
|
|
|
}
|
|
|
|
|
2023-11-26 21:43:37 +00:00
|
|
|
bool tr_ctorSetMetainfoFromMagnetLink(tr_ctor* const ctor, char const* const magnet, tr_error* const error)
|
2007-12-21 16:51:42 +00:00
|
|
|
{
|
2023-11-26 21:43:37 +00:00
|
|
|
auto const magnet_sv = std::string_view{ magnet != nullptr ? magnet : "" };
|
|
|
|
return ctor->set_metainfo_from_magnet_link(magnet_sv, error);
|
2007-12-21 16:51:42 +00:00
|
|
|
}
|
|
|
|
|
2023-11-26 21:43:37 +00:00
|
|
|
char const* tr_ctorGetSourceFile(tr_ctor const* const ctor)
|
2007-12-21 16:51:42 +00:00
|
|
|
{
|
2023-11-26 21:43:37 +00:00
|
|
|
return ctor->torrent_filename().c_str();
|
2007-12-21 16:51:42 +00:00
|
|
|
}
|
|
|
|
|
2023-11-26 21:43:37 +00:00
|
|
|
void tr_ctorSetFilePriorities(
|
|
|
|
tr_ctor* const ctor,
|
|
|
|
tr_file_index_t const* const files,
|
|
|
|
tr_file_index_t const n_files,
|
|
|
|
tr_priority_t const priority)
|
2009-10-21 05:03:10 +00:00
|
|
|
{
|
2023-11-26 21:43:37 +00:00
|
|
|
ctor->set_file_priorities(files, n_files, priority);
|
2009-10-21 05:03:10 +00:00
|
|
|
}
|
|
|
|
|
2023-11-26 21:43:37 +00:00
|
|
|
void tr_ctorSetFilesWanted(tr_ctor* ctor, tr_file_index_t const* const files, tr_file_index_t const n_files, bool const wanted)
|
2007-12-21 16:51:42 +00:00
|
|
|
{
|
2023-11-26 21:43:37 +00:00
|
|
|
ctor->set_files_wanted(files, n_files, wanted);
|
2007-12-21 16:51:42 +00:00
|
|
|
}
|
|
|
|
|
2023-11-26 21:43:37 +00:00
|
|
|
void tr_ctorSetDeleteSource(tr_ctor* const ctor, bool const delete_source)
|
2007-12-21 16:51:42 +00:00
|
|
|
{
|
2023-11-26 21:43:37 +00:00
|
|
|
ctor->set_should_delete_source_file(delete_source);
|
2007-12-21 16:51:42 +00:00
|
|
|
}
|
|
|
|
|
2023-11-26 21:43:37 +00:00
|
|
|
bool tr_ctorGetDeleteSource(tr_ctor const* const ctor, bool* const setme)
|
2007-12-21 16:51:42 +00:00
|
|
|
{
|
2023-11-26 21:43:37 +00:00
|
|
|
if (ctor != nullptr)
|
2017-04-19 12:04:45 +00:00
|
|
|
{
|
2023-11-26 21:43:37 +00:00
|
|
|
if (setme != nullptr)
|
|
|
|
{
|
|
|
|
*setme = ctor->should_delete_source_file();
|
|
|
|
}
|
2007-12-21 22:18:40 +00:00
|
|
|
|
2023-11-26 21:43:37 +00:00
|
|
|
return true;
|
2021-11-07 23:35:32 +00:00
|
|
|
}
|
|
|
|
|
2023-11-26 21:43:37 +00:00
|
|
|
return false;
|
2007-12-21 16:51:42 +00:00
|
|
|
}
|
|
|
|
|
2023-11-26 21:43:37 +00:00
|
|
|
void tr_ctorSetPaused(tr_ctor* const ctor, tr_ctorMode const mode, bool const paused)
|
2009-10-21 05:03:10 +00:00
|
|
|
{
|
2023-11-26 21:43:37 +00:00
|
|
|
ctor->set_paused(mode, paused);
|
2009-10-21 05:03:10 +00:00
|
|
|
}
|
|
|
|
|
2023-11-26 21:43:37 +00:00
|
|
|
void tr_ctorSetPeerLimit(tr_ctor* const ctor, tr_ctorMode const mode, uint16_t const peer_limit)
|
2022-01-15 19:33:57 +00:00
|
|
|
{
|
2023-11-26 21:43:37 +00:00
|
|
|
ctor->set_peer_limit(mode, peer_limit);
|
2022-01-15 19:33:57 +00:00
|
|
|
}
|
|
|
|
|
2023-11-26 21:43:37 +00:00
|
|
|
void tr_ctorSetDownloadDir(tr_ctor* const ctor, tr_ctorMode const mode, char const* const dir)
|
2007-12-21 16:51:42 +00:00
|
|
|
{
|
2024-02-13 16:42:19 +00:00
|
|
|
ctor->set_download_dir(mode, std::string_view{ dir != nullptr ? dir : "" });
|
2007-12-21 22:18:40 +00:00
|
|
|
}
|
|
|
|
|
2023-11-26 21:43:37 +00:00
|
|
|
void tr_ctorSetIncompleteDir(tr_ctor* const ctor, char const* const dir)
|
2009-04-02 17:30:29 +00:00
|
|
|
{
|
2024-02-13 16:42:19 +00:00
|
|
|
ctor->set_incomplete_dir(std::string_view{ dir != nullptr ? dir : "" });
|
2009-04-02 17:30:29 +00:00
|
|
|
}
|
|
|
|
|
2023-11-26 21:43:37 +00:00
|
|
|
bool tr_ctorGetPeerLimit(tr_ctor const* const ctor, tr_ctorMode const mode, uint16_t* const setme)
|
2010-02-02 07:48:03 +00:00
|
|
|
{
|
2023-11-26 21:43:37 +00:00
|
|
|
if (auto const val = ctor->peer_limit(mode); val)
|
2017-04-19 12:04:45 +00:00
|
|
|
{
|
2023-11-26 21:43:37 +00:00
|
|
|
if (setme != nullptr)
|
|
|
|
{
|
|
|
|
*setme = *val;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
2017-04-19 12:04:45 +00:00
|
|
|
}
|
2023-01-07 22:55:00 +00:00
|
|
|
|
2023-11-26 21:43:37 +00:00
|
|
|
return false;
|
2010-02-02 07:48:03 +00:00
|
|
|
}
|
|
|
|
|
2023-11-26 21:43:37 +00:00
|
|
|
bool tr_ctorGetPaused(tr_ctor const* const ctor, tr_ctorMode const mode, bool* const setme)
|
2010-02-02 07:48:03 +00:00
|
|
|
{
|
2023-11-26 21:43:37 +00:00
|
|
|
if (auto const val = ctor->paused(mode); val)
|
|
|
|
{
|
|
|
|
if (setme != nullptr)
|
|
|
|
{
|
|
|
|
*setme = *val;
|
|
|
|
}
|
2010-02-02 07:48:03 +00:00
|
|
|
|
2023-11-26 21:43:37 +00:00
|
|
|
return true;
|
|
|
|
}
|
2010-02-02 07:48:03 +00:00
|
|
|
|
2023-11-26 21:43:37 +00:00
|
|
|
return false;
|
2022-02-03 06:02:30 +00:00
|
|
|
}
|
|
|
|
|
2023-11-26 21:43:37 +00:00
|
|
|
bool tr_ctorGetDownloadDir(tr_ctor const* const ctor, tr_ctorMode const mode, char const** setme)
|
2022-02-03 06:02:30 +00:00
|
|
|
{
|
2023-11-26 21:43:37 +00:00
|
|
|
if (auto const& val = ctor->download_dir(mode); !std::empty(val))
|
|
|
|
{
|
|
|
|
if (setme != nullptr)
|
|
|
|
{
|
|
|
|
*setme = val.c_str();
|
|
|
|
}
|
2022-02-03 06:02:30 +00:00
|
|
|
|
2023-11-26 21:43:37 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
2022-02-03 06:02:30 +00:00
|
|
|
|
2023-11-26 21:43:37 +00:00
|
|
|
bool tr_ctorGetIncompleteDir(tr_ctor const* const ctor, char const** setme)
|
2007-12-21 22:18:40 +00:00
|
|
|
{
|
2023-11-26 21:43:37 +00:00
|
|
|
if (auto const& val = ctor->incomplete_dir(); !std::empty(val))
|
|
|
|
{
|
|
|
|
if (setme != nullptr)
|
|
|
|
{
|
|
|
|
*setme = val.c_str();
|
|
|
|
}
|
2017-04-19 12:04:45 +00:00
|
|
|
|
2023-11-26 21:43:37 +00:00
|
|
|
return true;
|
|
|
|
}
|
2017-04-19 12:04:45 +00:00
|
|
|
|
2023-11-26 21:43:37 +00:00
|
|
|
return false;
|
2007-12-21 22:18:40 +00:00
|
|
|
}
|
|
|
|
|
2023-11-26 21:43:37 +00:00
|
|
|
tr_torrent_metainfo const* tr_ctorGetMetainfo(tr_ctor const* const ctor)
|
2017-04-19 12:04:45 +00:00
|
|
|
{
|
2023-11-26 21:43:37 +00:00
|
|
|
auto const& metainfo = ctor->metainfo();
|
|
|
|
return std::empty(metainfo.info_hash_string()) ? nullptr : &metainfo;
|
2007-12-21 16:51:42 +00:00
|
|
|
}
|