Allow wildcards in file names to search for images, fixes #697
This commit is contained in:
+3
-3
@@ -99,14 +99,14 @@ cover-max-cache-size = 30;
|
|||||||
# JPEG quality for covers (range is 1-100)
|
# JPEG quality for covers (range is 1-100)
|
||||||
cover-jpeg-quality = 75;
|
cover-jpeg-quality = 75;
|
||||||
|
|
||||||
# Preferred file names for covers (order is important)
|
# Preferred file names for covers (order is important, accept wildcards)
|
||||||
cover-preferred-file-names = ("cover", "front", "folder", "default");
|
cover-preferred-file-names = ("cover", "front", "folder", "default");
|
||||||
|
|
||||||
# File names for artist images (order is important)
|
# File names for artist images (order is important, accept wildcards)
|
||||||
# Note: files whose name is the artist's MBID are always searched before the names in this list. You can place the MBID files anywhere in your libraries.
|
# Note: files whose name is the artist's MBID are always searched before the names in this list. You can place the MBID files anywhere in your libraries.
|
||||||
artist-image-file-names = ("artist");
|
artist-image-file-names = ("artist");
|
||||||
|
|
||||||
# File names for medium images (order is important)
|
# File names for medium images (order is important, accept wildcards)
|
||||||
# Note: files named after the disc itself are always searched before the names in this list.
|
# Note: files named after the disc itself are always searched before the names in this list.
|
||||||
medium-image-file-names = ("discsubtitle");
|
medium-image-file-names = ("discsubtitle");
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
namespace lms::db::utils
|
namespace lms::db::utils
|
||||||
{
|
{
|
||||||
std::string escapeLikeKeyword(std::string_view keyword)
|
std::string escapeForLikeKeyword(std::string_view keyword)
|
||||||
{
|
{
|
||||||
return core::stringUtils::escapeString(keyword, "%_", escapeChar);
|
return core::stringUtils::escapeString(keyword, "%_", escapeChar);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ namespace lms::db::utils
|
|||||||
{
|
{
|
||||||
#define ESCAPE_CHAR_STR "\\"
|
#define ESCAPE_CHAR_STR "\\"
|
||||||
static inline constexpr char escapeChar{ '\\' };
|
static inline constexpr char escapeChar{ '\\' };
|
||||||
std::string escapeLikeKeyword(std::string_view keywords);
|
std::string escapeForLikeKeyword(std::string_view keywords);
|
||||||
|
|
||||||
Wt::WDateTime normalizeDateTime(const Wt::WDateTime& dateTime);
|
Wt::WDateTime normalizeDateTime(const Wt::WDateTime& dateTime);
|
||||||
|
|
||||||
|
|||||||
@@ -106,13 +106,13 @@ namespace lms::db
|
|||||||
for (const std::string_view keyword : params.keywords)
|
for (const std::string_view keyword : params.keywords)
|
||||||
{
|
{
|
||||||
clauses.push_back("a.name LIKE ? ESCAPE '" ESCAPE_CHAR_STR "'");
|
clauses.push_back("a.name LIKE ? ESCAPE '" ESCAPE_CHAR_STR "'");
|
||||||
query.bind("%" + utils::escapeLikeKeyword(keyword) + "%");
|
query.bind("%" + utils::escapeForLikeKeyword(keyword) + "%");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const std::string_view keyword : params.keywords)
|
for (const std::string_view keyword : params.keywords)
|
||||||
{
|
{
|
||||||
sortClauses.push_back("a.sort_name LIKE ? ESCAPE '" ESCAPE_CHAR_STR "'");
|
sortClauses.push_back("a.sort_name LIKE ? ESCAPE '" ESCAPE_CHAR_STR "'");
|
||||||
query.bind("%" + utils::escapeLikeKeyword(keyword) + "%");
|
query.bind("%" + utils::escapeForLikeKeyword(keyword) + "%");
|
||||||
}
|
}
|
||||||
|
|
||||||
query.where("(" + core::stringUtils::joinStrings(clauses, " AND ") + ") OR (" + core::stringUtils::joinStrings(sortClauses, " AND ") + ")");
|
query.where("(" + core::stringUtils::joinStrings(clauses, " AND ") + ") OR (" + core::stringUtils::joinStrings(sortClauses, " AND ") + ")");
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ namespace lms::db
|
|||||||
auto query{ session.getDboSession()->query<Wt::Dbo::ptr<Directory>>("SELECT d FROM directory d") };
|
auto query{ session.getDboSession()->query<Wt::Dbo::ptr<Directory>>("SELECT d FROM directory d") };
|
||||||
|
|
||||||
for (std::string_view keyword : params.keywords)
|
for (std::string_view keyword : params.keywords)
|
||||||
query.where("d.name LIKE ? ESCAPE '" ESCAPE_CHAR_STR "'").bind("%" + utils::escapeLikeKeyword(keyword) + "%");
|
query.where("d.name LIKE ? ESCAPE '" ESCAPE_CHAR_STR "'").bind("%" + utils::escapeForLikeKeyword(keyword) + "%");
|
||||||
|
|
||||||
if (params.artist.isValid()
|
if (params.artist.isValid()
|
||||||
|| params.release.isValid()
|
|| params.release.isValid()
|
||||||
|
|||||||
@@ -43,7 +43,20 @@ namespace lms::db
|
|||||||
if (params.directory.isValid())
|
if (params.directory.isValid())
|
||||||
query.where("i.directory_id = ?").bind(params.directory);
|
query.where("i.directory_id = ?").bind(params.directory);
|
||||||
if (!params.fileStem.empty())
|
if (!params.fileStem.empty())
|
||||||
query.where("i.stem = ? COLLATE NOCASE").bind(params.fileStem);
|
{
|
||||||
|
// if contains a wildcard, replace by % for LIKE
|
||||||
|
if (params.processWildcardsInFileStem.value() && params.fileStem.find('*') != std::string::npos)
|
||||||
|
{
|
||||||
|
std::string fileStem{ params.fileStem };
|
||||||
|
utils::escapeForLikeKeyword(fileStem);
|
||||||
|
std::replace(std::begin(fileStem), std::end(fileStem), '*', '%');
|
||||||
|
query.where("i.stem LIKE ? COLLATE NOCASE ESCAPE '" ESCAPE_CHAR_STR "'").bind(fileStem);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
query.where("i.stem = ? COLLATE NOCASE").bind(params.fileStem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -100,13 +100,13 @@ namespace lms::db
|
|||||||
for (const std::string_view keyword : params.keywords)
|
for (const std::string_view keyword : params.keywords)
|
||||||
{
|
{
|
||||||
clauses.push_back("a.name LIKE ? ESCAPE '" ESCAPE_CHAR_STR "'");
|
clauses.push_back("a.name LIKE ? ESCAPE '" ESCAPE_CHAR_STR "'");
|
||||||
query.bind("%" + utils::escapeLikeKeyword(keyword) + "%");
|
query.bind("%" + utils::escapeForLikeKeyword(keyword) + "%");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const std::string_view keyword : params.keywords)
|
for (const std::string_view keyword : params.keywords)
|
||||||
{
|
{
|
||||||
sortClauses.push_back("a.sort_name LIKE ? ESCAPE '" ESCAPE_CHAR_STR "'");
|
sortClauses.push_back("a.sort_name LIKE ? ESCAPE '" ESCAPE_CHAR_STR "'");
|
||||||
query.bind("%" + utils::escapeLikeKeyword(keyword) + "%");
|
query.bind("%" + utils::escapeForLikeKeyword(keyword) + "%");
|
||||||
}
|
}
|
||||||
|
|
||||||
query.where("(" + core::stringUtils::joinStrings(clauses, " AND ") + ") OR (" + core::stringUtils::joinStrings(sortClauses, " AND ") + ")");
|
query.where("(" + core::stringUtils::joinStrings(clauses, " AND ") + ") OR (" + core::stringUtils::joinStrings(sortClauses, " AND ") + ")");
|
||||||
@@ -169,7 +169,7 @@ namespace lms::db
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (std::string_view keyword : params.keywords)
|
for (std::string_view keyword : params.keywords)
|
||||||
query.where("r.name LIKE ? ESCAPE '" ESCAPE_CHAR_STR "'").bind("%" + utils::escapeLikeKeyword(keyword) + "%");
|
query.where("r.name LIKE ? ESCAPE '" ESCAPE_CHAR_STR "'").bind("%" + utils::escapeForLikeKeyword(keyword) + "%");
|
||||||
|
|
||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
@@ -227,7 +227,7 @@ namespace lms::db
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (std::string_view keyword : params.keywords)
|
for (std::string_view keyword : params.keywords)
|
||||||
query.where("t.name LIKE ? ESCAPE '" ESCAPE_CHAR_STR "'").bind("%" + utils::escapeLikeKeyword(keyword) + "%");
|
query.where("t.name LIKE ? ESCAPE '" ESCAPE_CHAR_STR "'").bind("%" + utils::escapeForLikeKeyword(keyword) + "%");
|
||||||
|
|
||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ namespace lms::db
|
|||||||
query.where("r.name = ?").bind(params.name);
|
query.where("r.name = ?").bind(params.name);
|
||||||
|
|
||||||
for (std::string_view keyword : params.keywords)
|
for (std::string_view keyword : params.keywords)
|
||||||
query.where("r.name LIKE ? ESCAPE '" ESCAPE_CHAR_STR "'").bind("%" + utils::escapeLikeKeyword(keyword) + "%");
|
query.where("r.name LIKE ? ESCAPE '" ESCAPE_CHAR_STR "'").bind("%" + utils::escapeForLikeKeyword(keyword) + "%");
|
||||||
|
|
||||||
if (params.starringUser.isValid())
|
if (params.starringUser.isValid())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ namespace lms::db
|
|||||||
|
|
||||||
assert(params.keywords.empty() || params.name.empty());
|
assert(params.keywords.empty() || params.name.empty());
|
||||||
for (std::string_view keyword : params.keywords)
|
for (std::string_view keyword : params.keywords)
|
||||||
query.where("t.name LIKE ? ESCAPE '" ESCAPE_CHAR_STR "'").bind("%" + utils::escapeLikeKeyword(keyword) + "%");
|
query.where("t.name LIKE ? ESCAPE '" ESCAPE_CHAR_STR "'").bind("%" + utils::escapeForLikeKeyword(keyword) + "%");
|
||||||
|
|
||||||
if (!params.name.empty())
|
if (!params.name.empty())
|
||||||
query.where("t.name = ?").bind(params.name);
|
query.where("t.name = ?").bind(params.name);
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ namespace lms::db
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (std::string_view keyword : params.keywords)
|
for (std::string_view keyword : params.keywords)
|
||||||
query.where("t_l.name LIKE ? ESCAPE '" ESCAPE_CHAR_STR "'").bind("%" + utils::escapeLikeKeyword(keyword) + "%");
|
query.where("t_l.name LIKE ? ESCAPE '" ESCAPE_CHAR_STR "'").bind("%" + utils::escapeForLikeKeyword(keyword) + "%");
|
||||||
|
|
||||||
if (params.filters.mediaLibrary.isValid()
|
if (params.filters.mediaLibrary.isValid()
|
||||||
|| params.filters.label.isValid()
|
|| params.filters.label.isValid()
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ namespace lms::db
|
|||||||
static pointer find(Session& session, const std::filesystem::path& path);
|
static pointer find(Session& session, const std::filesystem::path& path);
|
||||||
static void find(Session& session, DirectoryId& lastRetrievedDirectory, std::size_t count, const std::function<void(const Directory::pointer&)>& func);
|
static void find(Session& session, DirectoryId& lastRetrievedDirectory, std::size_t count, const std::function<void(const Directory::pointer&)>& func);
|
||||||
static RangeResults<Directory::pointer> find(Session& session, const FindParameters& params);
|
static RangeResults<Directory::pointer> find(Session& session, const FindParameters& params);
|
||||||
static void find(Session& session, const FindParameters& parameters, const std::function<void(const Directory::pointer&)>& func);
|
static void find(Session& session, const FindParameters& params, const std::function<void(const Directory::pointer&)>& func);
|
||||||
static RangeResults<DirectoryId> findOrphanIds(Session& session, std::optional<Range> range = std::nullopt);
|
static RangeResults<DirectoryId> findOrphanIds(Session& session, std::optional<Range> range = std::nullopt);
|
||||||
static RangeResults<DirectoryId> findMismatchedLibrary(Session& session, std::optional<Range> range, const std::filesystem::path& rootPath, MediaLibraryId expectedLibraryId);
|
static RangeResults<DirectoryId> findMismatchedLibrary(Session& session, std::optional<Range> range, const std::filesystem::path& rootPath, MediaLibraryId expectedLibraryId);
|
||||||
static RangeResults<pointer> findRootDirectories(Session& session, std::optional<Range> range = std::nullopt);
|
static RangeResults<pointer> findRootDirectories(Session& session, std::optional<Range> range = std::nullopt);
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
#include <Wt/Dbo/Field.h>
|
#include <Wt/Dbo/Field.h>
|
||||||
#include <Wt/WDateTime.h>
|
#include <Wt/WDateTime.h>
|
||||||
|
|
||||||
|
#include "core/TaggedType.hpp"
|
||||||
#include "database/Object.hpp"
|
#include "database/Object.hpp"
|
||||||
#include "database/Types.hpp"
|
#include "database/Types.hpp"
|
||||||
#include "database/objects/DirectoryId.hpp"
|
#include "database/objects/DirectoryId.hpp"
|
||||||
@@ -43,18 +44,22 @@ namespace lms::db
|
|||||||
|
|
||||||
struct FindParameters
|
struct FindParameters
|
||||||
{
|
{
|
||||||
|
using ProcessWildcards = core::TaggedBool<class FindParametersProcessWildcardsTag>;
|
||||||
|
|
||||||
std::optional<Range> range;
|
std::optional<Range> range;
|
||||||
std::string fileStem; // if set, images with this file stem
|
std::string fileStem; // if set, images with this file stem
|
||||||
DirectoryId directory; // if set, images in this directory
|
ProcessWildcards processWildcardsInFileStem{ false }; // if true, replace '*' by '%' for SQL LIKE
|
||||||
|
DirectoryId directory; // if set, images in this directory
|
||||||
|
|
||||||
FindParameters& setRange(std::optional<Range> _range)
|
FindParameters& setRange(std::optional<Range> _range)
|
||||||
{
|
{
|
||||||
range = _range;
|
range = _range;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
FindParameters& setFileStem(std::string_view _fileStem)
|
FindParameters& setFileStem(std::string_view _fileStem, ProcessWildcards processWildcards = ProcessWildcards{ false })
|
||||||
{
|
{
|
||||||
fileStem = _fileStem;
|
fileStem = _fileStem;
|
||||||
|
processWildcardsInFileStem = processWildcards;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
FindParameters& setDirectory(DirectoryId _directory)
|
FindParameters& setDirectory(DirectoryId _directory)
|
||||||
|
|||||||
@@ -122,4 +122,102 @@ namespace lms::db::tests
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(DatabaseFixture, Image_findByFileStem)
|
||||||
|
{
|
||||||
|
ScopedDirectory directory{ session, "/path/to" };
|
||||||
|
ScopedImage image{ session, "/path/to/image" };
|
||||||
|
|
||||||
|
const std::string fileStem{ "image" };
|
||||||
|
{
|
||||||
|
auto transaction{ session.createWriteTransaction() };
|
||||||
|
image.get().modify()->setDirectory(directory.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto transaction{ session.createReadTransaction() };
|
||||||
|
Image::FindParameters params;
|
||||||
|
params.setFileStem(fileStem);
|
||||||
|
const auto results{ Image::find(session, params) };
|
||||||
|
ASSERT_EQ(results.results.size(), 1);
|
||||||
|
EXPECT_EQ(results.results[0]->getId(), image.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto transaction{ session.createReadTransaction() };
|
||||||
|
Image::FindParameters params;
|
||||||
|
params.setFileStem(fileStem, Image::FindParameters::ProcessWildcards{ true });
|
||||||
|
const auto results{ Image::find(session, params) };
|
||||||
|
ASSERT_EQ(results.results.size(), 1);
|
||||||
|
EXPECT_EQ(results.results[0]->getId(), image.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto transaction{ session.createReadTransaction() };
|
||||||
|
Image::FindParameters params;
|
||||||
|
params.setFileStem("nonexistent");
|
||||||
|
const auto results{ Image::find(session, params) };
|
||||||
|
EXPECT_EQ(results.results.size(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto transaction{ session.createReadTransaction() };
|
||||||
|
Image::FindParameters params;
|
||||||
|
params.setFileStem("ima*");
|
||||||
|
const auto results{ Image::find(session, params) };
|
||||||
|
ASSERT_EQ(results.results.size(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto transaction{ session.createReadTransaction() };
|
||||||
|
Image::FindParameters params;
|
||||||
|
params.setFileStem("ima*", Image::FindParameters::ProcessWildcards{ true });
|
||||||
|
const auto results{ Image::find(session, params) };
|
||||||
|
ASSERT_EQ(results.results.size(), 1);
|
||||||
|
EXPECT_EQ(results.results[0]->getId(), image.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto transaction{ session.createReadTransaction() };
|
||||||
|
Image::FindParameters params;
|
||||||
|
params.setFileStem("*ge", Image::FindParameters::ProcessWildcards{ true });
|
||||||
|
const auto results{ Image::find(session, params) };
|
||||||
|
ASSERT_EQ(results.results.size(), 1);
|
||||||
|
EXPECT_EQ(results.results[0]->getId(), image.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto transaction{ session.createReadTransaction() };
|
||||||
|
Image::FindParameters params;
|
||||||
|
params.setFileStem("*g*", Image::FindParameters::ProcessWildcards{ true });
|
||||||
|
const auto results{ Image::find(session, params) };
|
||||||
|
ASSERT_EQ(results.results.size(), 1);
|
||||||
|
EXPECT_EQ(results.results[0]->getId(), image.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto transaction{ session.createReadTransaction() };
|
||||||
|
Image::FindParameters params;
|
||||||
|
params.setFileStem("*", Image::FindParameters::ProcessWildcards{ true });
|
||||||
|
const auto results{ Image::find(session, params) };
|
||||||
|
ASSERT_EQ(results.results.size(), 1);
|
||||||
|
EXPECT_EQ(results.results[0]->getId(), image.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto transaction{ session.createReadTransaction() };
|
||||||
|
Image::FindParameters params;
|
||||||
|
params.setFileStem("ima%");
|
||||||
|
const auto results{ Image::find(session, params) };
|
||||||
|
ASSERT_EQ(results.results.size(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto transaction{ session.createReadTransaction() };
|
||||||
|
Image::FindParameters params;
|
||||||
|
params.setFileStem("ima%", Image::FindParameters::ProcessWildcards{ true });
|
||||||
|
const auto results{ Image::find(session, params) };
|
||||||
|
ASSERT_EQ(results.results.size(), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace lms::db::tests
|
} // namespace lms::db::tests
|
||||||
@@ -73,7 +73,7 @@ namespace lms::scanner
|
|||||||
{
|
{
|
||||||
db::Image::FindParameters params;
|
db::Image::FindParameters params;
|
||||||
params.setDirectory(directory->getId());
|
params.setDirectory(directory->getId());
|
||||||
params.setFileStem(fileStem); // no need to sanitize here, user is responsible for providing sanitized file stems in conf file
|
params.setFileStem(fileStem, db::Image::FindParameters::ProcessWildcards{ true }); // no need to sanitize here, user is responsible for providing sanitized file stems in conf file
|
||||||
|
|
||||||
db::Image::find(session, params, [&](const db::Image::pointer foundImg) {
|
db::Image::find(session, params, [&](const db::Image::pointer foundImg) {
|
||||||
if (!image)
|
if (!image)
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ namespace lms::scanner
|
|||||||
std::span<const std::string_view> mediumFileNames;
|
std::span<const std::string_view> mediumFileNames;
|
||||||
};
|
};
|
||||||
|
|
||||||
db::Image::pointer findImageInDirectory(db::Session& session, const db::Directory::pointer& directory, std::span<const std::string_view> fileStemsToSearch)
|
db::Image::pointer findImageInDirectory(db::Session& session, const db::Directory::pointer& directory, std::span<const std::string_view> fileStemsToSearch, db::Image::FindParameters::ProcessWildcards processWildcards)
|
||||||
{
|
{
|
||||||
db::Image::pointer image;
|
db::Image::pointer image;
|
||||||
|
|
||||||
@@ -70,7 +70,7 @@ namespace lms::scanner
|
|||||||
{
|
{
|
||||||
db::Image::FindParameters params;
|
db::Image::FindParameters params;
|
||||||
params.setDirectory(directory->getId());
|
params.setDirectory(directory->getId());
|
||||||
params.setFileStem(fileStem);
|
params.setFileStem(fileStem, processWildcards);
|
||||||
|
|
||||||
db::Image::find(session, params, [&](const db::Image::pointer foundImg) {
|
db::Image::find(session, params, [&](const db::Image::pointer foundImg) {
|
||||||
if (!image)
|
if (!image)
|
||||||
@@ -109,11 +109,11 @@ namespace lms::scanner
|
|||||||
if (const std::string mediumName{ core::pathUtils::sanitizeFileStem(medium->getName()) }; !mediumName.empty())
|
if (const std::string mediumName{ core::pathUtils::sanitizeFileStem(medium->getName()) }; !mediumName.empty())
|
||||||
{
|
{
|
||||||
std::string_view mediumNameView{ mediumName };
|
std::string_view mediumNameView{ mediumName };
|
||||||
image = findImageInDirectory(session, directory, std::span{ &mediumNameView, 1 });
|
image = findImageInDirectory(session, directory, std::span{ &mediumNameView, 1 }, db::Image::FindParameters::ProcessWildcards{ false });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!image)
|
if (!image)
|
||||||
image = findImageInDirectory(session, directory, searchParams.mediumFileNames);
|
image = findImageInDirectory(session, directory, searchParams.mediumFileNames, db::Image::FindParameters::ProcessWildcards{ true });
|
||||||
});
|
});
|
||||||
|
|
||||||
return image;
|
return image;
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ namespace lms::scanner
|
|||||||
{
|
{
|
||||||
db::Image::FindParameters params;
|
db::Image::FindParameters params;
|
||||||
params.setDirectory(directory->getId());
|
params.setDirectory(directory->getId());
|
||||||
params.setFileStem(fileStem);
|
params.setFileStem(fileStem, db::Image::FindParameters::ProcessWildcards{ true }); // no need to sanitize here, user is responsible for providing sanitized file stems in conf file
|
||||||
|
|
||||||
db::Image::find(session, params, [&](const db::Image::pointer& image) {
|
db::Image::find(session, params, [&](const db::Image::pointer& image) {
|
||||||
if (!artwork)
|
if (!artwork)
|
||||||
|
|||||||
Reference in New Issue
Block a user