From 44f16b6cd5b9cd9641c0c5df1c671c9e610ad7ac Mon Sep 17 00:00:00 2001 From: Your Name Date: Fri, 6 Nov 2020 15:28:10 -0500 Subject: Added mod installation to cli interface --- bible.cc | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- libbible.h | 3 ++- mods.cc | 18 ++++++++++++----- readme.md | 4 ++++ testLibbible.cc | 23 +++++++++++++++++++++ 5 files changed, 103 insertions(+), 7 deletions(-) diff --git a/bible.cc b/bible.cc index 2846c5f..b0e3ed3 100644 --- a/bible.cc +++ b/bible.cc @@ -16,6 +16,10 @@ void usage() { printf(" --list-books list books available in the current module\n"); printf(" --list-chapters list chapters available in book in the current module\n"); printf(" -o, --omit-verse-numbers when printing verse text, skip printing verse and chapter numbers\n"); + printf(" --list-installable= list bible versions available for download and install. Default lists for all languages.\n"); + printf(" --install-network install module from the network where is LANG:NAME as provided by --list-installable\n"); + printf(" --install-zip install module from a zip file\n"); + printf(" --remove-mod delete a mod from the system\n"); printf("\n\nExamples:\n bible Gal 5:22-23\n"); printf(" bible John 3:16\n bible Romans 12\n bible Matt 5:3-7:27\n"); printf(" bible Genesis 1-3\n"); @@ -61,6 +65,42 @@ void listChapters(string modname, string book) { } } +void listInstallable(string language) { + map> installable = libbible::downloadModsAvailable(); + for(auto pair : installable) { + if(!language.empty() && language != pair.first) { + continue; + } + printf("For language %s:\n", pair.first.c_str()); + for(string name : pair.second) { + printf(" %s\n", name.c_str()); + } + } +} + +void installNetwork(string mod) { + //Split on : + if(mod.find(':') == string::npos) { + printf("Unable to process module \"%s\": Must contain colon separated language:name\n", mod.c_str()); + return; + } + string lang = mod.substr(0, mod.find(':')); + string name = mod.substr(mod.find(':')+1); + if(libbible::installModFromInternet(lang, name)) { + printf("Module installed.\n"); + } else { + printf("Error installing module!\n"); + } +} + +void installZip(string path) { + libbible::installModFromZip(path); +} + +void removeMod(string mod) { + libbible::uninstallMod(mod); +} + int main(int argc, char* argv[]) { static struct option long_options[] = { {"help", no_argument, 0, 'h'}, @@ -69,7 +109,11 @@ int main(int argc, char* argv[]) { {"set-default-module", required_argument, 0, 0}, {"list-books", no_argument, 0, 0}, {"list-chapters", required_argument, 0, 0}, - {"omit-verse-numbers", no_argument, 0, 'o'} + {"omit-verse-numbers", no_argument, 0, 'o'}, + {"list-installable", optional_argument, 0, 0}, + {"install-network", required_argument, 0, 0}, + {"install-zip", required_argument, 0, 0}, + {"remove-mod", required_argument, 0, 0} }; int opt, option_index; string modname; @@ -99,6 +143,18 @@ int main(int argc, char* argv[]) { doListBooks = true; } else if(option == "list-chapters") { listChaptersBook = string(optarg); + } else if(option == "list-installable") { + if(optarg == nullptr) { + listInstallable(string()); + } else { + listInstallable(string(optarg)); + } + } else if(option == "install-network") { + installNetwork(string(optarg)); + } else if(option == "install-zip") { + installZip(string(optarg)); + } else if(option == "remove-mod") { + removeMod(string(optarg)); } break; default: @@ -120,6 +176,10 @@ int main(int argc, char* argv[]) { reference += argv[optind++]; reference += " "; } + if(reference.empty()) { + // That's all. + return 0; + } auto text = libbible::getText(libbible::passage{.modName = modname, .reference = reference}); int chapter = 0; diff --git a/libbible.h b/libbible.h index d21639a..cf8a1f4 100644 --- a/libbible.h +++ b/libbible.h @@ -63,8 +63,9 @@ namespace libbible { * @param language The language of the mod to install as provided from downloadModsAvailable * @param name The name of the bible version as provided from downloadModsAvailable * @see downloadModsAvailable() + * @return true on success, false otherwise */ - void installModFromInternet(std::string language, std::string name); + bool installModFromInternet(std::string language, std::string name); /** * @param filename Path to the .zip compressed module to be installed diff --git a/mods.cc b/mods.cc index c30fce4..1a31602 100644 --- a/mods.cc +++ b/mods.cc @@ -62,9 +62,9 @@ map> libbible::downloadModsAvailable(libbible::Status *st config["General"]["PassiveFTP"] = "true"; config["Sources"]["FTPSource"] = is.getConfEnt(); config.save(); + installMgr->refreshRemoteSourceConfiguration(); } installMgr->readInstallConf(); - installMgr->refreshRemoteSourceConfiguration(); map> modsAvailable; //printf("Getting langs...\n"); for(auto src : installMgr->sources) { @@ -96,15 +96,21 @@ void libbible::terminateDownload() { installMgr->terminate(); } -void libbible::installModFromInternet(string language, string name) { +bool libbible::installModFromInternet(string language, string name) { // Searching through map>> installSources; + if(installSources.empty()) { + downloadModsAvailable(); + } for (pair p : installSources[language]) { if(p.first == name) { sword::SWMgr mgr(basedir.c_str()); - installMgr->installModule(&mgr, 0, name.c_str(), p.second); - break; + if(installMgr->installModule(&mgr, 0, name.c_str(), p.second) == 0) { + return true; + } + return false; } } + return false; } void libbible::installModFromZip(string filename) { @@ -122,5 +128,7 @@ void libbible::installModFromZip(string filename) { void libbible::uninstallMod(string modname) { sword::SWMgr mgr(basedir.c_str()); sword::ModMap::iterator it = mgr.Modules.find(modname.c_str()); - installMgr->removeModule(&mgr, it->second->getName()); + if(it != mgr.Modules.end()) { + installMgr->removeModule(&mgr, it->second->getName()); + } } diff --git a/readme.md b/readme.md index a9cf063..21be739 100644 --- a/readme.md +++ b/readme.md @@ -39,6 +39,10 @@ Options: --list-books list books available in the current module --list-chapters list chapters available in book in the current module -o, --omit-verse-numbers when printing verse text, skip printing verse and chapter numbers + --list-installable= list bible versions available for download and install. Default lists for all languages. + --install-network install module from the network where is LANG:NAME as provided by --list-installable + --install-zip install module from a zip file + --remove-mod delete a mod from the system Examples: diff --git a/testLibbible.cc b/testLibbible.cc index ad51c44..b06a0bd 100644 --- a/testLibbible.cc +++ b/testLibbible.cc @@ -29,6 +29,7 @@ class TestLibbible : public CppUnit::TestFixture CPPUNIT_TEST(testGetPassages); CPPUNIT_TEST(testGetText); CPPUNIT_TEST(testSettings); + CPPUNIT_TEST(testDownload); CPPUNIT_TEST_SUITE_END(); //public: @@ -40,6 +41,7 @@ class TestLibbible : public CppUnit::TestFixture void testGetPassages(void); void testGetText(void); void testSettings(void); + void testDownload(void); }; @@ -171,6 +173,27 @@ void TestLibbible::testSettings(void) { libbible::settingsWrite("test", ""); CPPUNIT_ASSERT(libbible::settingsRead("test") == ""); } + +void TestLibbible::testDownload(void) { + map> modsAvailable = libbible::downloadModsAvailable(); + // We try installing the first available one + string language; + string name; + for(auto pair : modsAvailable) { + language = pair.first; + name = pair.second[0]; + break; + } + CPPUNIT_ASSERT(!language.empty() && !name.empty()); + // Try uninstalling it (shouldn't crash or have nasty side effects!) + libbible::uninstallMod(name); + auto mods = libbible::getModules(); + CPPUNIT_ASSERT(mods.find(name) == mods.end()); + libbible::installModFromInternet(language, name); + mods = libbible::getModules(); + CPPUNIT_ASSERT(mods.find(name) != mods.end()); + +} //----------------------------------------------------------------------------- CPPUNIT_TEST_SUITE_REGISTRATION( TestLibbible ); -- cgit v1.2.3