#include "commands.h" #include #include #include #include #include #include namespace qi = boost::spirit::qi; std::vector Commands::ls() { if(args.size() != 2) { throw CommandException("usage: ls DIR"); } MusicDirectory::p dir = music::get_directory(args[1]); if(!dir) { throw CommandException("no such directory"); } std::cout << dir->path << std::endl; std::vector result; for(MusicDirectory::PathListings::iterator it = dir->directories.begin(); it != dir->directories.end(); it++) { std::string rel_path = it->string().substr(music::root_directory.string().size()); result.push_back(rel_path); } for(MusicDirectory::PathListings::iterator it = dir->tracks.begin(); it != dir->tracks.end(); it++) { std::string rel_path = it->string().substr(music::root_directory.string().size()); result.push_back(rel_path); } 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() < 2) { throw CommandException("usage: find SEARCH"); } 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 { ml = music::find(search); } if(!ml.size()) { throw CommandException("no results"); } std::vector result; for(std::vector::iterator it = ml.begin(); it != ml.end(); it++) { result.push_back((*it)->path.string()); } return result; } std::vector Commands::update() { if(args.size() != 2) { throw CommandException("usage: update DIR"); } io_service.post(boost::bind(music::begin_update, args[1])); std::vector v; return v; } 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; handlers["update"] = &Commands::update; } /** Invokes the command and returns its results. * Throws CommandException if the command isn't found. */ std::vector Commands::operator()() { assert(args.size()); Handler h = handlers[args[0]]; if(!h) { throw CommandException(boost::str(boost::format("unknown command \"%s\"") % args[0])); } return h(this); }