]> git.mxchange.org Git - flightgear.git/blobdiff - src/Network/HTTPClient.cxx
Interim windows build fix
[flightgear.git] / src / Network / HTTPClient.cxx
index 134c38f929164576a5cc264513bcdd19df120a32..57b6626dd3b6932547512fa9a072867667d5e0db 100644 (file)
@@ -47,11 +47,8 @@ typedef nasal::Ghost<pkg::PackageRef> NasalPackage;
 typedef nasal::Ghost<pkg::CatalogRef> NasalCatalog;
 typedef nasal::Ghost<pkg::InstallRef> NasalInstall;
 
-// #define ENABLE_PACKAGE_SYSTEM 1
 
-namespace {
-  
-  class FGDelegate : public pkg::Delegate
+class FGHTTPClient::FGDelegate : public pkg::Delegate
 {
 public:
   virtual void refreshComplete()
@@ -69,50 +66,55 @@ public:
       r->scheduleToUpdate((*it)->install());
     }
   }
-
-  virtual void failedRefresh(pkg::Catalog* aCat, FailureCode aReason)
+    
+  virtual void catalogRefreshed(pkg::CatalogRef aCat, StatusCode aReason)
   {
+      if (aCat.ptr() == NULL) {
+          SG_LOG(SG_IO, SG_INFO, "refresh of all catalogs done");
+          return;
+      }
+      
     switch (aReason) {
-    case pkg::Delegate::FAIL_SUCCESS:
-        SG_LOG(SG_IO, SG_WARN, "refresh of Catalog done");
+    case pkg::Delegate::STATUS_SUCCESS:
+    case pkg::Delegate::STATUS_REFRESHED:
+        SG_LOG(SG_IO, SG_INFO, "refresh of Catalog done:" << aCat->url());
         break;
-        
+            
+    case pkg::Delegate::STATUS_IN_PROGRESS:
+        SG_LOG(SG_IO, SG_INFO, "refresh of Catalog started:" << aCat->url());
+        break;
+            
     default:
         SG_LOG(SG_IO, SG_WARN, "refresh of Catalog " << aCat->url() << " failed:" << aReason);
     }
   }
   
-  virtual void startInstall(pkg::Install* aInstall)
+  virtual void startInstall(pkg::InstallRef aInstall)
   {
-    SG_LOG(SG_IO, SG_INFO, "begining install of:" << aInstall->package()->id()
+    SG_LOG(SG_IO, SG_INFO, "beginning install of:" << aInstall->package()->id()
            << " to local path:" << aInstall->path());
 
   }
   
-  virtual void installProgress(pkg::Install* aInstall, unsigned int aBytes, unsigned int aTotal)
+  virtual void installProgress(pkg::InstallRef aInstall, unsigned int aBytes, unsigned int aTotal)
   {
-    SG_LOG(SG_IO, SG_INFO, "installing:" << aInstall->package()->id() << ":"
-           << aBytes << " of " << aTotal);
   }
   
-  virtual void finishInstall(pkg::Install* aInstall)
+  virtual void finishInstall(pkg::InstallRef aInstall, StatusCode aReason)
   {
+      if (aReason == STATUS_SUCCESS) {
     SG_LOG(SG_IO, SG_INFO, "finished install of:" << aInstall->package()->id()
            << " to local path:" << aInstall->path());
+      } else {
+          SG_LOG(SG_IO, SG_WARN, "install failed of:" << aInstall->package()->id()
+                 << " to local path:" << aInstall->path());
+      }
 
   }
-  
-  virtual void failedInstall(pkg::Install* aInstall, FailureCode aReason)
-  {
-    SG_LOG(SG_IO, SG_WARN, "install failed of:" << aInstall->package()->id()
-           << " to local path:" << aInstall->path());
-  }
-
-};
+}; // of FGHTTPClient::FGDelegate
 
-} // of anonymous namespace
-
-FGHTTPClient::FGHTTPClient()
+FGHTTPClient::FGHTTPClient() :
+    _inited(false)
 {
 }
 
@@ -122,6 +124,12 @@ FGHTTPClient::~FGHTTPClient()
 
 void FGHTTPClient::init()
 {
+    // launcher may need to setup HTTP access abnormally early, so
+    // guard against duplicate inits
+    if (_inited) {
+        return;
+    }
+
   _http.reset(new simgear::HTTP::Client);
   
   std::string proxyHost(fgGetString("/sim/presets/proxy/host"));
@@ -132,27 +140,68 @@ void FGHTTPClient::init()
     _http->setProxy(proxyHost, proxyPort, proxyAuth);
   }
   
-#ifdef ENABLE_PACKAGE_SYSTEM
   pkg::Root* packageRoot = globals->packageRoot();
   if (packageRoot) {
     // package system needs access to the HTTP engine too
     packageRoot->setHTTPClient(_http.get());
     
-    packageRoot->setDelegate(new FGDelegate);
-    
-    // setup default catalog if not present
-    pkg::Catalog* defaultCatalog = packageRoot->getCatalogById("org.flightgear.default");
-    if (!defaultCatalog) {
-      // always show this message
-      SG_LOG(SG_GENERAL, SG_ALERT, "default catalog not found, installing...");
-      pkg::Catalog::createFromUrl(packageRoot,
-          "http://fgfs.goneabitbursar.com/pkg/" FLIGHTGEAR_VERSION "/default-catalog.xml");
-    }
+    _packageDelegate.reset(new FGDelegate);
+    packageRoot->addDelegate(_packageDelegate.get());
     
     // start a refresh now
     packageRoot->refresh();
   }
-#endif // of ENABLE_PACKAGE_SYSTEM
+
+    _inited = true;
+}
+
+namespace {
+
+std::string _getDefaultCatalogId()
+{
+    return fgGetString("/sim/package-system/default-catalog/id", "org.flightgear.official" );
+}
+
+pkg::CatalogRef getDefaultCatalog()
+{
+    if (!globals->packageRoot())
+        return pkg::CatalogRef();
+
+    return globals->packageRoot()->getCatalogById(_getDefaultCatalogId());
+}
+
+} // of anonymous namespace
+
+bool FGHTTPClient::isDefaultCatalogInstalled() const
+{
+    return getDefaultCatalog().valid();
+}
+
+void FGHTTPClient::addDefaultCatalog()
+{
+    pkg::CatalogRef defaultCatalog = getDefaultCatalog();
+    if (!defaultCatalog.valid()) {
+      pkg::Catalog::createFromUrl(globals->packageRoot(), getDefaultCatalogUrl());
+    }
+}
+
+std::string FGHTTPClient::getDefaultCatalogId() const
+{
+    return _getDefaultCatalogId();
+}
+
+std::string FGHTTPClient::getDefaultCatalogUrl() const
+{
+    return fgGetString("/sim/package-system/default-catalog/url",
+                       "http://fgfs.goneabitbursar.com/pkg/" FLIGHTGEAR_VERSION "/catalog.xml");;
+}
+
+static naRef f_package_existingInstall( pkg::Package& pkg,
+                                        const nasal::CallContext& ctx )
+{
+  return ctx.to_nasal(
+    pkg.existingInstall( ctx.getArg<pkg::Package::InstallCallback>(0) )
+  );
 }
 
 static naRef f_package_uninstall(pkg::Package& pkg, const nasal::CallContext& ctx)
@@ -168,18 +217,25 @@ static naRef f_package_uninstall(pkg::Package& pkg, const nasal::CallContext& ct
 static SGPropertyNode_ptr queryPropsFromHash(const nasal::Hash& h)
 {
     SGPropertyNode_ptr props(new SGPropertyNode);
-    string_list keys(h.keys());
-    string_list::const_iterator it;
-    int tagCount = 0;
-
-    for (it = keys.begin(); it != keys.end(); ++it) {
-        if ((*it == "name") || (*it == "description")) {
-            props->setStringValue(*it, h.get<std::string>(*it));
-        } else if (strutils::starts_with(*it, "rating-")) {
-            props->setIntValue(*it, h.get<int>(*it));
-        } else if (strutils::starts_with(*it, "tag-")) {
-            SGPropertyNode_ptr tag = props->getChild("tag", tagCount++, true);
-            tag->setStringValue(it->substr(4));
+
+    for (nasal::Hash::const_iterator it = h.begin(); it != h.end(); ++it) {
+        std::string const key = it->getKey();
+        if ((key == "name") || (key == "description")) {
+            props->setStringValue(key, it->getValue<std::string>());
+        } else if (strutils::starts_with(key, "rating-")) {
+            props->setIntValue(key, it->getValue<int>());
+        } else if (key == "tags") {
+            string_list tags = it->getValue<string_list>();
+            string_list::const_iterator tagIt;
+            int tagCount = 0;
+            for (tagIt = tags.begin(); tagIt != tags.end(); ++tagIt) {
+                SGPropertyNode_ptr tag = props->getChild("tag", tagCount++, true);
+                tag->setStringValue(*tagIt);
+            }
+        } else if (key == "installed") {
+            props->setBoolValue(key, it->getValue<bool>());
+        } else {
+            SG_LOG(SG_GENERAL, SG_WARN, "unknown filter term in hash:" << key);
         }
     }
 
@@ -200,9 +256,19 @@ static naRef f_catalog_search(pkg::Catalog& cat, const nasal::CallContext& ctx)
     return ctx.to_nasal(result);
 }
 
+static naRef f_package_variants(pkg::Package& pack, naContext c)
+{
+    nasal::Hash h(c);
+    string_list vars(pack.variants());
+    for (string_list_iterator it  = vars.begin(); it != vars.end(); ++it) {
+        h.set(*it, pack.nameForVariant(*it));
+    }
+
+    return h.get_naRef();
+}
+
 void FGHTTPClient::postinit()
 {
-#ifdef ENABLE_PACKAGE_SYSTEM
   NasalPackageRoot::init("PackageRoot")
   .member("path", &pkg::Root::path)
   .member("version", &pkg::Root::catalogVersion)
@@ -230,19 +296,30 @@ void FGHTTPClient::postinit()
   .member("description", &pkg::Package::description)
   .member("installed", &pkg::Package::isInstalled)
   .member("thumbnails", &pkg::Package::thumbnailUrls)
+  .member("variants", &f_package_variants)
   .member("revision", &pkg::Package::revision)
   .member("catalog", &pkg::Package::catalog)
   .method("install", &pkg::Package::install)
   .method("uninstall", &f_package_uninstall)
-  .method("lprop", &pkg::Package::getLocalisedProp);
+  .method("existingInstall", &f_package_existingInstall)
+  .method("lprop", &pkg::Package::getLocalisedProp)
+  .member("fileSize", &pkg::Package::fileSizeBytes);
   
+  typedef pkg::Install* (pkg::Install::*InstallCallback)
+                        (const pkg::Install::Callback&);
+  typedef pkg::Install* (pkg::Install::*ProgressCallback)
+                        (const pkg::Install::ProgressCallback&);
   NasalInstall::init("Install")
   .member("revision", &pkg::Install::revsion)
   .member("pkg", &pkg::Install::package)
   .member("path", &pkg::Install::path)
   .member("hasUpdate", &pkg::Install::hasUpdate)
   .method("startUpdate", &pkg::Install::startUpdate)
-  .method("uninstall", &pkg::Install::uninstall);
+  .method("uninstall", &pkg::Install::uninstall)
+  .method("done", static_cast<InstallCallback>(&pkg::Install::done))
+  .method("fail", static_cast<InstallCallback>(&pkg::Install::fail))
+  .method("always", static_cast<InstallCallback>(&pkg::Install::always))
+  .method("progress", static_cast<ProgressCallback>(&pkg::Install::progress));
   
   pkg::Root* packageRoot = globals->packageRoot();
   if (packageRoot) {
@@ -251,12 +328,17 @@ void FGHTTPClient::postinit()
     nasal::Hash nasalPkg = nasalGlobals.createHash("pkg"); // module
     nasalPkg.set("root", packageRoot);
   }
-#endif // of ENABLE_PACKAGE_SYSTEM
 }
 
 void FGHTTPClient::shutdown()
 {
-  _http.reset();
+    pkg::Root* packageRoot = globals->packageRoot();
+    if (packageRoot && _packageDelegate.get()) {
+        packageRoot->removeDelegate(_packageDelegate.get());
+    }
+
+    _packageDelegate.reset();
+    _http.reset();
 }
 
 void FGHTTPClient::update(double)