1 // HTTPClient.cxx -- Singleton HTTP client object
3 // Written by James Turner, started April 2012.
5 // Copyright (C) 2012 James Turner
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License as
9 // published by the Free Software Foundation; either version 2 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 // General Public License for more details.
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 #include "HTTPClient.hxx"
25 #include <Main/fg_props.hxx>
26 #include <Include/version.h>
28 #include <simgear/sg_inlines.h>
30 #include <simgear/package/Root.hxx>
31 #include <simgear/package/Catalog.hxx>
32 #include <simgear/package/Delegate.hxx>
33 #include <simgear/package/Install.hxx>
34 #include <simgear/package/Package.hxx>
36 #include <simgear/nasal/cppbind/from_nasal.hxx>
37 #include <simgear/nasal/cppbind/to_nasal.hxx>
38 #include <simgear/nasal/cppbind/NasalHash.hxx>
39 #include <simgear/nasal/cppbind/Ghost.hxx>
41 #include <Scripting/NasalSys.hxx>
43 using namespace simgear;
45 typedef nasal::Ghost<pkg::RootRef> NasalPackageRoot;
46 typedef nasal::Ghost<pkg::PackageRef> NasalPackage;
47 typedef nasal::Ghost<pkg::CatalogRef> NasalCatalog;
48 typedef nasal::Ghost<pkg::InstallRef> NasalInstall;
50 // #define ENABLE_PACKAGE_SYSTEM 1
54 class FGDelegate : public pkg::Delegate
57 virtual void refreshComplete()
59 SG_LOG(SG_IO, SG_INFO, "all Catalogs refreshed");
61 // auto-update; make this controlled by a property
62 pkg::Root* r = globals->packageRoot();
64 pkg::PackageList toBeUpdated(r->packagesNeedingUpdate());
65 pkg::PackageList::const_iterator it;
66 for (it = toBeUpdated.begin(); it != toBeUpdated.end(); ++it) {
67 assert((*it)->isInstalled());
68 SG_LOG(SG_IO, SG_INFO, "updating:" << (*it)->id());
69 r->scheduleToUpdate((*it)->install());
73 virtual void failedRefresh(pkg::Catalog* aCat, FailureCode aReason)
76 case pkg::Delegate::FAIL_SUCCESS:
77 SG_LOG(SG_IO, SG_WARN, "refresh of Catalog done");
81 SG_LOG(SG_IO, SG_WARN, "refresh of Catalog " << aCat->url() << " failed:" << aReason);
85 virtual void startInstall(pkg::Install* aInstall)
87 SG_LOG(SG_IO, SG_INFO, "begining install of:" << aInstall->package()->id()
88 << " to local path:" << aInstall->path());
92 virtual void installProgress(pkg::Install* aInstall, unsigned int aBytes, unsigned int aTotal)
94 SG_LOG(SG_IO, SG_INFO, "installing:" << aInstall->package()->id() << ":"
95 << aBytes << " of " << aTotal);
98 virtual void finishInstall(pkg::Install* aInstall)
100 SG_LOG(SG_IO, SG_INFO, "finished install of:" << aInstall->package()->id()
101 << " to local path:" << aInstall->path());
105 virtual void failedInstall(pkg::Install* aInstall, FailureCode aReason)
107 SG_LOG(SG_IO, SG_WARN, "install failed of:" << aInstall->package()->id()
108 << " to local path:" << aInstall->path());
113 } // of anonymous namespace
115 FGHTTPClient::FGHTTPClient()
119 FGHTTPClient::~FGHTTPClient()
123 void FGHTTPClient::init()
125 _http.reset(new simgear::HTTP::Client);
127 std::string proxyHost(fgGetString("/sim/presets/proxy/host"));
128 int proxyPort(fgGetInt("/sim/presets/proxy/port"));
129 std::string proxyAuth(fgGetString("/sim/presets/proxy/auth"));
131 if (!proxyHost.empty()) {
132 _http->setProxy(proxyHost, proxyPort, proxyAuth);
135 #ifdef ENABLE_PACKAGE_SYSTEM
136 pkg::Root* packageRoot = globals->packageRoot();
138 // package system needs access to the HTTP engine too
139 packageRoot->setHTTPClient(_http.get());
141 packageRoot->setDelegate(new FGDelegate);
143 // setup default catalog if not present
144 pkg::Catalog* defaultCatalog = packageRoot->getCatalogById("org.flightgear.default");
145 if (!defaultCatalog) {
146 // always show this message
147 SG_LOG(SG_GENERAL, SG_ALERT, "default catalog not found, installing...");
148 pkg::Catalog::createFromUrl(packageRoot,
149 "http://fgfs.goneabitbursar.com/pkg/" FLIGHTGEAR_VERSION "/default-catalog.xml");
152 // start a refresh now
153 packageRoot->refresh();
155 #endif // of ENABLE_PACKAGE_SYSTEM
158 void FGHTTPClient::postinit()
160 #ifdef ENABLE_PACKAGE_SYSTEM
161 NasalPackageRoot::init("PackageRoot")
162 .member("path", &pkg::Root::path)
163 .member("version", &pkg::Root::catalogVersion)
164 .method("refresh", &pkg::Root::refresh)
165 .method("catalogs", &pkg::Root::catalogs)
166 .method("packageById", &pkg::Root::getPackageById)
167 .method("catalogById", &pkg::Root::getCatalogById);
169 NasalCatalog::init("Catalog")
170 .member("installRoot", &pkg::Catalog::installRoot)
171 .member("id", &pkg::Catalog::id)
172 .member("url", &pkg::Catalog::url)
173 .member("description", &pkg::Catalog::description)
174 .method("packages", &pkg::Catalog::packages)
175 .method("packageById", &pkg::Catalog::getPackageById)
176 .method("refresh", &pkg::Catalog::refresh)
177 .method("needingUpdate", &pkg::Catalog::packagesNeedingUpdate)
178 .member("installed", &pkg::Catalog::installedPackages);
180 NasalPackage::init("Package")
181 .member("id", &pkg::Package::id)
182 .member("name", &pkg::Package::name)
183 .member("description", &pkg::Package::description)
184 .member("installed", &pkg::Package::isInstalled)
185 .member("thumbnails", &pkg::Package::thumbnailUrls)
186 .member("revision", &pkg::Package::revision)
187 .member("catalog", &pkg::Package::catalog)
188 .method("install", &pkg::Package::install)
189 .method("lprop", &pkg::Package::getLocalisedProp);
191 NasalInstall::init("Install")
192 .member("revision", &pkg::Install::revsion)
193 .member("pkg", &pkg::Install::package)
194 .member("path", &pkg::Install::path)
195 .member("hasUpdate", &pkg::Install::hasUpdate)
196 .method("startUpdate", &pkg::Install::startUpdate)
197 .method("uninstall", &pkg::Install::uninstall);
199 pkg::Root* packageRoot = globals->packageRoot();
201 FGNasalSys* nasalSys = (FGNasalSys*) globals->get_subsystem("nasal");
202 nasal::Hash nasalGlobals = nasalSys->getGlobals();
203 nasal::Hash nasalPkg = nasalGlobals.createHash("pkg"); // module
204 nasalPkg.set("root", packageRoot);
206 #endif // of ENABLE_PACKAGE_SYSTEM
209 void FGHTTPClient::shutdown()
214 void FGHTTPClient::update(double)
219 void FGHTTPClient::makeRequest(const simgear::HTTP::Request_ptr& req)
221 _http->makeRequest(req);