2022-01-20 18:27:56 +00:00
|
|
|
// This file Copyright © 2021-2022 Mnemosyne LLC.
|
|
|
|
// It may be used under GPLv2 (SPDX: GPL-2.0), GPLv3 (SPDX: GPL-3.0),
|
|
|
|
// or any future license endorsed by Mnemosyne LLC.
|
|
|
|
// License text can be found in the licenses/ folder.
|
2021-12-14 20:59:40 +00:00
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <cstddef>
|
|
|
|
#include <optional>
|
|
|
|
#include <set>
|
2022-02-18 17:52:01 +00:00
|
|
|
#include <string>
|
2021-12-14 20:59:40 +00:00
|
|
|
#include <string_view>
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
#include "transmission.h"
|
|
|
|
|
2022-01-13 02:13:58 +00:00
|
|
|
#include "quark.h"
|
2021-12-23 17:16:05 +00:00
|
|
|
#include "interned-string.h"
|
2021-12-14 20:59:40 +00:00
|
|
|
#include "web-utils.h"
|
|
|
|
|
2021-12-15 21:25:42 +00:00
|
|
|
struct tr_error;
|
|
|
|
|
2021-12-14 20:59:40 +00:00
|
|
|
class tr_announce_list
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
struct tracker_info
|
|
|
|
{
|
2022-04-16 20:41:51 +00:00
|
|
|
tr_interned_string announce;
|
|
|
|
tr_interned_string scrape;
|
|
|
|
tr_interned_string host; // 'example.org:80'
|
|
|
|
tr_interned_string sitename; // 'example'
|
2021-12-14 20:59:40 +00:00
|
|
|
tr_tracker_tier_t tier = 0;
|
|
|
|
tr_tracker_id_t id = 0;
|
|
|
|
|
2022-04-16 19:14:18 +00:00
|
|
|
[[nodiscard]] constexpr int compare(tracker_info const& that) const noexcept // <=>
|
2021-12-14 20:59:40 +00:00
|
|
|
{
|
|
|
|
if (this->tier != that.tier)
|
|
|
|
{
|
|
|
|
return this->tier < that.tier ? -1 : 1;
|
|
|
|
}
|
|
|
|
|
2022-04-16 20:41:51 +00:00
|
|
|
if (int const i{ this->announce.compare(that.announce) }; i != 0)
|
2021-12-14 20:59:40 +00:00
|
|
|
{
|
2022-04-16 20:41:51 +00:00
|
|
|
return i;
|
2021-12-14 20:59:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2022-04-16 19:14:18 +00:00
|
|
|
[[nodiscard]] constexpr bool operator<(tracker_info const& that) const noexcept
|
2021-12-14 20:59:40 +00:00
|
|
|
{
|
|
|
|
return compare(that) < 0;
|
|
|
|
}
|
|
|
|
|
2022-04-16 19:14:18 +00:00
|
|
|
[[nodiscard]] constexpr bool operator==(tracker_info const& that) const noexcept
|
2021-12-14 20:59:40 +00:00
|
|
|
{
|
|
|
|
return compare(that) == 0;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
private:
|
|
|
|
using trackers_t = std::vector<tracker_info>;
|
|
|
|
|
|
|
|
public:
|
2022-04-05 03:51:56 +00:00
|
|
|
[[nodiscard]] auto begin() const noexcept
|
2021-12-14 20:59:40 +00:00
|
|
|
{
|
|
|
|
return std::begin(trackers_);
|
|
|
|
}
|
2022-02-18 17:52:01 +00:00
|
|
|
|
2022-04-05 03:51:56 +00:00
|
|
|
[[nodiscard]] auto end() const noexcept
|
2021-12-14 20:59:40 +00:00
|
|
|
{
|
|
|
|
return std::end(trackers_);
|
|
|
|
}
|
2022-02-18 17:52:01 +00:00
|
|
|
|
2022-04-05 03:51:56 +00:00
|
|
|
[[nodiscard]] bool empty() const noexcept
|
2021-12-14 20:59:40 +00:00
|
|
|
{
|
|
|
|
return std::empty(trackers_);
|
|
|
|
}
|
2022-02-18 17:52:01 +00:00
|
|
|
|
2022-04-05 03:51:56 +00:00
|
|
|
[[nodiscard]] size_t size() const noexcept
|
2021-12-14 20:59:40 +00:00
|
|
|
{
|
|
|
|
return std::size(trackers_);
|
|
|
|
}
|
2022-02-18 17:52:01 +00:00
|
|
|
|
|
|
|
[[nodiscard]] tracker_info const& at(size_t i) const
|
2021-12-14 20:59:40 +00:00
|
|
|
{
|
|
|
|
return trackers_.at(i);
|
|
|
|
}
|
|
|
|
|
2022-02-18 17:52:01 +00:00
|
|
|
[[nodiscard]] tr_tracker_tier_t nextTier() const;
|
2021-12-14 20:59:40 +00:00
|
|
|
|
2022-02-21 03:25:49 +00:00
|
|
|
[[nodiscard]] bool operator==(tr_announce_list const& that) const
|
|
|
|
{
|
|
|
|
return trackers_ == that.trackers_;
|
|
|
|
}
|
|
|
|
|
|
|
|
[[nodiscard]] bool operator!=(tr_announce_list const& that) const
|
|
|
|
{
|
|
|
|
return trackers_ != that.trackers_;
|
|
|
|
}
|
|
|
|
|
2022-01-29 21:37:42 +00:00
|
|
|
bool add(std::string_view announce_url_sv)
|
|
|
|
{
|
|
|
|
return add(announce_url_sv, this->nextTier());
|
|
|
|
}
|
|
|
|
|
|
|
|
bool add(std::string_view announce_url_sv, tr_tracker_tier_t tier);
|
2022-02-20 19:00:52 +00:00
|
|
|
void add(tr_announce_list const& that);
|
2021-12-14 20:59:40 +00:00
|
|
|
bool remove(std::string_view announce_url);
|
|
|
|
bool remove(tr_tracker_id_t id);
|
|
|
|
bool replace(tr_tracker_id_t id, std::string_view announce_url_sv);
|
|
|
|
size_t set(char const* const* announce_urls, tr_tracker_tier_t const* tiers, size_t n);
|
|
|
|
void clear()
|
|
|
|
{
|
|
|
|
return trackers_.clear();
|
|
|
|
}
|
|
|
|
|
2022-02-18 17:52:01 +00:00
|
|
|
/**
|
|
|
|
* Populate the announce list from a text string.
|
|
|
|
* - One announce URL per line
|
|
|
|
* - Blank line denotes a new tier
|
|
|
|
*/
|
|
|
|
bool parse(std::string_view text);
|
|
|
|
[[nodiscard]] std::string toString() const;
|
|
|
|
|
2022-03-28 22:13:32 +00:00
|
|
|
bool save(std::string_view torrent_file, tr_error** error = nullptr) const;
|
2021-12-14 20:59:40 +00:00
|
|
|
|
|
|
|
static std::optional<std::string> announceToScrape(std::string_view announce);
|
|
|
|
static tr_quark announceToScrape(tr_quark announce);
|
|
|
|
|
|
|
|
private:
|
2022-02-18 17:52:01 +00:00
|
|
|
[[nodiscard]] tr_tracker_tier_t getTier(tr_tracker_tier_t tier, tr_url_parsed_t const& announce) const;
|
2021-12-14 20:59:40 +00:00
|
|
|
|
|
|
|
bool canAdd(tr_url_parsed_t const& announce);
|
2022-01-23 22:47:41 +00:00
|
|
|
static tr_tracker_id_t nextUniqueId();
|
2021-12-14 20:59:40 +00:00
|
|
|
trackers_t::iterator find(std::string_view announce);
|
|
|
|
trackers_t::iterator find(tr_tracker_id_t id);
|
|
|
|
|
|
|
|
trackers_t trackers_;
|
|
|
|
};
|