1
0
Fork 0
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:
King_DuckZ 2016-05-17 19:54:05 +02:00
parent 67bdabb548
commit 21c5b3efcb
5 changed files with 54 additions and 14 deletions

View file

@ -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}")

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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

View file

@ -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