#include "libbible.h" #include #include #include #include #include using namespace std; class myStatusReporter : public sword::StatusReporter { public: myStatusReporter(libbible::Status *status); virtual ~myStatusReporter(); virtual void preStatus(long totalBytes, long completedBytes, const char *message); virtual void update(unsigned long totalBytes, unsigned long completedBytes); protected: libbible::Status *status; string message; }; myStatusReporter::myStatusReporter(libbible::Status *s) { status = s; } myStatusReporter::~myStatusReporter() {}; void libbible::Status::update(unsigned long totalBytes, unsigned long completedBytes, string message) {} void myStatusReporter::preStatus(long totalBytes, long completedBytes, const char *msg) { message = string(msg); status->update((unsigned long) totalBytes, (unsigned long) completedBytes, message); } void myStatusReporter::update(unsigned long totalBytes, unsigned long completedBytes) { status->update(totalBytes, completedBytes, message); } string basedir = (getenv("HOME")) + string("/.sword/"); sword::InstallMgr *installMgr = new sword::InstallMgr((basedir + std::string("InstallMgr")).c_str(), nullptr); map>> installSources; map> libbible::downloadModsAvailable(libbible::Status *status) { installSources.clear(); mkdir((basedir + std::string("mods.d/")).c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); mkdir((basedir + std::string("modules/")).c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); myStatusReporter *msr = nullptr; if(status) { msr = new myStatusReporter(status); } free(installMgr); installMgr = new sword::InstallMgr((basedir + std::string("InstallMgr")).c_str(), msr); installMgr->setUserDisclaimerConfirmed(true); string confpath = basedir + string("InstallMgr/InstallMgr.conf"); if(! sword::FileMgr::existsFile(confpath.c_str())) { // Lifted directly from xiphos sword::FileMgr::createParent(confpath.c_str()); sword::SWConfig config(confpath.c_str()); sword::InstallSource is("FTP"); is.caption = "CrossWire"; is.source = "ftp.crosswire.org"; is.directory = "/pub/sword/raw"; config["General"]["PassiveFTP"] = "true"; config["Sources"]["FTPSource"] = is.getConfEnt(); config.save(); installMgr->refreshRemoteSourceConfiguration(); } installMgr->readInstallConf(); map> modsAvailable; //printf("Getting langs...\n"); for(auto src : installMgr->sources) { if(src.second->getMgr()->Modules.empty()) { //printf("Refreshing remote source: %s\n", src.second->getConfEnt().c_str()); installMgr->refreshRemoteSource(src.second); } for(auto mod : src.second->getMgr()->Modules) { auto *curMod = mod.second; string type(curMod->getType()); if(type == "Biblical Texts") { string language(curMod->getLanguage()); //printf("Got language %s\n", language.c_str()); vector newMods; vector> newSources; // emplace only adds if key is unique modsAvailable.emplace(language, newMods); installSources.emplace(language, newSources); modsAvailable[language].push_back(string(curMod->getName())); pair p(string(curMod->getName()), src.second); installSources[language].push_back(p); } } } return modsAvailable; } void libbible::terminateDownload() { installMgr->terminate(); } 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()); if(installMgr->installModule(&mgr, 0, name.c_str(), p.second) == 0) { return true; } return false; } } return false; } void libbible::installModFromZip(string filename) { // So... turns out it's a mite unsupported to install from a .zip // Here's the deal. We do a syscall to unzip. We fancy like that. // TODO: Use the ZipCompress module from SWORD instead. string command = "unzip -o " + filename + " -d " + basedir + "&> /dev/null"; if(system(command.c_str())) { //Uh oh... printf("Something bad happened when unpacking %s\n", filename.c_str()); } } void libbible::uninstallMod(string modname) { sword::SWMgr mgr(basedir.c_str()); sword::ModMap::iterator it = mgr.Modules.find(modname.c_str()); if(it != mgr.Modules.end()) { installMgr->removeModule(&mgr, it->second->getName()); } }