29#include <simgear/sg_inlines.h>
31#include <simgear/package/Root.hxx>
32#include <simgear/package/Catalog.hxx>
33#include <simgear/package/Delegate.hxx>
34#include <simgear/package/Install.hxx>
35#include <simgear/package/Package.hxx>
37#include <simgear/nasal/cppbind/from_nasal.hxx>
38#include <simgear/nasal/cppbind/to_nasal.hxx>
39#include <simgear/nasal/cppbind/NasalHash.hxx>
40#include <simgear/nasal/cppbind/Ghost.hxx>
54static const char*
FALLBACK_CATALOG_URL =
"http://mirrors.ibiblio.org/flightgear/ftp/Aircraft-trunk/catalog.xml";
58 std::string _getDefaultCatalogId()
60 return fgGetString(
"/sim/package-system/default-catalog/id",
64 pkg::CatalogRef getDefaultCatalog()
67 return pkg::CatalogRef();
69 return globals->packageRoot()->getCatalogById(_getDefaultCatalogId());
72 std::string _getDefaultCatalogUrl()
74 return fgGetString(
"/sim/package-system/default-catalog/url",
75 "http://mirrors.ibiblio.org/flightgear/ftp/" FLIGHTGEAR_VERSION
"/catalog.xml");
110 _http.reset(
new simgear::HTTP::Client);
112 std::string proxyHost(
fgGetString(
"/sim/presets/proxy/host"));
113 int proxyPort(
fgGetInt(
"/sim/presets/proxy/port"));
114 std::string proxyAuth(
fgGetString(
"/sim/presets/proxy/auth"));
116 if (!proxyHost.empty()) {
117 _http->setProxy(proxyHost, proxyPort, proxyAuth);
120 pkg::Root* packageRoot =
globals->packageRoot();
123 packageRoot->setHTTPClient(_http.get());
129 packageRoot->refresh(
true);
137 return getDefaultCatalog().valid();
142 pkg::CatalogRef defaultCatalog = getDefaultCatalog();
143 if (!defaultCatalog.valid()) {
148 return defaultCatalog;
153 return _getDefaultCatalogId();
158 return _getDefaultCatalogUrl();
167 const nasal::CallContext& ctx )
170 pkg.existingInstall( ctx.getArg<pkg::Package::InstallCallback>(0) )
176 pkg::InstallRef ins =
pkg.existingInstall();
186 SGPropertyNode_ptr props(
new SGPropertyNode);
188 for (nasal::Hash::const_iterator it = h.begin(); it != h.end(); ++it) {
189 std::string
const key = it->getKey();
190 if ((key ==
"name") || (key ==
"description")) {
191 props->setStringValue(key, it->getValue<std::string>());
192 }
else if (strutils::starts_with(key,
"rating-")) {
193 props->setIntValue(key, it->getValue<
int>());
194 }
else if (key ==
"tags") {
196 string_list::const_iterator tagIt;
198 for (tagIt = tags.begin(); tagIt != tags.end(); ++tagIt) {
199 SGPropertyNode_ptr tag = props->getChild(
"tag", tagCount++,
true);
200 tag->setStringValue(*tagIt);
202 }
else if (key ==
"installed") {
203 props->setBoolValue(key, it->getValue<
bool>());
205 SG_LOG(SG_GENERAL, SG_WARN,
"unknown filter term in hash:" << key);
215 pkg::PackageList result = root.packagesMatching(query);
216 return ctx.to_nasal(result);
222 pkg::PackageList result = cat.packagesMatching(query);
223 return ctx.to_nasal(result);
229 pkg::PackageList result = cat.packages();
230 return ctx.to_nasal(result);
237 pkg::PackageList result = cat.installedPackages();
238 return nasal::to_nasal(c, result);
245 for (string_list_iterator it = vars.begin(); it != vars.end(); ++it) {
246 h.set(*it, pack.nameForVariant(*it));
249 return h.get_naRef();
254 NasalPackageRoot::init(
"PackageRoot")
255 .member(
"path", &pkg::Root::path)
256 .member(
"version", &pkg::Root::catalogVersion)
257 .method(
"refresh", &pkg::Root::refresh)
258 .method(
"catalogs", &pkg::Root::catalogs)
259 .method(
"packageById", &pkg::Root::getPackageById)
260 .method(
"catalogById", &pkg::Root::getCatalogById)
263 NasalCatalog::init(
"Catalog")
264 .member(
"installRoot", &pkg::Catalog::installRoot)
265 .member(
"id", &pkg::Catalog::id)
266 .member(
"url", &pkg::Catalog::url)
267 .member(
"description", &pkg::Catalog::description)
269 .method(
"packageById", &pkg::Catalog::getPackageById)
270 .method(
"refresh", &pkg::Catalog::refresh)
271 .method(
"needingUpdate", &pkg::Catalog::packagesNeedingUpdate)
274 .member(
"enabled", &pkg::Catalog::isEnabled);
276 NasalPackage::init(
"Package")
277 .member(
"id", &pkg::Package::id)
278 .member(
"name", &pkg::Package::name)
279 .member(
"description", &pkg::Package::description)
280 .member(
"installed", &pkg::Package::isInstalled)
281 .member(
"thumbnails", &pkg::Package::thumbnailUrls)
283 .member(
"revision", &pkg::Package::revision)
284 .member(
"catalog", &pkg::Package::catalog)
285 .method(
"install", &pkg::Package::install)
288 .method(
"lprop", &pkg::Package::getLocalisedProp)
289 .member(
"fileSize", &pkg::Package::fileSizeBytes);
291 typedef pkg::Install* (pkg::Install::*InstallCallback)
292 (
const pkg::Install::Callback&);
293 typedef pkg::Install* (pkg::Install::*ProgressCallback)
294 (
const pkg::Install::ProgressCallback&);
295 NasalInstall::init(
"Install")
296 .member(
"revision", &pkg::Install::revsion)
297 .member(
"pkg", &pkg::Install::package)
298 .member(
"path", &pkg::Install::path)
299 .member(
"hasUpdate", &pkg::Install::hasUpdate)
300 .method(
"startUpdate", &pkg::Install::startUpdate)
301 .method(
"uninstall", &pkg::Install::uninstall)
302 .method(
"done",
static_cast<InstallCallback
>(&pkg::Install::done))
303 .method(
"fail",
static_cast<InstallCallback
>(&pkg::Install::fail))
304 .method(
"always",
static_cast<InstallCallback
>(&pkg::Install::always))
305 .method(
"progress",
static_cast<ProgressCallback
>(&pkg::Install::progress));
307 pkg::Root* packageRoot =
globals->packageRoot();
310 nasal::Hash nasalGlobals =
nasalSys->getGlobals();
311 nasal::Hash nasalPkg = nasalGlobals.createHash(
"pkg");
312 nasalPkg.set(
"root", packageRoot);
330 _http->makeRequest(req);
336 SGSubsystemMgr::GENERAL,
337 {{
"nasal", SGSubsystemMgr::Dependency::HARD}});
static naRef f_catalog_packages(pkg::Catalog &cat, const nasal::CallContext &ctx)
static naRef f_root_search(pkg::Root &root, const nasal::CallContext &ctx)
static naRef f_package_existingInstall(pkg::Package &pkg, const nasal::CallContext &ctx)
static naRef f_catalog_installedPackages(pkg::Catalog &cat, naContext c)
nasal::Ghost< pkg::RootRef > NasalPackageRoot
static SGPropertyNode_ptr queryPropsFromHash(const nasal::Hash &h)
static naRef f_package_variants(pkg::Package &pack, naContext c)
static naRef f_catalog_search(pkg::Catalog &cat, const nasal::CallContext &ctx)
nasal::Ghost< pkg::PackageRef > NasalPackage
static const char * OFFICIAL_CATALOG_ID
static naRef f_package_uninstall(pkg::Package &pkg, const nasal::CallContext &ctx)
nasal::Ghost< pkg::InstallRef > NasalInstall
nasal::Ghost< pkg::CatalogRef > NasalCatalog
SGSubsystemMgr::Registrant< FGHTTPClient > registrantFGHTTPClient(SGSubsystemMgr::GENERAL, {{"nasal", SGSubsystemMgr::Dependency::HARD}})
static const char * FALLBACK_CATALOG_URL
static FGNasalSys * nasalSys
bool isDefaultCatalogInstalled() const
void makeRequest(const simgear::HTTP::Request_ptr &req)
static FGHTTPClient * getOrCreate()
std::string getDefaultCatalogId() const
void update(double) override
simgear::pkg::CatalogRef addDefaultCatalog()
std::string getDefaultCatalogFallbackUrl() const
std::string getDefaultCatalogUrl() const
int fgGetInt(const char *name, int defaultValue)
Get an int value for a property.
std::string fgGetString(const char *name, const char *defaultValue)
Get a string value for a property.
std::vector< std::string > string_list