From 7068eb66c1268c098c480415ee1e7c48a41923a7 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Sat, 8 Jan 2022 21:03:21 -0600 Subject: [PATCH] refactor: migrate makeFilename() to tr_magnet_metainfo (#2385) --- libtransmission/magnet-metainfo.cc | 13 ++++ libtransmission/magnet-metainfo.h | 18 +++++ libtransmission/metainfo.cc | 52 +++----------- libtransmission/metainfo.h | 21 ------ libtransmission/resume.cc | 17 ++--- libtransmission/torrent-metainfo.cc | 106 +--------------------------- libtransmission/torrent.cc | 35 +++++++-- 7 files changed, 79 insertions(+), 183 deletions(-) diff --git a/libtransmission/magnet-metainfo.cc b/libtransmission/magnet-metainfo.cc index b2b9d9a2c..028a95494 100644 --- a/libtransmission/magnet-metainfo.cc +++ b/libtransmission/magnet-metainfo.cc @@ -260,3 +260,16 @@ void tr_magnet_metainfo::toVariant(tr_variant* top) const tr_variantDictAddStr(d, TR_KEY_display_name, this->name()); } } + +std::string tr_magnet_metainfo::makeFilename( + std::string_view dirname, + std::string_view name, + std::string_view info_hash_string, + BasenameFormat format, + std::string_view suffix) +{ + // `${dirname}/${name}.${info_hash}${suffix}` + // `${dirname}/${info_hash}${suffix}` + return format == BasenameFormat::Hash ? tr_strvJoin(dirname, "/"sv, info_hash_string, suffix) : + tr_strvJoin(dirname, "/"sv, name, "."sv, info_hash_string.substr(0, 16), suffix); +} diff --git a/libtransmission/magnet-metainfo.h b/libtransmission/magnet-metainfo.h index 0042a7871..d04345951 100644 --- a/libtransmission/magnet-metainfo.h +++ b/libtransmission/magnet-metainfo.h @@ -63,6 +63,24 @@ public: void toVariant(tr_variant* top) const; + enum class BasenameFormat + { + Hash, + NameAndPartialHash + }; + + static std::string makeFilename( + std::string_view dirname, + std::string_view name, + std::string_view info_hash_string, + BasenameFormat format, + std::string_view suffix); + + std::string makeFilename(std::string_view dirname, BasenameFormat format, std::string_view suffix) const + { + return makeFilename(dirname, name(), infoHashString(), format, suffix); + } + protected: tr_announce_list announce_list_; std::vector webseed_urls_; diff --git a/libtransmission/metainfo.cc b/libtransmission/metainfo.cc index 854bcca89..ddf467a89 100644 --- a/libtransmission/metainfo.cc +++ b/libtransmission/metainfo.cc @@ -28,6 +28,7 @@ #include "torrent.h" #include "utils.h" #include "variant.h" +#include "magnet-metainfo.h" #include "web-utils.h" using namespace std::literals; @@ -36,21 +37,14 @@ using namespace std::literals; **** ***/ -std::string tr_buildTorrentFilename( - std::string_view dirname, - std::string_view name, - std::string_view info_hash_string, - enum tr_metainfo_basename_format format, - std::string_view suffix) +static std::string getTorrentFilename(tr_session const* session, tr_info const* inf, tr_magnet_metainfo::BasenameFormat format) { - return format == TR_METAINFO_BASENAME_NAME_AND_PARTIAL_HASH ? - tr_strvJoin(dirname, "/"sv, name, "."sv, info_hash_string.substr(0, 16), suffix) : - tr_strvJoin(dirname, "/"sv, info_hash_string, suffix); -} - -static std::string getTorrentFilename(tr_session const* session, tr_info const* inf, enum tr_metainfo_basename_format format) -{ - return tr_buildTorrentFilename(tr_getTorrentDir(session), inf->name(), inf->infoHashString(), format, ".torrent"sv); + return tr_magnet_metainfo::makeFilename( + tr_getTorrentDir(session), + inf->name(), + inf->infoHashString(), + format, + ".torrent"sv); } /*** @@ -508,7 +502,7 @@ static char const* tr_metainfoParseImpl( geturllist(inf, meta); /* filename of Transmission's copy */ - inf->torrent_file_ = session != nullptr ? getTorrentFilename(session, inf, TR_METAINFO_BASENAME_HASH) : ""sv; + inf->torrent_file_ = session != nullptr ? getTorrentFilename(session, inf, tr_magnet_metainfo::BasenameFormat::Hash) : ""sv; return nullptr; } @@ -544,31 +538,3 @@ void tr_metainfoFree(tr_info* inf) inf->announce_list.reset(); } - -void tr_metainfoRemoveSaved(tr_session const* session, tr_info const* inf) -{ - auto filename = getTorrentFilename(session, inf, TR_METAINFO_BASENAME_HASH); - tr_sys_path_remove(filename.c_str(), nullptr); - - filename = getTorrentFilename(session, inf, TR_METAINFO_BASENAME_NAME_AND_PARTIAL_HASH); - tr_sys_path_remove(filename.c_str(), nullptr); -} - -void tr_metainfoMigrateFile( - tr_session const* session, - tr_info const* info, - enum tr_metainfo_basename_format old_format, - enum tr_metainfo_basename_format new_format) -{ - auto const old_filename = getTorrentFilename(session, info, old_format); - auto const new_filename = getTorrentFilename(session, info, new_format); - - if (tr_sys_path_rename(old_filename.c_str(), new_filename.c_str(), nullptr)) - { - tr_logAddNamedError( - info->name().c_str(), - "Migrated torrent file from \"%s\" to \"%s\"", - old_filename.c_str(), - new_filename.c_str()); - } -} diff --git a/libtransmission/metainfo.h b/libtransmission/metainfo.h index 085018971..c55532732 100644 --- a/libtransmission/metainfo.h +++ b/libtransmission/metainfo.h @@ -28,12 +28,6 @@ struct tr_error; struct tr_variant; -enum tr_metainfo_basename_format -{ - TR_METAINFO_BASENAME_NAME_AND_PARTIAL_HASH, - TR_METAINFO_BASENAME_HASH -}; - struct tr_metainfo_parsed { tr_info info = {}; @@ -62,20 +56,5 @@ struct tr_metainfo_parsed std::optional tr_metainfoParse(tr_session const* session, tr_variant const* variant, tr_error** error); -void tr_metainfoRemoveSaved(tr_session const* session, tr_info const* info); - -std::string tr_buildTorrentFilename( - std::string_view dirname, - std::string_view name, - std::string_view info_hash_string, - enum tr_metainfo_basename_format format, - std::string_view suffix); - -void tr_metainfoMigrateFile( - tr_session const* session, - tr_info const* info, - enum tr_metainfo_basename_format old_format, - enum tr_metainfo_basename_format new_format); - /** @brief Private function that's exposed here only for unit tests */ bool tr_metainfoAppendSanitizedPathComponent(std::string& out, std::string_view in); diff --git a/libtransmission/resume.cc b/libtransmission/resume.cc index 62bad57f2..ae5751cab 100644 --- a/libtransmission/resume.cc +++ b/libtransmission/resume.cc @@ -17,6 +17,7 @@ #include "error.h" #include "file.h" #include "log.h" +#include "magnet-metainfo.h" #include "metainfo.h" /* tr_metainfoGetBasename() */ #include "peer-mgr.h" /* pex */ #include "platform.h" /* tr_getResumeDir() */ @@ -36,9 +37,9 @@ constexpr int MAX_REMEMBERED_PEERS = 200; } // unnamed namespace -static std::string getResumeFilename(tr_torrent const* tor, enum tr_metainfo_basename_format format) +static std::string getResumeFilename(tr_torrent const* tor, tr_magnet_metainfo::BasenameFormat format) { - return tr_buildTorrentFilename( + return tr_magnet_metainfo::makeFilename( tr_getResumeDir(tor->session), tr_torrentName(tor), tor->infoHashString(), @@ -692,8 +693,8 @@ void tr_torrentSaveResume(tr_torrent* tor) saveName(&top, tor); saveLabels(&top, tor); - std::string const filename = getResumeFilename(tor, TR_METAINFO_BASENAME_HASH); - int const err = tr_variantToFile(&top, TR_VARIANT_FMT_BENC, filename.c_str()); + auto const filename = getResumeFilename(tor, tr_magnet_metainfo::BasenameFormat::Hash); + auto const err = tr_variantToFile(&top, TR_VARIANT_FMT_BENC, filename.c_str()); if (err != 0) { tor->setLocalError(tr_strvJoin("Unable to save resume file: ", tr_strerror(err))); @@ -719,7 +720,7 @@ static uint64_t loadFromFile(tr_torrent* tor, uint64_t fieldsToLoad, bool* didRe *didRenameToHashOnlyName = false; } - std::string const filename = getResumeFilename(tor, TR_METAINFO_BASENAME_HASH); + std::string const filename = getResumeFilename(tor, tr_magnet_metainfo::BasenameFormat::Hash); auto buf = std::vector{}; if (!tr_loadFile(buf, filename, &error) || @@ -733,7 +734,7 @@ static uint64_t loadFromFile(tr_torrent* tor, uint64_t fieldsToLoad, bool* didRe tr_logAddTorDbg(tor, "Couldn't read \"%s\": %s", filename.c_str(), error->message); tr_error_clear(&error); - std::string const old_filename = getResumeFilename(tor, TR_METAINFO_BASENAME_NAME_AND_PARTIAL_HASH); + std::string const old_filename = getResumeFilename(tor, tr_magnet_metainfo::BasenameFormat::NameAndPartialHash); if (!tr_variantFromFile(&top, TR_VARIANT_PARSE_BENC, old_filename.c_str(), &error)) { @@ -969,9 +970,9 @@ uint64_t tr_torrentLoadResume(tr_torrent* tor, uint64_t fieldsToLoad, tr_ctor co void tr_torrentRemoveResume(tr_torrent const* tor) { - std::string filename = getResumeFilename(tor, TR_METAINFO_BASENAME_HASH); + std::string filename = getResumeFilename(tor, tr_magnet_metainfo::BasenameFormat::Hash); tr_sys_path_remove(filename.c_str(), nullptr); - filename = getResumeFilename(tor, TR_METAINFO_BASENAME_NAME_AND_PARTIAL_HASH); + filename = getResumeFilename(tor, tr_magnet_metainfo::BasenameFormat::NameAndPartialHash); tr_sys_path_remove(filename.c_str(), nullptr); } diff --git a/libtransmission/torrent-metainfo.cc b/libtransmission/torrent-metainfo.cc index f260652d4..a0e644e8b 100644 --- a/libtransmission/torrent-metainfo.cc +++ b/libtransmission/torrent-metainfo.cc @@ -28,32 +28,11 @@ using namespace std::literals; -#if 0 -tr_piece_index_t getBytePiece(tr_torrent_metainfo const& tm, uint64_t byte_offset) -{ - // handle 0-byte files at the end of a torrent - return byte_offset == tm.total_size ? tm.n_pieces - 1 : byte_offset / tm.piece_size; -} -#endif - -#if 0 -std::string tr_new_magnet_metainfo::makeFilename(std::string_view dirname, FilenameFormat format, std::string_view suffix) const -{ - // `${dirname}/${name}.${info_hash}${suffix}` - // `${dirname}/${info_hash}${suffix}` - return format == FilenameFormat::NameAndParitalHash ? - tr_strvJoin(dirname, "/"sv, this->name, "."sv, this->infoHashString().substr(0, 16), suffix) : - tr_strvJoin(dirname, "/"sv, this->infoHashString(), suffix); -} -#endif - -/// tr_torrent_metainfo - //// C BINDINGS +#if 0 /// Lifecycle -#if 0 tr_torrent_metainfo* tr_torrentMetainfoNewFromData(char const* data, size_t data_len, struct tr_error** error) { auto* tm = new tr_torrent_metainfo{}; @@ -65,9 +44,7 @@ tr_torrent_metainfo* tr_torrentMetainfoNewFromData(char const* data, size_t data return tm; } -#endif -#if 0 tr_torrent_metainfo* tr_torrentMetainfoNewFromFile(char const* filename, struct tr_error** error) { auto* tm = new tr_torrent_metainfo{}; @@ -79,27 +56,21 @@ tr_torrent_metainfo* tr_torrentMetainfoNewFromFile(char const* filename, struct return tm; } -#endif -#if 0 void tr_torrentMetainfoFree(tr_torrent_metainfo* tm) { delete tm; } -#endif //// Accessors -#if 0 char* tr_torrentMetainfoMagnet(struct tr_torrent_metainfo const* tm) { return tr_strvDup(tm->magnet()); } -#endif /// Info -#if 0 tr_torrent_metainfo_info* tr_torrentMetainfoGet(tr_torrent_metainfo const* tm, tr_torrent_metainfo_info* setme) { setme->comment = tm->comment.c_str(); @@ -114,18 +85,14 @@ tr_torrent_metainfo_info* tr_torrentMetainfoGet(tr_torrent_metainfo const* tm, t setme->total_size = tm->total_size; return setme; } -#endif /// Files -#if 0 size_t tr_torrentMetainfoFileCount(tr_torrent_metainfo const* tm) { return std::size(tm->files); } -#endif -#if 0 tr_torrent_metainfo_file_info* tr_torrentMetainfoFile( tr_torrent_metainfo const* tm, size_t n, @@ -136,18 +103,14 @@ tr_torrent_metainfo_file_info* tr_torrentMetainfoFile( setme->size = file.size; return setme; } -#endif /// Trackers -#if 0 size_t tr_torrentMetainfoTrackerCount(tr_torrent_metainfo const* tm) { return std::size(tm->trackers); } -#endif -#if 0 tr_torrent_metainfo_tracker_info* tr_torrentMetainfoTracker( tr_torrent_metainfo const* tm, size_t n, @@ -163,73 +126,6 @@ tr_torrent_metainfo_tracker_info* tr_torrentMetainfoTracker( } #endif -#if 0 -void tr_metainfoDestruct(tr_info* inf) -{ - for (unsigned int i = 0; i < inf->webseedCount; i++) - { - tr_free(inf->webseeds[i]); - } - - for (tr_file_index_t ff = 0; ff < inf->fileCount; ff++) - { - tr_free(inf->files[ff].name); - } - - tr_free(inf->webseeds); - tr_free(inf->files); - tr_free(inf->comment); - tr_free(inf->creator); - tr_free(inf->source); - tr_free(inf->torrent); - tr_free(inf->originalName); - tr_free(inf->name); - - for (unsigned int i = 0; i < inf->trackerCount; i++) - { - tr_free(inf->trackers[i].announce); - tr_free(inf->trackers[i].scrape); - } - - tr_free(inf->trackers); - - memset(inf, '\0', sizeof(tr_info)); -} - -static std::string getTorrentFilename(tr_session const* session, tr_info const* inf, enum tr_metainfo_basename_format format) -{ - return tr_buildTorrentFilename(tr_getTorrentDir(session), inf, format, ".torrent"sv); -} - -void tr_metainfoRemoveSaved(tr_session const* session, tr_torrent_metainfo const& metainfo) -{ - auto filename = getTorrentFilename(session, inf, tr_torrent_metainfo::FilenameFormat::FullHash); - tr_sys_path_remove(filename.c_str(), nullptr); - - filename = getTorrentFilename(session, inf, tr_torrent_metainfo::FilenameFormat::NameAndParitalHash); - tr_sys_path_remove(filename.c_str(), nullptr); -} - -void tr_metainfoMigrateFile( - tr_session const* session, - tr_info const* info, - enum tr_metainfo_basename_format old_format, - enum tr_metainfo_basename_format new_format) -{ - auto const old_filename = getTorrentFilename(session, info, old_format); - auto const new_filename = getTorrentFilename(session, info, new_format); - - if (tr_sys_path_rename(old_filename.c_str(), new_filename.c_str(), nullptr)) - { - tr_logAddNamedError( - info->name, - "Migrated torrent file from \"%s\" to \"%s\"", - old_filename.c_str(), - new_filename.c_str()); - } -} -#endif - /*** **** ***/ diff --git a/libtransmission/torrent.cc b/libtransmission/torrent.cc index ad9595e42..6c25db795 100644 --- a/libtransmission/torrent.cc +++ b/libtransmission/torrent.cc @@ -632,6 +632,29 @@ static void callScriptIfEnabled(tr_torrent const* tor, TrScript type) static void refreshCurrentDir(tr_torrent* tor); +static void migrateFile( + tr_torrent const* tor, + tr_magnet_metainfo::BasenameFormat old_format, + tr_magnet_metainfo::BasenameFormat new_format) +{ + auto const torrent_dir = tor->session->torrent_dir; + auto const& name = tor->name(); + auto const& hash_string = tor->infoHashString(); + auto const suffix = "torrent"sv; + + auto const old_filename = tr_magnet_metainfo::makeFilename(torrent_dir, name, hash_string, old_format, suffix); + auto const new_filename = tr_magnet_metainfo::makeFilename(torrent_dir, name, hash_string, new_format, suffix); + + if (tr_sys_path_rename(old_filename.c_str(), new_filename.c_str(), nullptr)) + { + tr_logAddNamedError( + tor->name().c_str(), + "Migrated torrent file from \"%s\" to \"%s\"", + old_filename.c_str(), + new_filename.c_str()); + } +} + static void torrentInit(tr_torrent* tor, tr_ctor const* ctor) { static auto next_unique_id = int{ 1 }; @@ -689,7 +712,7 @@ static void torrentInit(tr_torrent* tor, tr_ctor const* ctor) if (didRenameResumeFileToHashOnlyName) { /* Rename torrent file as well */ - tr_metainfoMigrateFile(session, &tor->info, TR_METAINFO_BASENAME_NAME_AND_PARTIAL_HASH, TR_METAINFO_BASENAME_HASH); + migrateFile(tor, tr_magnet_metainfo::BasenameFormat::NameAndPartialHash, tr_magnet_metainfo::BasenameFormat::Hash); } tor->completeness = tor->completion.status(); @@ -1160,15 +1183,15 @@ tr_torrent_view tr_torrentView(tr_torrent const* tor) ret.name = tr_torrentName(tor); ret.hash_string = tor->infoHashString().c_str(); ret.torrent_filename = tor->torrentFile().c_str(); - ret.comment = tor->info.comment().c_str(); - ret.creator = tor->info.creator().c_str(); - ret.source = tor->info.source().c_str(); + ret.comment = tor->comment().c_str(); + ret.creator = tor->creator().c_str(); + ret.source = tor->source().c_str(); ret.total_size = tor->totalSize(); ret.date_created = tor->dateCreated(); ret.piece_size = tor->pieceSize(); ret.n_pieces = tor->pieceCount(); ret.is_private = tor->isPrivate(); - ret.is_folder = tor->info.isFolder; + ret.is_folder = tor->fileCount() > 1; return ret; } @@ -1550,7 +1573,7 @@ static void closeTorrent(void* vtor) if (tor->isDeleting) { - tr_metainfoRemoveSaved(tor->session, &tor->info); + tr_sys_path_remove(tor->torrentFile().c_str(), nullptr); tr_torrentRemoveResume(tor); }