Browse Source

don't needlessly redownload contents.xml

David Rose 16 years ago
parent
commit
09483f7133

+ 9 - 4
direct/src/p3d/AppRunner.py

@@ -521,17 +521,20 @@ class AppRunner(DirectObject):
         # The "super mirror" URL, generally used only by panda3d.exe.
         # The "super mirror" URL, generally used only by panda3d.exe.
         self.superMirrorUrl = superMirrorUrl
         self.superMirrorUrl = superMirrorUrl
 
 
-    def addPackageInfo(self, name, platform, version, hostUrl):
+    def addPackageInfo(self, name, platform, version, hostUrl, hostDir = None):
         """ Called by the browser for each one of the "required"
         """ Called by the browser for each one of the "required"
         packages that were preloaded before starting the application.
         packages that were preloaded before starting the application.
         If for some reason the package isn't already downloaded, this
         If for some reason the package isn't already downloaded, this
         will download it on the spot.  Raises OSError on failure. """
         will download it on the spot.  Raises OSError on failure. """
 
 
         host = self.getHost(hostUrl)
         host = self.getHost(hostUrl)
+        if hostDir and not host.hostDir:
+            host.hostDir = hostDir
 
 
-        if not host.downloadContentsFile(self.http):
-            message = "Host %s cannot be downloaded, cannot preload %s." % (hostUrl, name)
-            raise OSError, message
+        if not host.readContentsFile():
+            if not host.downloadContentsFile(self.http):
+                message = "Host %s cannot be downloaded, cannot preload %s." % (hostUrl, name)
+                raise OSError, message
 
 
         if not platform:
         if not platform:
             platform = None
             platform = None
@@ -894,6 +897,8 @@ def dummyAppRunner(tokens = [], argv = None):
     
     
     if platform.startswith('win'):
     if platform.startswith('win'):
         rootDir = Filename(Filename.getUserAppdataDirectory(), 'Panda3D')
         rootDir = Filename(Filename.getUserAppdataDirectory(), 'Panda3D')
+    elif platform.startswith('osx'):
+        rootDir = Filename(Filename.getHomeDirectory(), 'Library/Caches/Panda3D')
     else:
     else:
         rootDir = Filename(Filename.getHomeDirectory(), '.panda3d')
         rootDir = Filename(Filename.getHomeDirectory(), '.panda3d')
 
 

+ 19 - 6
direct/src/p3d/HostInfo.py

@@ -164,17 +164,31 @@ class HostInfo:
             return False
             return False
 
 
 
 
-    def readContentsFile(self, tempFilename):
+    def readContentsFile(self, tempFilename = None):
         """ Reads the contents.xml file for this particular host, once
         """ Reads the contents.xml file for this particular host, once
         it has been downloaded into the indicated temporary file.
         it has been downloaded into the indicated temporary file.
         Returns true on success, false if the contents file is not
         Returns true on success, false if the contents file is not
-        already on disk or is unreadable.  On success, copies the file
-        into the standard location if it's not there already. """
+        already on disk or is unreadable.
 
 
-        assert not self.hasContentsFile
+        If tempFilename is specified, it is the filename read, and it
+        is copied the file into the standard location if it's not
+        there already.  If tempFilename is not specified, the standard
+        filename is read if it is known. """
+
+        if self.hasContentsFile:
+            # No need to read it again.
+            return True
 
 
         if not hasattr(PandaModules, 'TiXmlDocument'):
         if not hasattr(PandaModules, 'TiXmlDocument'):
             return False
             return False
+
+        if not tempFilename:
+            if not self.hostDir:
+                # If the filename is not specified, we can infer it
+                # only if we already know our hostDir.
+                return False
+            
+            tempFilename = Filename(self.hostDir, 'contents.xml')
         
         
         doc = PandaModules.TiXmlDocument(tempFilename.toOsSpecific())
         doc = PandaModules.TiXmlDocument(tempFilename.toOsSpecific())
         if not doc.LoadFile():
         if not doc.LoadFile():
@@ -256,8 +270,7 @@ class HostInfo:
             self.descriptiveName = descriptiveName
             self.descriptiveName = descriptiveName
 
 
         hostDirBasename = xhost.Attribute('host_dir')
         hostDirBasename = xhost.Attribute('host_dir')
-        if hostDirBasename and not self.hostDir:
-            self.__determineHostDir(hostDirBasename)
+        self.__determineHostDir(hostDirBasename)
 
 
         # Get the "download" URL, which is the source from which we
         # Get the "download" URL, which is the source from which we
         # download everything other than the contents.xml file.
         # download everything other than the contents.xml file.

+ 3 - 0
direct/src/p3d/coreapi.pdef

@@ -19,6 +19,9 @@ from pandac.PandaModules import getModelPath, Filename, ConfigVariableFilename
 
 
 # Also see panda3d.pdef.
 # Also see panda3d.pdef.
 
 
+packager.setHost('file:///Users/drose/p3dstage',
+                 descriptiveName = 'local odysseus', hostDir = 'odysseus')
+
 class coreapi(solo):
 class coreapi(solo):
     # The special "coreapi" package.  As a "solo", this is just a
     # The special "coreapi" package.  As a "solo", this is just a
     # single .dll (or dylib, or whatever).
     # single .dll (or dylib, or whatever).

+ 68 - 43
direct/src/plugin/p3dHost.cxx

@@ -15,6 +15,7 @@
 #include "p3dHost.h"
 #include "p3dHost.h"
 #include "p3dInstanceManager.h"
 #include "p3dInstanceManager.h"
 #include "p3dPackage.h"
 #include "p3dPackage.h"
+#include "mkdir_complete.h"
 #include "openssl/md5.h"
 #include "openssl/md5.h"
 
 
 #include <algorithm>
 #include <algorithm>
@@ -97,6 +98,25 @@ get_alt_host(const string &alt_host) {
   return this;
   return this;
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: P3DHost::read_contents_file
+//       Access: Public
+//  Description: Reads the contents.xml file in the standard
+//               filename, if possible.
+//
+//               Returns true on success, false on failure.
+////////////////////////////////////////////////////////////////////
+bool P3DHost::
+read_contents_file() {
+  if (_host_dir.empty()) {
+    // If we haven't got a host_dir yet, we can't read the contents.
+    return false;
+  }
+
+  string standard_filename = _host_dir + "/contents.xml";
+  return read_contents_file(standard_filename);
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: P3DHost::read_contents_file
 //     Function: P3DHost::read_contents_file
 //       Access: Public
 //       Access: Public
@@ -163,16 +183,63 @@ read_contents_file(const string &contents_filename) {
     determine_host_dir("");
     determine_host_dir("");
   }
   }
   assert(!_host_dir.empty());
   assert(!_host_dir.empty());
+  mkdir_complete(_host_dir, nout);
 
 
   string standard_filename = _host_dir + "/contents.xml";
   string standard_filename = _host_dir + "/contents.xml";
   if (standardize_filename(standard_filename) != 
   if (standardize_filename(standard_filename) != 
       standardize_filename(contents_filename)) {
       standardize_filename(contents_filename)) {
-    copy_file(contents_filename, standard_filename);
+    if (!copy_file(contents_filename, standard_filename)) {
+      nout << "Couldn't copy to " << standard_filename << "\n";
+    }
   }
   }
 
 
   return true;
   return true;
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: P3DHost::read_xhost
+//       Access: Public
+//  Description: Reads the host data from the <host> (or <alt_host>)
+//               entry in the contents.xml file, or from a
+//               p3d_info.xml file.
+////////////////////////////////////////////////////////////////////
+void P3DHost::
+read_xhost(TiXmlElement *xhost) {
+  const char *descriptive_name = xhost->Attribute("descriptive_name");
+  if (descriptive_name != NULL && _descriptive_name.empty()) {
+    _descriptive_name = descriptive_name;
+  }
+
+  const char *host_dir_basename = xhost->Attribute("host_dir");
+  if (host_dir_basename == NULL) {
+    host_dir_basename = "";
+  }
+  determine_host_dir(host_dir_basename);
+
+  // Get the "download" URL, which is the source from which we
+  // download everything other than the contents.xml file.
+  const char *download_url = xhost->Attribute("download_url");
+  if (download_url != NULL) {
+    _download_url_prefix = download_url;
+  }
+  if (!_download_url_prefix.empty()) {
+    if (_download_url_prefix[_download_url_prefix.size() - 1] != '/') {
+      _download_url_prefix += "/";
+    }
+  } else {
+    _download_url_prefix = _host_url_prefix;
+  }
+        
+  TiXmlElement *xmirror = xhost->FirstChildElement("mirror");
+  while (xmirror != NULL) {
+    const char *url = xmirror->Attribute("url");
+    if (url != NULL) {
+      add_mirror(url);
+    }
+    xmirror = xmirror->NextSiblingElement("mirror");
+  }
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: P3DHost::get_package
 //     Function: P3DHost::get_package
 //       Access: Public
 //       Access: Public
@@ -455,48 +522,6 @@ determine_host_dir(const string &host_dir_basename) {
   }
   }
 }
 }
 
 
-////////////////////////////////////////////////////////////////////
-//     Function: P3DHost::read_xhost
-//       Access: Private
-//  Description: Reads the host data from the <host> (or <alt_host>)
-//               entry in the contents.xml file.
-////////////////////////////////////////////////////////////////////
-void P3DHost::
-read_xhost(TiXmlElement *xhost) {
-  const char *descriptive_name = xhost->Attribute("descriptive_name");
-  if (descriptive_name != NULL && _descriptive_name.empty()) {
-    _descriptive_name = descriptive_name;
-  }
-
-  const char *host_dir_basename = xhost->Attribute("host_dir");
-  if (host_dir_basename != NULL && _host_dir.empty()) {
-    determine_host_dir(host_dir_basename);
-  }
-
-  // Get the "download" URL, which is the source from which we
-  // download everything other than the contents.xml file.
-  const char *download_url = xhost->Attribute("download_url");
-  if (download_url != NULL) {
-    _download_url_prefix = download_url;
-  }
-  if (!_download_url_prefix.empty()) {
-    if (_download_url_prefix[_download_url_prefix.size() - 1] != '/') {
-      _download_url_prefix += "/";
-    }
-  } else {
-    _download_url_prefix = _host_url_prefix;
-  }
-        
-  TiXmlElement *xmirror = xhost->FirstChildElement("mirror");
-  while (xmirror != NULL) {
-    const char *url = xmirror->Attribute("url");
-    if (url != NULL) {
-      add_mirror(url);
-    }
-    xmirror = xmirror->NextSiblingElement("mirror");
-  }
-}
-
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: P3DHost::standardize_filename
 //     Function: P3DHost::standardize_filename

+ 2 - 1
direct/src/plugin/p3dHost.h

@@ -46,7 +46,9 @@ public:
   inline int get_contents_seq() const;
   inline int get_contents_seq() const;
   inline bool check_contents_hash(const string &pathname) const;
   inline bool check_contents_hash(const string &pathname) const;
 
 
+  bool read_contents_file();
   bool read_contents_file(const string &contents_filename);
   bool read_contents_file(const string &contents_filename);
+  void read_xhost(TiXmlElement *xhost);
 
 
   P3DPackage *get_package(const string &package_name, 
   P3DPackage *get_package(const string &package_name, 
                           const string &package_version,
                           const string &package_version,
@@ -64,7 +66,6 @@ public:
 
 
 private:
 private:
   void determine_host_dir(const string &host_dir_basename);
   void determine_host_dir(const string &host_dir_basename);
-  void read_xhost(TiXmlElement *xhost);
 
 
   static string standardize_filename(const string &filename);
   static string standardize_filename(const string &filename);
   static bool copy_file(const string &from_filename, const string &to_filename);
   static bool copy_file(const string &from_filename, const string &to_filename);

+ 35 - 0
direct/src/plugin/p3dInstance.cxx

@@ -912,6 +912,12 @@ add_package(const string &name, const string &version, P3DHost *host) {
     host = inst_mgr->get_host(alt_host_url);
     host = inst_mgr->get_host(alt_host_url);
     alt_host.clear();
     alt_host.clear();
   }
   }
+
+  if (!host->has_contents_file()) {
+    // Since we haven't downloaded this host's contents.xml file yet,
+    // get its additional host information.
+    get_host_info(host);
+  }
   
   
   P3DPackage *package = host->get_package(name, version, alt_host);
   P3DPackage *package = host->get_package(name, version, alt_host);
   add_package(package);
   add_package(package);
@@ -1822,6 +1828,35 @@ find_alt_host_url(const string &host_url, const string &alt_host) {
   return string();
   return string();
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: P3DInstance::get_host_info
+//       Access: Private
+//  Description: Looks in the p3d_info.xml file for the auxiliary host
+//               information for the selected host.  Some of this
+//               information is helpful to have before the host has
+//               read its own contents.xml file (particularly the
+//               host_dir specification).
+////////////////////////////////////////////////////////////////////
+void P3DInstance::
+get_host_info(P3DHost *host) {
+  // We should only call this function if we haven't already read the
+  // host's more-authoritative contents.xml file.
+  assert(!host->has_contents_file());
+
+  TiXmlElement *xhost = _xpackage->FirstChildElement("host");
+  while (xhost != NULL) {
+    const char *url = xhost->Attribute("url");
+    if (url != NULL && host->get_host_url() == url) {
+      // Found the entry for this particular host.
+      host->read_xhost(xhost);
+      return;
+    }
+    xhost = xhost->NextSiblingElement("host");
+  }
+
+  // Didn't find an entry for this host; oh well.
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: P3DInstance::send_browser_script_object
 //     Function: P3DInstance::send_browser_script_object
 //       Access: Private
 //       Access: Private

+ 1 - 0
direct/src/plugin/p3dInstance.h

@@ -169,6 +169,7 @@ private:
   void mark_p3d_trusted();
   void mark_p3d_trusted();
   void scan_app_desc_file(TiXmlDocument *doc);
   void scan_app_desc_file(TiXmlDocument *doc);
   string find_alt_host_url(const string &host_url, const string &alt_host);
   string find_alt_host_url(const string &host_url, const string &alt_host);
+  void get_host_info(P3DHost *host);
 
 
   void send_browser_script_object();
   void send_browser_script_object();
   P3D_request *make_p3d_request(TiXmlElement *xrequest);
   P3D_request *make_p3d_request(TiXmlElement *xrequest);

+ 3 - 3
direct/src/plugin/p3dPackage.cxx

@@ -225,6 +225,7 @@ make_xml() {
     xpackage->SetAttribute("version", _package_version);
     xpackage->SetAttribute("version", _package_version);
   }
   }
   xpackage->SetAttribute("host", _host->get_host_url());
   xpackage->SetAttribute("host", _host->get_host_url());
+  xpackage->SetAttribute("host_dir", _host->get_host_dir());
 
 
   return xpackage;
   return xpackage;
 }
 }
@@ -268,14 +269,12 @@ begin_info_download() {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void P3DPackage::
 void P3DPackage::
 download_contents_file() {
 download_contents_file() {
-  /*
   P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
   P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
   if (!_host->has_contents_file() && !inst_mgr->get_verify_contents()) {
   if (!_host->has_contents_file() && !inst_mgr->get_verify_contents()) {
     // If we're allowed to read a contents file without checking the
     // If we're allowed to read a contents file without checking the
     // server first, try it now.
     // server first, try it now.
     _host->read_contents_file();
     _host->read_contents_file();
   }
   }
-  */
 
 
   if (_host->has_contents_file()) {
   if (_host->has_contents_file()) {
     // We've already got a contents.xml file; go straight to the
     // We've already got a contents.xml file; go straight to the
@@ -310,7 +309,8 @@ contents_file_download_finished(bool success) {
 
 
       // Maybe we can read an already-downloaded contents.xml file.
       // Maybe we can read an already-downloaded contents.xml file.
       string standard_filename = _host->get_host_dir() + "/contents.xml";
       string standard_filename = _host->get_host_dir() + "/contents.xml";
-      if (!_host->read_contents_file(standard_filename)) {
+      if (_host->get_host_dir().empty() || 
+          !_host->read_contents_file(standard_filename)) {
         // Couldn't even read that.  Fail.
         // Couldn't even read that.  Fail.
         report_done(false);
         report_done(false);
         delete _temp_contents_file;
         delete _temp_contents_file;

+ 6 - 2
direct/src/plugin/p3dPythonRun.cxx

@@ -1224,6 +1224,7 @@ add_package_info(P3DCInstance *inst, TiXmlElement *xpackage) {
   const char *platform = xpackage->Attribute("platform");
   const char *platform = xpackage->Attribute("platform");
   const char *version = xpackage->Attribute("version");
   const char *version = xpackage->Attribute("version");
   const char *host = xpackage->Attribute("host");
   const char *host = xpackage->Attribute("host");
+  const char *host_dir = xpackage->Attribute("host_dir");
   if (name == NULL || host == NULL) {
   if (name == NULL || host == NULL) {
     return;
     return;
   }
   }
@@ -1233,10 +1234,13 @@ add_package_info(P3DCInstance *inst, TiXmlElement *xpackage) {
   if (platform == NULL) {
   if (platform == NULL) {
     platform = "";
     platform = "";
   }
   }
+  if (host_dir == NULL) {
+    host_dir = "";
+  }
 
 
   PyObject *result = PyObject_CallMethod
   PyObject *result = PyObject_CallMethod
-    (_runner, (char *)"addPackageInfo", (char *)"ssss",
-     name, platform, version, host);
+    (_runner, (char *)"addPackageInfo", (char *)"sssss",
+     name, platform, version, host, host_dir);
 
 
   if (result == NULL) {
   if (result == NULL) {
     PyErr_Print();
     PyErr_Print();