Procházet zdrojové kódy

don't needlessly redownload contents.xml

David Rose před 16 roky
rodič
revize
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.
         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"
         packages that were preloaded before starting the application.
         If for some reason the package isn't already downloaded, this
         will download it on the spot.  Raises OSError on failure. """
 
         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:
             platform = None
@@ -894,6 +897,8 @@ def dummyAppRunner(tokens = [], argv = None):
     
     if platform.startswith('win'):
         rootDir = Filename(Filename.getUserAppdataDirectory(), 'Panda3D')
+    elif platform.startswith('osx'):
+        rootDir = Filename(Filename.getHomeDirectory(), 'Library/Caches/Panda3D')
     else:
         rootDir = Filename(Filename.getHomeDirectory(), '.panda3d')
 

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

@@ -164,17 +164,31 @@ class HostInfo:
             return False
 
 
-    def readContentsFile(self, tempFilename):
+    def readContentsFile(self, tempFilename = None):
         """ Reads the contents.xml file for this particular host, once
         it has been downloaded into the indicated temporary file.
         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'):
             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())
         if not doc.LoadFile():
@@ -256,8 +270,7 @@ class HostInfo:
             self.descriptiveName = descriptiveName
 
         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
         # 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.
 
+packager.setHost('file:///Users/drose/p3dstage',
+                 descriptiveName = 'local odysseus', hostDir = 'odysseus')
+
 class coreapi(solo):
     # The special "coreapi" package.  As a "solo", this is just a
     # single .dll (or dylib, or whatever).

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

@@ -15,6 +15,7 @@
 #include "p3dHost.h"
 #include "p3dInstanceManager.h"
 #include "p3dPackage.h"
+#include "mkdir_complete.h"
 #include "openssl/md5.h"
 
 #include <algorithm>
@@ -97,6 +98,25 @@ get_alt_host(const string &alt_host) {
   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
 //       Access: Public
@@ -163,16 +183,63 @@ read_contents_file(const string &contents_filename) {
     determine_host_dir("");
   }
   assert(!_host_dir.empty());
+  mkdir_complete(_host_dir, nout);
 
   string standard_filename = _host_dir + "/contents.xml";
   if (standardize_filename(standard_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;
 }
 
+////////////////////////////////////////////////////////////////////
+//     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
 //       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

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

@@ -46,7 +46,9 @@ public:
   inline int get_contents_seq() const;
   inline bool check_contents_hash(const string &pathname) const;
 
+  bool read_contents_file();
   bool read_contents_file(const string &contents_filename);
+  void read_xhost(TiXmlElement *xhost);
 
   P3DPackage *get_package(const string &package_name, 
                           const string &package_version,
@@ -64,7 +66,6 @@ public:
 
 private:
   void determine_host_dir(const string &host_dir_basename);
-  void read_xhost(TiXmlElement *xhost);
 
   static string standardize_filename(const string &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);
     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);
   add_package(package);
@@ -1822,6 +1828,35 @@ find_alt_host_url(const string &host_url, const string &alt_host) {
   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
 //       Access: Private

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

@@ -169,6 +169,7 @@ private:
   void mark_p3d_trusted();
   void scan_app_desc_file(TiXmlDocument *doc);
   string find_alt_host_url(const string &host_url, const string &alt_host);
+  void get_host_info(P3DHost *host);
 
   void send_browser_script_object();
   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("host", _host->get_host_url());
+  xpackage->SetAttribute("host_dir", _host->get_host_dir());
 
   return xpackage;
 }
@@ -268,14 +269,12 @@ begin_info_download() {
 ////////////////////////////////////////////////////////////////////
 void P3DPackage::
 download_contents_file() {
-  /*
   P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
   if (!_host->has_contents_file() && !inst_mgr->get_verify_contents()) {
     // If we're allowed to read a contents file without checking the
     // server first, try it now.
     _host->read_contents_file();
   }
-  */
 
   if (_host->has_contents_file()) {
     // 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.
       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.
         report_done(false);
         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 *version = xpackage->Attribute("version");
   const char *host = xpackage->Attribute("host");
+  const char *host_dir = xpackage->Attribute("host_dir");
   if (name == NULL || host == NULL) {
     return;
   }
@@ -1233,10 +1234,13 @@ add_package_info(P3DCInstance *inst, TiXmlElement *xpackage) {
   if (platform == NULL) {
     platform = "";
   }
+  if (host_dir == NULL) {
+    host_dir = "";
+  }
 
   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) {
     PyErr_Print();