From 78c5f37d50ed5687bd5525954838f62b50de0690 Mon Sep 17 00:00:00 2001 From: Jon Bergli Heier Date: Thu, 6 Jan 2011 04:01:17 +0100 Subject: Reworked "find" to allow for more sophisticated searches. The usage of the "find" command is as follows: find SEARCH where SEARCH is either a simple string to search for, or key:value pairs with the following keys: artist album title --- commands.cpp | 45 +++++++++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 14 deletions(-) (limited to 'commands.cpp') diff --git a/commands.cpp b/commands.cpp index 84c1e5f..76ce2ff 100644 --- a/commands.cpp +++ b/commands.cpp @@ -3,9 +3,13 @@ #include #include #include +#include +#include #include +namespace qi = boost::spirit::qi; + std::vector Commands::ls() { if(args.size() != 2) { throw CommandException("usage: ls DIR"); @@ -29,24 +33,39 @@ std::vector Commands::ls() { return result; } +typedef std::map stringmap; + +static bool find_parse(std::string str, stringmap& foo) { + typedef std::string::const_iterator Iterator; + + Iterator begin = str.begin(); + Iterator end = str.end(); + + return qi::parse(begin, end, + // pairs wrapped in "quotes" + (('"' >> +(qi::char_ - ':') >> ':' >> +(qi::char_ - '"') >> '"') | + // simple key:value pairs + (+(qi::char_ - ':' - ' ') >> ':' >> +(qi::char_ - ' '))) + // skip spaces between pairs + % +qi::char_(' '), + foo) && begin == end; +} + std::vector Commands::find() { - if(args.size() != 3) { - throw CommandException("usage: find TYPE SEARCH"); + if(args.size() < 2) { + throw CommandException("usage: find SEARCH"); } - FindFunction ff; - if(find_handlers.find(args[1]) != find_handlers.end()) { - ff = find_handlers[args[1]]; + stringmap find_args; + args.erase(args.begin()); + std::string search = boost::algorithm::join(args, " "); + std::vector ml; + if(find_parse(search, find_args)) { + ml = music::find(find_args); } else { - std::vector types; - for(std::map::iterator it = find_handlers.begin(); it != find_handlers.end(); it++) { - types.push_back(it->first); - } - std::string s = boost::str(boost::format("unknown search type, must be one of %s") % boost::algorithm::join(types, ", ")); - throw CommandException(s.c_str()); + ml = music::find(search); } - std::vector ml = ff(args[2]); if(!ml.size()) { throw CommandException("no results"); } @@ -56,7 +75,6 @@ std::vector Commands::find() { result.push_back((*it)->path.string()); } - return result; } @@ -74,7 +92,6 @@ std::vector Commands::update() { Commands::Commands(boost::asio::io_service& io_service_, std::vector& args_) : io_service(io_service_), args(args_) { handlers["ls"] = &Commands::ls; handlers["find"] = &Commands::find; - find_handlers["artist"] = music::find_artist; handlers["update"] = &Commands::update; } -- cgit v1.2.3