/* * UserListCommands.cpp * * Copyright (C) 2009 Matthias Schiffer * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License along * with this program. If not, see . */ #include "UserListCommands.h" #include "Application.h" #include "Requests/UserLists/UserListListRequest.h" #include "Requests/UserLists/UserListDownloadRequest.h" #include "Requests/UserLists/UserListDiffListRequest.h" #include #include #include #include namespace Mad { namespace Client { const UserListCommands::Command UserListCommands::commands[] = { {{"help", "?", 0}, "help [command]", "Display usage information about user list commands", "Display usage information about a user list command. If no command is given, display a list of all available user list commands.", &UserListCommands::helpCommand}, {{"list", "ls", 0}, "list", "List the stored user lists", "List the stored user lists.", &UserListCommands::listCommand}, {{"show_list", "sl", 0}, "show_list list", "Displays a user list", "Displays a user list.", &UserListCommands::showListCommand}, {{0}, 0, 0, 0, 0} }; const UserListCommands::Command* UserListCommands::findCommand(const std::string& command) { for(int i = 0; commands[i].commands[0] != 0; ++i) { for(int j = 0; commands[i].commands[j] != 0; ++j) { if(command == commands[i].commands[j]) { return &commands[i]; } } } return 0; } void UserListCommands::printUsage(const std::string& command) { const UserListCommands::Command *cmd = findCommand(command); if(cmd) std::cerr << "Usage: " << "user_lists " << cmd->cmdline << std::endl; } void UserListCommands::helpCommand(CommandParser* /*commandParser*/, const std::vector &args) { if(args.size() <= 2) { std::cout << "Available commands:" << std::endl << std::endl; for(int i = 0; commands[i].commands[0] != 0; ++i) { std::cout << commands[i].commands[0]; for(int j = 1; commands[i].commands[j] != 0; ++j) std::cout << ", " << commands[i].commands[j]; std::cout << std::endl << "\t" << commands[i].desc << std::endl; } } else if(args.size() == 3) { const Command* command = findCommand(args[2]); if(command) { std::cout << "Usage: " << "user_lists " << command->cmdline << std::endl << std::endl; std::cout << command->longdesc << std::endl << std::endl; } else std::cerr << args[0] << " " << args[1] << ": Command '" << args[2] << "' doesn't exist." << std::endl; } else { std::cerr << args[0] << " " << args[1] << ": Too many arguments." << std::endl; printUsage("help"); } } void UserListCommands::listCommand(CommandParser *commandParser, const std::vector& /*args*/) { boost::shared_ptr userListRequest(new Requests::UserLists::UserListListRequest(commandParser->application)); boost::shared_ptr userListDiffRequest(new Requests::UserLists::UserListDiffListRequest(commandParser->application)); commandParser->application->getRequestManager()->sendRequest(commandParser->connection, userListRequest); commandParser->application->getRequestManager()->sendRequest(commandParser->connection, userListDiffRequest); userListRequest->wait(); userListDiffRequest->wait(); std::pair, Core::Exception> userListResult = userListRequest->getResult(); std::pair, Core::Exception> userListDiffResult = userListDiffRequest->getResult(); if(userListResult.second) { std::cerr << "An error occurred during your request: " << userListResult.second.what() << "." << std::endl; return; } else if(!userListResult.first || !userListDiffResult.first || userListDiffResult.second) { std::cerr << "An error occurred during your request: " << userListDiffResult.second.what() << "." << std::endl; return; } const Common::XmlData::List *userLists = userListResult.first->getList("userLists"); const Common::XmlData::List *userListDiffs = userListDiffResult.first->getList("userListDiffs"); if(userLists->isEmpty()) { std::cout << "There aren't any user lists stored on the server." << std::endl; } else { if(userLists->getSize() == 1) std::cout << "There is 1 user list stored on the server:" << std::endl; else std::cout << "There are " << userLists->getSize() << " user lists stored on the server:" << std::endl; for(Common::XmlData::List::const_iterator userList = userLists->begin(); userList != userLists->end(); ++userList) { std::cout << " " << userList->get("name") << std::endl; } } std::cout << std::endl; if(!userListDiffs->isEmpty()) { if(userListDiffs->getSize() == 1) std::cout << "There is 1 user list difference record stored on the server:" << std::endl; else std::cout << "There are " << userListDiffs->getSize() << " user list difference records stored on the server:" << std::endl; for(Common::XmlData::List::const_iterator diff = userListDiffs->begin(); diff != userListDiffs->end(); ++diff) { std::cout << " " << diff->get("name") << std::endl; } } } void UserListCommands::showListCommand(CommandParser *commandParser, const std::vector &args) { if(args.size() < 3) { std::cerr << args[0] << " " << args[1] << ": No list name given." << std::endl; printUsage("show_list"); return; } else if(args.size() == 3) { boost::shared_ptr request( new Requests::UserLists::UserListDownloadRequest(commandParser->application, args[2])); commandParser->application->getRequestManager()->sendRequest(commandParser->connection, request); request->wait(); std::pair, Core::Exception> result = request->getResult(); if(!result.first || result.second) { std::cerr << "An error occurred during your request: " << result.second.what() << "." << std::endl; return; } boost::shared_ptr userList = Common::UserLists::Util::deserializeUserList(result.first.get()); std::cout << "User list '" << args[2]; if(userList->isEmpty()) { std::cout << " is empty." << std::endl; } else { std::cout << "' contains " << userList->getLength() << " user"; if(userList->getLength() > 1) std::cout << "s"; std::cout << "." << std::endl << std::endl; std::map lengths; static const std::string USER_NAME("User name"); lengths.insert(std::make_pair(USER_NAME, USER_NAME.length())); static const std::string GROUP_NAME("Group name"); lengths.insert(std::make_pair(GROUP_NAME, GROUP_NAME.length())); std::set details = userList->getDetails(); for(std::set::iterator detail = details.begin(); detail != details.end(); ++detail) { lengths.insert(std::make_pair(*detail, detail->length())); } for(Common::UserLists::UserList::iterator user = userList->begin(); user != userList->end(); ++user) { std::map::iterator it = lengths.find(USER_NAME); if(user->getName().length() > it->second) it->second = user->getName().length(); it = lengths.find(GROUP_NAME); if(user->getGroup().length() > it->second) it->second = user->getGroup().length(); for(std::set::iterator detail = details.begin(); detail != details.end(); ++detail) { it = lengths.find(*detail); std::string detailStr = user->getDetail(*detail); if(detailStr.length() > it->second) it->second = detailStr.length(); } } std::cout << " "; printPadded(USER_NAME, lengths.find(USER_NAME)->second); std::cout << " "; printPadded(GROUP_NAME, lengths.find(GROUP_NAME)->second); for(std::set::iterator detail = details.begin(); detail != details.end(); ++detail) { std::cout << " "; printPadded(*detail, lengths.find(*detail)->second); } std::cout << std::endl; std::cout << "-"; printDelimiter(lengths.find(USER_NAME)->second); std::cout << "- -"; printDelimiter(lengths.find(GROUP_NAME)->second); for(std::set::iterator detail = details.begin(); detail != details.end(); ++detail) { std::cout << "- -"; printDelimiter(lengths.find(*detail)->second); } std::cout << "-" << std::endl; for(Common::UserLists::UserList::iterator user = userList->begin(); user != userList->end(); ++user) { static const std::string UNSET(""); std::cout << " "; if(!user->getName().empty()) printPadded(user->getName(), lengths.find(USER_NAME)->second); else printPadded(UNSET, lengths.find(USER_NAME)->second); std::cout << " "; if(!user->getGroup().empty()) printPadded(user->getGroup(), lengths.find(GROUP_NAME)->second); else printPadded(UNSET, lengths.find(GROUP_NAME)->second); for(std::set::iterator detail = details.begin(); detail != details.end(); ++detail) { std::cout << " "; printPadded(user->getDetail(*detail), lengths.find(*detail)->second); } std::cout << std::endl; } } std::cout << std::endl; } else { std::cerr << args[0] << " " << args[1] << ": Too many arguments." << std::endl; printUsage("show_list"); return; } } void UserListCommands::printPadded(const std::string &str, unsigned length) { std::cout << str; if(str.length() < length) std::cout << std::string(length-str.length(), ' '); } void UserListCommands::printDelimiter(unsigned length) { printPadded(std::string(length, '-'), length); } void UserListCommands::userListCommand(CommandParser *commandParser, const std::vector &args) { std::string cmd; if(args.size() < 2) cmd = "help"; else cmd = args[1]; const Command* command = findCommand(cmd); if(command) command->function(commandParser, args); else std::cerr << args[0] << ": Unknown command '" << cmd << "'." << std::endl; } } }