mirror of
https://github.com/KingDuckZ/dindexer.git
synced 2025-07-03 14:14:11 +00:00
Allow tagging files by glob
Tagging by ID is still possible using the --ids switch, which takes a comma-separated list of IDs. However only one mode is allowed at time, so either tag by glob OR tag by ID.
This commit is contained in:
parent
67bdabb548
commit
21c5b3efcb
5 changed files with 54 additions and 14 deletions
|
@ -8,11 +8,13 @@ add_executable(${PROJECT_NAME}
|
||||||
|
|
||||||
target_include_directories(${PROJECT_NAME}
|
target_include_directories(${PROJECT_NAME}
|
||||||
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/..
|
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/..
|
||||||
|
PRIVATE ${CMAKE_SOURCE_DIR}/lib/glob2regex/include
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(${PROJECT_NAME}
|
target_link_libraries(${PROJECT_NAME}
|
||||||
PRIVATE ${bare_name}-if
|
PRIVATE ${bare_name}-if
|
||||||
PRIVATE ${bare_name}-common
|
PRIVATE ${bare_name}-common
|
||||||
|
PRIVATE glob2regex
|
||||||
)
|
)
|
||||||
|
|
||||||
string(REPLACE "${bare_name}-" "" ACTION_NAME "${PROJECT_NAME}")
|
string(REPLACE "${bare_name}-" "" ACTION_NAME "${PROJECT_NAME}")
|
||||||
|
|
|
@ -26,23 +26,24 @@ namespace po = boost::program_options;
|
||||||
namespace din {
|
namespace din {
|
||||||
bool parse_commandline (int parArgc, char* parArgv[], po::variables_map& parVarMap) {
|
bool parse_commandline (int parArgc, char* parArgv[], po::variables_map& parVarMap) {
|
||||||
po::options_description set_options(ACTION_NAME " options");
|
po::options_description set_options(ACTION_NAME " options");
|
||||||
//set_options.add_options()
|
set_options.add_options()
|
||||||
//("switch,s", "Help message")
|
//("switch,s", "Help message")
|
||||||
//("option,o", po::value<std::string>()->default_value("default_value"), "Help message")
|
//("option,o", po::value<std::string>()->default_value("default_value"), "Help message")
|
||||||
//("option2", po::value<int>(), "Help message")
|
//("option2", po::value<int>(), "Help message")
|
||||||
//;
|
("ids", po::value<std::string>(), "Comma-separated list of IDs of files to be tagged")
|
||||||
|
;
|
||||||
|
|
||||||
po::options_description positional_options("Positional options");
|
po::options_description positional_options("Positional options");
|
||||||
positional_options.add_options()
|
positional_options.add_options()
|
||||||
("tags", po::value<std::string>(), "comma-separated tag list")
|
("tags", po::value<std::string>(), "comma-separated tag list")
|
||||||
("ids", po::value<std::vector<uint64_t>>(), "pos_option description")
|
("glob", po::value<std::string>(), "glob to match against")
|
||||||
;
|
;
|
||||||
|
|
||||||
const auto desc = dinlib::get_default_commandline();
|
const auto desc = dinlib::get_default_commandline();
|
||||||
po::options_description all("Available options");
|
po::options_description all("Available options");
|
||||||
po::positional_options_description pd;
|
po::positional_options_description pd;
|
||||||
all.add(desc).add(positional_options).add(set_options);
|
all.add(desc).add(positional_options).add(set_options);
|
||||||
pd.add("tags", 1).add("ids", -1);
|
pd.add("tags", 1).add("glob", 1);
|
||||||
try {
|
try {
|
||||||
po::store(po::command_line_parser(parArgc, parArgv).options(all).positional(pd).run(), parVarMap);
|
po::store(po::command_line_parser(parArgc, parArgv).options(all).positional(pd).run(), parVarMap);
|
||||||
}
|
}
|
||||||
|
@ -52,7 +53,7 @@ namespace din {
|
||||||
|
|
||||||
po::notify(parVarMap);
|
po::notify(parVarMap);
|
||||||
|
|
||||||
const char* const help_text = "[options...] tag[,tag2...] ids...";
|
const char* const help_text = "[options...] tag[,tag2...] (--ids id1[,id2...] | <glob>)";
|
||||||
if (dinlib::manage_common_commandline(std::cout, ACTION_NAME, help_text, parVarMap, {std::cref(desc), std::cref(set_options)})) {
|
if (dinlib::manage_common_commandline(std::cout, ACTION_NAME, help_text, parVarMap, {std::cref(desc), std::cref(set_options)})) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,14 +20,19 @@
|
||||||
#include "dindexerConfig.h"
|
#include "dindexerConfig.h"
|
||||||
#include "tag_postgres.hpp"
|
#include "tag_postgres.hpp"
|
||||||
#include "dindexer-common/split_tags.hpp"
|
#include "dindexer-common/split_tags.hpp"
|
||||||
|
#include "glob2regex/glob2regex.hpp"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <ciso646>
|
#include <ciso646>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <boost/lexical_cast.hpp>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
} //unnamed namespace
|
} //unnamed namespace
|
||||||
|
|
||||||
int main (int parArgc, char* parArgv[]) {
|
int main (int parArgc, char* parArgv[]) {
|
||||||
using boost::program_options::variables_map;
|
using boost::program_options::variables_map;
|
||||||
|
using boost::lexical_cast;
|
||||||
|
using boost::string_ref;
|
||||||
|
|
||||||
variables_map vm;
|
variables_map vm;
|
||||||
try {
|
try {
|
||||||
|
@ -40,10 +45,17 @@ int main (int parArgc, char* parArgv[]) {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (not vm.count("ids")) {
|
const bool id_mode = static_cast<bool>(vm.count("ids"));
|
||||||
std::cerr << "No IDs specified\n";
|
const bool glob_mode = static_cast<bool>(vm.count("glob"));
|
||||||
|
if (not id_mode and not glob_mode) {
|
||||||
|
std::cerr << "No IDs or glob specified\n";
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
else if (id_mode and glob_mode) {
|
||||||
|
std::cerr << "Can't specify both a glob and IDs, please only use one of them\n";
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
assert(id_mode xor glob_mode);
|
||||||
|
|
||||||
dinlib::Settings settings;
|
dinlib::Settings settings;
|
||||||
{
|
{
|
||||||
|
@ -54,14 +66,24 @@ int main (int parArgc, char* parArgv[]) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto ids = vm["ids"].as<std::vector<uint64_t>>();
|
const auto master_tags_string = vm["tags"].as<std::string>();
|
||||||
for (auto id : ids) {
|
const std::vector<boost::string_ref> tags = dinlib::split_tags(master_tags_string);
|
||||||
std::cout << id << '\n';
|
|
||||||
|
if (id_mode) {
|
||||||
|
auto ids_string = dinlib::split_tags(vm["ids"].as<std::string>());
|
||||||
|
std::vector<uint64_t> ids;
|
||||||
|
ids.reserve(ids_string.size());
|
||||||
|
std::transform(ids_string.begin(), ids_string.end(), std::back_inserter(ids), &lexical_cast<uint64_t, string_ref>);
|
||||||
|
din::tag_files(settings.db, ids, tags);
|
||||||
|
}
|
||||||
|
else if (glob_mode) {
|
||||||
|
const auto regex = g2r::convert(vm["glob"].as<std::string>());
|
||||||
|
din::tag_files(settings.db, regex, true, tags);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
assert(false);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto master_tags_string = vm["tags"].as<std::string>();
|
|
||||||
std::vector<boost::string_ref> tags = dinlib::split_tags(master_tags_string);
|
|
||||||
|
|
||||||
din::tag_files(settings.db, ids, tags);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "tag_postgres.hpp"
|
#include "tag_postgres.hpp"
|
||||||
#include "pq/connection.hpp"
|
#include "pq/connection.hpp"
|
||||||
#include "dindexer-common/settings.hpp"
|
#include "dindexer-common/settings.hpp"
|
||||||
|
#include <ciso646>
|
||||||
|
|
||||||
namespace din {
|
namespace din {
|
||||||
void tag_files (const dinlib::SettingsDB& parDB, const std::vector<uint64_t>& parFiles, const std::vector<boost::string_ref>& parTags) {
|
void tag_files (const dinlib::SettingsDB& parDB, const std::vector<uint64_t>& parFiles, const std::vector<boost::string_ref>& parTags) {
|
||||||
|
@ -29,4 +30,17 @@ namespace din {
|
||||||
|
|
||||||
conn.query(query, parTags, parFiles);
|
conn.query(query, parTags, parFiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tag_files (const dinlib::SettingsDB& parDB, std::string parRegex, bool parCaseSensitive, const std::vector<boost::string_ref>& parTags) {
|
||||||
|
pq::Connection conn(std::string(parDB.username), std::string(parDB.password), std::string(parDB.dbname), std::string(parDB.address), parDB.port);
|
||||||
|
conn.connect();
|
||||||
|
|
||||||
|
if (not parCaseSensitive)
|
||||||
|
parRegex = "(?i)" + parRegex;
|
||||||
|
|
||||||
|
const std::string query =
|
||||||
|
"UPDATE \"files\" SET \"tags\" = ARRAY(SELECT DISTINCT UNNEST(\"tags\" || $1) ORDER BY 1) WHERE \"path\" ~ $2;";
|
||||||
|
|
||||||
|
conn.query(query, parTags, parRegex);
|
||||||
|
}
|
||||||
} //namespace din
|
} //namespace din
|
||||||
|
|
|
@ -28,6 +28,7 @@ namespace dinlib {
|
||||||
|
|
||||||
namespace din {
|
namespace din {
|
||||||
void tag_files ( const dinlib::SettingsDB& parDB, const std::vector<uint64_t>& parFiles, const std::vector<boost::string_ref>& parTags );
|
void tag_files ( const dinlib::SettingsDB& parDB, const std::vector<uint64_t>& parFiles, const std::vector<boost::string_ref>& parTags );
|
||||||
|
void tag_files ( const dinlib::SettingsDB& parDB, std::string parRegex, bool parCaseSensitive, const std::vector<boost::string_ref>& parTags );
|
||||||
} //namespace din
|
} //namespace din
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue