From d88c486ae403bee8f4b16e4bdf9daf19f8915eed Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 26 Sep 2009 02:09:03 +0200 Subject: Client: Added unfinished XLS import command --- src/Client/UserListCommands.cpp | 268 +++++++++++++++++++++++++++++++--------- 1 file changed, 210 insertions(+), 58 deletions(-) (limited to 'src/Client/UserListCommands.cpp') diff --git a/src/Client/UserListCommands.cpp b/src/Client/UserListCommands.cpp index ad0c2d0..7774240 100644 --- a/src/Client/UserListCommands.cpp +++ b/src/Client/UserListCommands.cpp @@ -19,6 +19,8 @@ #include "UserListCommands.h" #include "Application.h" +#include "XLSReader.h" +#include "XLSSheet.h" #include "Requests/UserLists/UserListListRequest.h" #include "Requests/UserLists/UserListDownloadRequest.h" #include "Requests/UserLists/UserListDiffListRequest.h" @@ -36,6 +38,7 @@ 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}, + {{"import", "im", 0}, "import filename", "Imports a user list file", "Imports a user list file. At the moment, this supports only XLS files.", &UserListCommands::importCommand}, {{0}, 0, 0, 0, 0} }; @@ -173,90 +176,239 @@ void UserListCommands::showListCommand(CommandParser *commandParser, const std:: std::cout << "s"; std::cout << "." << std::endl << std::endl; - std::map lengths; + printUserList(*userList); + } - 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::cout << std::endl; + } + else { + std::cerr << args[0] << " " << args[1] << ": Too many arguments." << std::endl; + printUsage("show_list"); + return; + } +} - std::set details = userList->getDetails(); - for(std::set::iterator detail = details.begin(); detail != details.end(); ++detail) { - lengths.insert(std::make_pair(*detail, detail->length())); +void UserListCommands::importCommand(CommandParser* /*commandParser*/, const std::vector &args) { + if(args.size() < 3) { + std::cerr << args[0] << " " << args[1] << ": No filename given." << std::endl; + printUsage("import"); + return; + } + else if(args.size() == 3) { + try { + XLSReader reader(args[2]); + const std::list > &sheets = reader.getSheets(); + + if(sheets.empty()) { + std::cerr << "There aren't any worksheets in the file." << std::endl; + return; } - 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(); + unsigned long sheetNum = 1; + + if(sheets.size() > 1) { + std::cout << "There is more than one worksheet in the file. Which one do you want to import?" << std::endl << std::endl; + + while(true) { + int i = 1; + for(std::list >::const_iterator sheet = sheets.begin(); sheet != sheets.end(); ++sheet, ++i) { + std::cout << " " << i << ") " << (*sheet)->getTitle() << std::endl; + } - it = lengths.find(GROUP_NAME); - if(user->getGroup().length() > it->second) - it->second = user->getGroup().length(); + std::cout << std::endl; + std::cout << "Worksheet number: " << std::flush; - 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::string input; + std::getline(std::cin, input); + sheetNum = std::strtoul(input.c_str(), 0, 10); + + if(sheetNum > 0 && sheetNum <= sheets.size()) + break; + + std::cout << "Invalid selection. Please choose one of:" << std::endl << std::endl; } } - 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; + std::list >::const_iterator sheet = sheets.begin(); + std::advance(sheet, sheetNum-1); - for(Common::UserLists::UserList::iterator user = userList->begin(); user != userList->end(); ++user) { - static const std::string UNSET(""); + std::cout << "Imported worksheet:" << std::endl; + printSheet(**sheet, 10); - std::cout << " "; + std::cout << std::endl << std::endl; + std::cout << "Does the first line of the worksheet contain the column names? (Y/n) " << std::flush; - if(!user->getName().empty()) - printPadded(user->getName(), lengths.find(USER_NAME)->second); - else - printPadded(UNSET, lengths.find(USER_NAME)->second); + std::string input; + std::getline(std::cin, input); + if(input.empty() || (input[0] != 'n' && input[0] != 'N')) { + (*sheet)->useFirstRowAsColumnNames(true); + } + + std::cout << std::endl << std ::endl; + printSheet(**sheet, 10); + std::cout << std::endl << std ::endl; + + Common::UserLists::UserList userList; + const std::vector &rows = (*sheet)->getRows(); + unsigned id = 1; - std::cout << " "; + for(std::vector::const_iterator rowIt = rows.begin(); rowIt != rows.end(); ++rowIt, ++id) { + const std::vector &row = **rowIt; + Common::UserLists::UserListEntry entry; - if(!user->getGroup().empty()) - printPadded(user->getGroup(), lengths.find(GROUP_NAME)->second); - else - printPadded(UNSET, lengths.find(GROUP_NAME)->second); + std::ostringstream stream; + stream << id; + entry.setName(stream.str()); - for(std::set::iterator detail = details.begin(); detail != details.end(); ++detail) { - std::cout << " "; - printPadded(user->getDetail(*detail), lengths.find(*detail)->second); + for(unsigned col = 0; col < (*sheet)->getColumnCount(); ++col) { + entry.setDetail((*sheet)->getColumnName(col), row[col]); } - std::cout << std::endl; + userList.addUser(entry); } - } - std::cout << std::endl; + printUserList(userList); + std::cout << std::endl << std ::endl; + } + catch(Core::Exception e) { + std::cerr << "The file can't be read: " << e.what() << "." << std::endl; + } } else { std::cerr << args[0] << " " << args[1] << ": Too many arguments." << std::endl; - printUsage("show_list"); + printUsage("import"); return; } } + +void UserListCommands::printUserList(const Common::UserLists::UserList &list) { + std::map lengths; + + static const std::string USER_NAME = "User name"; + static const std::string GROUP_NAME = "Group name"; + + lengths.insert(std::make_pair(USER_NAME, USER_NAME.length())); + lengths.insert(std::make_pair(GROUP_NAME, GROUP_NAME.length())); + + std::set details = list.getDetails(); + for(std::set::iterator detail = details.begin(); detail != details.end(); ++detail) { + lengths.insert(std::make_pair(*detail, detail->length())); + } + + for(Common::UserLists::UserList::const_iterator user = list.begin(); user != list.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::const_iterator user = list.begin(); user != list.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; + } +} + +void UserListCommands::printSheet(const XLSSheet &sheet, unsigned rowCount) { + const std::vector &rows = sheet.getRows(); + std::vector lengths(sheet.getColumnCount()); + + for(unsigned col = 0; col < sheet.getColumnCount(); ++col) { + lengths[col] = sheet.getColumnName(col).size(); + } + + for(std::vector::const_iterator rowIt = rows.begin(); rowIt != rows.end() && (rowCount == 0 || rowIt != rows.begin()+rowCount); ++rowIt) { + const std::vector &row = **rowIt; + + for(unsigned col = 0; col < sheet.getColumnCount(); ++col) { + if(row[col].size() > lengths[col]) + lengths[col] = row[col].size(); + } + } + + for(unsigned col = 0; col < sheet.getColumnCount(); ++col) { + std::cout << " "; + printPadded(sheet.getColumnName(col), lengths[col]); + } + std::cout << std::endl; + + std::cout << " "; + for(unsigned col = 0; col < sheet.getColumnCount(); ++col) { + std::cout << " -"; + printDelimiter(lengths[col]); + std::cout << "-"; + } + std::cout << std::endl; + + for(std::vector::const_iterator rowIt = rows.begin(); rowIt != rows.end() && (rowCount == 0 || rowIt != rows.begin()+rowCount); ++rowIt) { + const std::vector &row = **rowIt; + + for(unsigned col = 0; col < sheet.getColumnCount(); ++col) { + std::cout << " "; + printPadded(row[col], lengths[col]); + } + + std::cout << std::endl; + } + + if(rowCount > 0 && rows.size() > rowCount) { + for(unsigned col = 0; col < sheet.getColumnCount(); ++col) { + std::cout << " "; + printPadded("...", lengths[col]); + } + } +} + void UserListCommands::printPadded(const std::string &str, unsigned length) { std::cout << str; if(str.length() < length) -- cgit v1.2.3