mirror of
https://github.com/KingDuckZ/dindexer.git
synced 2024-11-29 01:33:46 +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}
|
||||
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/..
|
||||
PRIVATE ${CMAKE_SOURCE_DIR}/lib/glob2regex/include
|
||||
)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
PRIVATE ${bare_name}-if
|
||||
PRIVATE ${bare_name}-common
|
||||
PRIVATE glob2regex
|
||||
)
|
||||
|
||||
string(REPLACE "${bare_name}-" "" ACTION_NAME "${PROJECT_NAME}")
|
||||
|
|
|
@ -26,23 +26,24 @@ namespace po = boost::program_options;
|
|||
namespace din {
|
||||
bool parse_commandline (int parArgc, char* parArgv[], po::variables_map& parVarMap) {
|
||||
po::options_description set_options(ACTION_NAME " options");
|
||||
//set_options.add_options()
|
||||
set_options.add_options()
|
||||
//("switch,s", "Help message")
|
||||
//("option,o", po::value<std::string>()->default_value("default_value"), "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");
|
||||
positional_options.add_options()
|
||||
("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();
|
||||
po::options_description all("Available options");
|
||||
po::positional_options_description pd;
|
||||
all.add(desc).add(positional_options).add(set_options);
|
||||
pd.add("tags", 1).add("ids", -1);
|
||||
pd.add("tags", 1).add("glob", 1);
|
||||
try {
|
||||
po::store(po::command_line_parser(parArgc, parArgv).options(all).positional(pd).run(), parVarMap);
|
||||
}
|
||||
|
@ -52,7 +53,7 @@ namespace din {
|
|||
|
||||
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)})) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -20,14 +20,19 @@
|
|||
#include "dindexerConfig.h"
|
||||
#include "tag_postgres.hpp"
|
||||
#include "dindexer-common/split_tags.hpp"
|
||||
#include "glob2regex/glob2regex.hpp"
|
||||
#include <iostream>
|
||||
#include <ciso646>
|
||||
#include <algorithm>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
namespace {
|
||||
} //unnamed namespace
|
||||
|
||||
int main (int parArgc, char* parArgv[]) {
|
||||
using boost::program_options::variables_map;
|
||||
using boost::lexical_cast;
|
||||
using boost::string_ref;
|
||||
|
||||
variables_map vm;
|
||||
try {
|
||||
|
@ -40,10 +45,17 @@ int main (int parArgc, char* parArgv[]) {
|
|||
return 2;
|
||||
}
|
||||
|
||||
if (not vm.count("ids")) {
|
||||
std::cerr << "No IDs specified\n";
|
||||
const bool id_mode = static_cast<bool>(vm.count("ids"));
|
||||
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;
|
||||
}
|
||||
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;
|
||||
{
|
||||
|
@ -54,14 +66,24 @@ int main (int parArgc, char* parArgv[]) {
|
|||
}
|
||||
}
|
||||
|
||||
const auto ids = vm["ids"].as<std::vector<uint64_t>>();
|
||||
for (auto id : ids) {
|
||||
std::cout << id << '\n';
|
||||
const auto master_tags_string = vm["tags"].as<std::string>();
|
||||
const std::vector<boost::string_ref> tags = dinlib::split_tags(master_tags_string);
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "tag_postgres.hpp"
|
||||
#include "pq/connection.hpp"
|
||||
#include "dindexer-common/settings.hpp"
|
||||
#include <ciso646>
|
||||
|
||||
namespace din {
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
|
|
|
@ -28,6 +28,7 @@ namespace dinlib {
|
|||
|
||||
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, std::string parRegex, bool parCaseSensitive, const std::vector<boost::string_ref>& parTags );
|
||||
} //namespace din
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue