aboutsummaryrefslogtreecommitdiff
path: root/mods.cc
blob: c30fce437cd83a497810b4cfc103eef569ce7365 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#include "libbible.h"
#include <sword/swmgr.h>
#include <sword/swmodule.h>
#include <sword/installmgr.h>
#include <sword/filemgr.h>
#include <sword/remotetrans.h>

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<string, vector<pair<string, sword::InstallSource *>>> installSources;

map<string, vector<string>> 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->readInstallConf();
    installMgr->refreshRemoteSourceConfiguration();
    map<string, vector<string>> 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<string> newMods;
                vector<pair<string, sword::InstallSource *>> newSources;
                // emplace only adds if key is unique
                modsAvailable.emplace(language, newMods);
                installSources.emplace(language, newSources);
                modsAvailable[language].push_back(string(curMod->getName()));
                pair<string, sword::InstallSource *> p(string(curMod->getName()), src.second);
                installSources[language].push_back(p);
            }
        }
    }
    return modsAvailable;
}

void libbible::terminateDownload() {
    installMgr->terminate();
}

void libbible::installModFromInternet(string language, string name) {
    // Searching through map<string, vector<pair<string, sword::InstallSource *>>> installSources;
    for (pair<string, sword::InstallSource *> p : installSources[language]) {
        if(p.first == name) {
            sword::SWMgr mgr(basedir.c_str());
            installMgr->installModule(&mgr, 0, name.c_str(), p.second);
            break;
        }
    }
}

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());
    installMgr->removeModule(&mgr, it->second->getName());
}