diff --git a/.gitattributes b/.gitattributes index af0322240..67a86deae 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,5 +1,5 @@ # libtransmission -libtransmission/mime-types.h linguist-generated=true +lib/base/mime-types.h linguist-generated=true # web web/package.json.buildonly linguist-generated=true diff --git a/gtk/FileList.cc b/gtk/FileList.cc index 1201d3408..305eeddf2 100644 --- a/gtk/FileList.cc +++ b/gtk/FileList.cc @@ -12,10 +12,8 @@ #include "Session.h" #include "Utils.h" -#include - -#include "lib/base/string-utils.h" #include +#include #include #include diff --git a/gtk/Torrent.cc b/gtk/Torrent.cc index 0236aeedd..003cdc0c0 100644 --- a/gtk/Torrent.cc +++ b/gtk/Torrent.cc @@ -13,6 +13,7 @@ #include #include +#include "lib/base/file-utils.h" #include "lib/base/tr-macros.h" #include "lib/base/values.h" diff --git a/lib/base/CMakeLists.txt b/lib/base/CMakeLists.txt index e044bab42..59d1a8d3c 100644 --- a/lib/base/CMakeLists.txt +++ b/lib/base/CMakeLists.txt @@ -21,6 +21,7 @@ target_sources(trbase i18n.h log.cc log.h + mime-types.h quark.cc quark.h serializer.cc diff --git a/lib/base/file-utils.cc b/lib/base/file-utils.cc index fc3af78c3..20f9ec4cd 100644 --- a/lib/base/file-utils.cc +++ b/lib/base/file-utils.cc @@ -6,6 +6,9 @@ #include #include +#include +#include + #ifndef _WIN32 #include /* umask() */ #endif @@ -18,6 +21,8 @@ #include "lib/base/file.h" #include "lib/base/i18n.h" #include "lib/base/log.h" +#include "lib/base/mime-types.h" +#include "lib/base/string-utils.h" #include "lib/base/tr-strbuf.h" using namespace std::literals; @@ -197,3 +202,40 @@ bool tr_file_move(std::string_view oldpath, std::string_view newpath, bool allow return true; } + +// --- mime-type + +std::string_view tr_get_mime_type_for_filename(std::string_view filename) +{ + auto constexpr Compare = [](mime_type_suffix const& entry, auto const& suffix) + { + return entry.suffix < suffix; + }; + + if (auto const pos = filename.rfind('.'); pos != std::string_view::npos) + { + auto const suffix_lc = tr_strlower(filename.substr(pos + 1)); + auto const it = std::lower_bound(std::begin(MimeTypeSuffixes), std::end(MimeTypeSuffixes), suffix_lc, Compare); + if (it != std::end(MimeTypeSuffixes) && suffix_lc == it->suffix) + { + std::string_view mime_type = it->mime_type; + + // https://github.com/transmission/transmission/issues/5965#issuecomment-1704421231 + // An mp4 file's correct mime-type depends on the codecs used in the file, + // which we have no way of inspecting and which might not be downloaded yet. + // Let's use `video/mp4` since that's by far the most common use case for torrents. + if (mime_type == "application/mp4") + { + mime_type = "video/mp4"; + } + + return mime_type; + } + } + + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types + // application/octet-stream is the default value. + // An unknown file type should use this type. + auto constexpr Fallback = "application/octet-stream"sv; + return Fallback; +} diff --git a/lib/base/file-utils.h b/lib/base/file-utils.h index f39c31ef8..03d7f0319 100644 --- a/lib/base/file-utils.h +++ b/lib/base/file-utils.h @@ -18,6 +18,8 @@ struct tr_error; bool tr_file_read(std::string_view filename, std::vector& contents, tr_error* error = nullptr); +[[nodiscard]] std::string_view tr_get_mime_type_for_filename(std::string_view filename); + /** * Tries to move a file by renaming, and [optionally] if that fails, by copying. * diff --git a/libtransmission/mime-types.h b/lib/base/mime-types.h similarity index 99% rename from libtransmission/mime-types.h rename to lib/base/mime-types.h index 4200c6bb1..cde357ea7 100644 --- a/libtransmission/mime-types.h +++ b/lib/base/mime-types.h @@ -1,4 +1,4 @@ -// This file was generated with libtransmission/mime-types.js +// This file was generated with lib/base/mime-types.js // DO NOT EDIT MANUALLY // This file Copyright © Mnemosyne LLC. diff --git a/libtransmission/mime-types.js b/lib/base/mime-types.js similarity index 97% rename from libtransmission/mime-types.js rename to lib/base/mime-types.js index 50bf619b5..88d5e3edd 100755 --- a/libtransmission/mime-types.js +++ b/lib/base/mime-types.js @@ -2,7 +2,7 @@ import fs from 'node:fs'; const copyright = - `// This file was generated with libtransmission/mime-types.js + `// This file was generated with lib/base/mime-types.js // DO NOT EDIT MANUALLY // This file Copyright © Mnemosyne LLC. diff --git a/libtransmission/CMakeLists.txt b/libtransmission/CMakeLists.txt index 087f0f8ec..9f225e82f 100644 --- a/libtransmission/CMakeLists.txt +++ b/libtransmission/CMakeLists.txt @@ -62,7 +62,6 @@ target_sources(${TR_NAME} magnet-metainfo.h makemeta.cc makemeta.h - mime-types.h net.cc net.h open-files.cc diff --git a/libtransmission/torrent-files.cc b/libtransmission/torrent-files.cc index 262f08d67..1248d7215 100644 --- a/libtransmission/torrent-files.cc +++ b/libtransmission/torrent-files.cc @@ -30,7 +30,6 @@ #include "libtransmission/torrent-files.h" #include "libtransmission/types.h" -#include "libtransmission/utils.h" using namespace std::literals; diff --git a/libtransmission/utils.cc b/libtransmission/utils.cc index 4fd98e045..71d6034ba 100644 --- a/libtransmission/utils.cc +++ b/libtransmission/utils.cc @@ -44,7 +44,6 @@ #include "lib/base/tr-strbuf.h" #include "lib/base/values.h" -#include "libtransmission/mime-types.h" #include "libtransmission/types.h" #include "libtransmission/utils.h" @@ -435,40 +434,3 @@ void tr_lib_init() tr::serializer::install_libtransmission_converters(); }); } - -// --- mime-type - -std::string_view tr_get_mime_type_for_filename(std::string_view filename) -{ - auto constexpr Compare = [](mime_type_suffix const& entry, auto const& suffix) - { - return entry.suffix < suffix; - }; - - if (auto const pos = filename.rfind('.'); pos != std::string_view::npos) - { - auto const suffix_lc = tr_strlower(filename.substr(pos + 1)); - auto const it = std::lower_bound(std::begin(MimeTypeSuffixes), std::end(MimeTypeSuffixes), suffix_lc, Compare); - if (it != std::end(MimeTypeSuffixes) && suffix_lc == it->suffix) - { - std::string_view mime_type = it->mime_type; - - // https://github.com/transmission/transmission/issues/5965#issuecomment-1704421231 - // An mp4 file's correct mime-type depends on the codecs used in the file, - // which we have no way of inspecting and which might not be downloaded yet. - // Let's use `video/mp4` since that's by far the most common use case for torrents. - if (mime_type == "application/mp4") - { - mime_type = "video/mp4"; - } - - return mime_type; - } - } - - // https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types - // application/octet-stream is the default value. - // An unknown file type should use this type. - auto constexpr Fallback = "application/octet-stream"sv; - return Fallback; -} diff --git a/libtransmission/utils.h b/libtransmission/utils.h index 4f0a1da54..8a85fd2fa 100644 --- a/libtransmission/utils.h +++ b/libtransmission/utils.h @@ -25,8 +25,6 @@ std::optional tr_locale_set_global(std::locale const& locale) noexc // --- -[[nodiscard]] std::string_view tr_get_mime_type_for_filename(std::string_view filename); - /** @brief return the current date in milliseconds */ [[nodiscard]] uint64_t tr_time_msec(); diff --git a/tests/libtransmission/utils-test.cc b/tests/libtransmission/utils-test.cc index fee030b63..7ebf4ae88 100644 --- a/tests/libtransmission/utils-test.cc +++ b/tests/libtransmission/utils-test.cc @@ -17,6 +17,7 @@ #include #include "lib/base/env.h" +#include "lib/base/file-utils.h" #include "libtransmission/transmission.h" #include "libtransmission/utils.h"