summaryrefslogtreecommitdiff
path: root/commands.cpp
diff options
context:
space:
mode:
authorJon Bergli Heier <snakebite@jvnv.net>2011-01-06 04:01:17 +0100
committerJon Bergli Heier <snakebite@jvnv.net>2011-01-06 04:05:46 +0100
commit78c5f37d50ed5687bd5525954838f62b50de0690 (patch)
tree2def0d74af305f040f6e48e8f644621cd8add64e /commands.cpp
parente755f01e631e832e3ef529049888d62af38d2b38 (diff)
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
Diffstat (limited to 'commands.cpp')
-rw-r--r--commands.cpp45
1 files changed, 31 insertions, 14 deletions
diff --git a/commands.cpp b/commands.cpp
index 84c1e5f..76ce2ff 100644
--- a/commands.cpp
+++ b/commands.cpp
@@ -3,9 +3,13 @@
#include <boost/format.hpp>
#include <boost/algorithm/string/join.hpp>
#include <boost/bind.hpp>
+#include <boost/spirit/include/qi.hpp>
+#include <boost/fusion/include/std_pair.hpp>
#include <iostream>
+namespace qi = boost::spirit::qi;
+
std::vector<std::string> Commands::ls() {
if(args.size() != 2) {
throw CommandException("usage: ls DIR");
@@ -29,24 +33,39 @@ std::vector<std::string> Commands::ls() {
return result;
}
+typedef std::map<std::string, std::string> 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<std::string> 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<MusicListing::p> ml;
+ if(find_parse(search, find_args)) {
+ ml = music::find(find_args);
} else {
- std::vector<std::string> types;
- for(std::map<std::string, FindFunction>::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<MusicListing::p> ml = ff(args[2]);
if(!ml.size()) {
throw CommandException("no results");
}
@@ -56,7 +75,6 @@ std::vector<std::string> Commands::find() {
result.push_back((*it)->path.string());
}
-
return result;
}
@@ -74,7 +92,6 @@ std::vector<std::string> Commands::update() {
Commands::Commands(boost::asio::io_service& io_service_, std::vector<std::string>& 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;
}