mirror of
https://github.com/transmission/transmission
synced 2024-12-23 00:04:06 +00:00
refactor: use tr_web instead of curl in transmission-show (#4281)
This commit is contained in:
parent
595d0ac14a
commit
a0b5623769
1 changed files with 25 additions and 46 deletions
|
@ -5,14 +5,13 @@
|
|||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <condition_variable>
|
||||
#include <ctime>
|
||||
#include <chrono>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include <event2/buffer.h>
|
||||
|
||||
#include <fmt/chrono.h>
|
||||
#include <fmt/core.h>
|
||||
#include <fmt/format.h>
|
||||
|
@ -28,6 +27,7 @@
|
|||
#include <libtransmission/utils.h>
|
||||
#include <libtransmission/variant.h>
|
||||
#include <libtransmission/version.h>
|
||||
#include <libtransmission/web.h>
|
||||
#include <libtransmission/web-utils.h>
|
||||
|
||||
#include "units.h"
|
||||
|
@ -37,11 +37,10 @@ using namespace std::literals;
|
|||
namespace
|
||||
{
|
||||
|
||||
auto constexpr TimeoutSecs = long{ 30 };
|
||||
auto constexpr TimeoutSecs = std::chrono::seconds{ 30 };
|
||||
|
||||
char constexpr MyName[] = "transmission-show";
|
||||
char constexpr Usage[] = "Usage: transmission-show [options] <torrent-file>";
|
||||
char constexpr UserAgent[] = "transmission-show/" LONG_VERSION_STRING;
|
||||
|
||||
auto options = std::array<tr_option, 14>{
|
||||
{ { 'd', "header", "Show only header section", "d", false, nullptr },
|
||||
|
@ -304,30 +303,10 @@ void showInfo(app_opts const& opts, tr_torrent_metainfo const& metainfo)
|
|||
}
|
||||
}
|
||||
|
||||
size_t writeFunc(void* ptr, size_t size, size_t nmemb, void* vbuf)
|
||||
{
|
||||
auto* buf = static_cast<evbuffer*>(vbuf);
|
||||
size_t const byteCount = size * nmemb;
|
||||
evbuffer_add(buf, ptr, byteCount);
|
||||
return byteCount;
|
||||
}
|
||||
|
||||
CURL* tr_curl_easy_init(struct evbuffer* writebuf)
|
||||
{
|
||||
CURL* curl = curl_easy_init();
|
||||
(void)curl_easy_setopt(curl, CURLOPT_USERAGENT, UserAgent);
|
||||
(void)curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeFunc);
|
||||
(void)curl_easy_setopt(curl, CURLOPT_WRITEDATA, writebuf);
|
||||
(void)curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
|
||||
(void)curl_easy_setopt(curl, CURLOPT_VERBOSE, tr_env_key_exists("TR_CURL_VERBOSE"));
|
||||
(void)curl_easy_setopt(curl, CURLOPT_ENCODING, "");
|
||||
return curl;
|
||||
}
|
||||
|
||||
void doScrape(tr_torrent_metainfo const& metainfo)
|
||||
{
|
||||
auto* const buf = evbuffer_new();
|
||||
auto* const curl = tr_curl_easy_init(buf);
|
||||
auto mediator = tr_web::Mediator{};
|
||||
auto web = tr_web::create(mediator);
|
||||
|
||||
for (auto const& tracker : metainfo.announceList())
|
||||
{
|
||||
|
@ -345,28 +324,30 @@ void doScrape(tr_torrent_metainfo const& metainfo)
|
|||
fflush(stdout);
|
||||
|
||||
// execute the http scrape
|
||||
(void)curl_easy_setopt(curl, CURLOPT_URL, scrape_url.c_str());
|
||||
(void)curl_easy_setopt(curl, CURLOPT_TIMEOUT, TimeoutSecs);
|
||||
if (auto const res = curl_easy_perform(curl); res != CURLE_OK)
|
||||
{
|
||||
fmt::print("error: {:s}\n", curl_easy_strerror(res));
|
||||
continue;
|
||||
}
|
||||
auto response = tr_web::FetchResponse{};
|
||||
auto response_mutex = std::mutex{};
|
||||
auto response_cv = std::condition_variable{};
|
||||
auto lock = std::unique_lock(response_mutex);
|
||||
web->fetch({ scrape_url,
|
||||
[&response, &response_cv](tr_web::FetchResponse const& resp)
|
||||
{
|
||||
response = resp;
|
||||
response_cv.notify_one();
|
||||
},
|
||||
nullptr,
|
||||
TimeoutSecs });
|
||||
response_cv.wait(lock);
|
||||
|
||||
// check the response code
|
||||
long response;
|
||||
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response);
|
||||
if (response != 200 /*HTTP OK*/)
|
||||
if (auto const code = response.status; code != 200 /*HTTP OK*/)
|
||||
{
|
||||
fmt::print("error: unexpected response {:d} '{:s}'\n", response, tr_webGetResponseStr(response));
|
||||
fmt::print("error: unexpected response {:d} '{:s}'\n", code, tr_webGetResponseStr(code));
|
||||
continue;
|
||||
}
|
||||
|
||||
// print it out
|
||||
tr_variant top;
|
||||
auto* const begin = (char const*)evbuffer_pullup(buf, -1);
|
||||
if (auto sv = std::string_view{ begin, evbuffer_get_length(buf) };
|
||||
!tr_variantFromBuf(&top, TR_VARIANT_PARSE_BENC | TR_VARIANT_PARSE_INPLACE, sv))
|
||||
auto top = tr_variant{};
|
||||
if (!tr_variantFromBuf(&top, TR_VARIANT_PARSE_BENC | TR_VARIANT_PARSE_INPLACE, response.body))
|
||||
{
|
||||
fmt::print("error parsing scrape response\n");
|
||||
continue;
|
||||
|
@ -404,15 +385,13 @@ void doScrape(tr_torrent_metainfo const& metainfo)
|
|||
fmt::print("no match\n");
|
||||
}
|
||||
}
|
||||
|
||||
curl_easy_cleanup(curl);
|
||||
evbuffer_free(buf);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int tr_main(int argc, char* argv[])
|
||||
{
|
||||
tr_logSetQueueEnabled(false);
|
||||
tr_logSetLevel(TR_LOG_ERROR);
|
||||
tr_formatter_mem_init(MemK, MemKStr, MemMStr, MemGStr, MemTStr);
|
||||
tr_formatter_size_init(DiskK, DiskKStr, DiskMStr, DiskGStr, DiskTStr);
|
||||
|
|
Loading…
Reference in a new issue