support host_dir

This commit is contained in:
David Rose 2009-11-19 23:59:04 +00:00
parent 95bff4b0e0
commit 4631711957
8 changed files with 91 additions and 55 deletions

View File

@ -529,7 +529,6 @@ class AppRunner(DirectObject):
host = self.getHost(hostUrl)
if not host.readContentsFile():
if not host.downloadContentsFile(self.http):
message = "Host %s cannot be downloaded, cannot preload %s." % (hostUrl, name)
raise OSError, message

View File

@ -30,6 +30,10 @@ class HostInfo:
self.hostDir = hostDir
self.asMirror = asMirror
self.importsDir = None
if self.hostDir:
self.importsDir = Filename(self.hostDir, 'imports')
# hostUrlPrefix is the host URL, but it is guaranteed to end
# with a slash.
self.hostUrlPrefix = hostUrl
@ -64,12 +68,6 @@ class HostInfo:
# will be filled in when the contents file is read.
self.packages = {}
if appRunner:
self.__determineHostDir(appRunner)
assert self.hostDir
self.importsDir = Filename(self.hostDir, 'imports')
def downloadContentsFile(self, http, redownload = False):
""" Downloads the contents.xml file for this particular host,
synchronously, and then reads it. Returns true on success,
@ -118,19 +116,23 @@ class HostInfo:
print "Unable to download %s" % (url)
rf = None
filename = Filename(self.hostDir, 'contents.xml')
tempFilename = Filename.temporary('', 'p3d_', '.xml')
if rf:
filename.makeDir()
f = open(filename.toOsSpecific(), 'wb')
f = open(tempFilename.toOsSpecific(), 'wb')
f.write(rf.getData())
f.close()
if not self.readContentsFile():
print "Failure reading %s" % (filename)
if not self.readContentsFile(tempFilename):
print "Failure reading %s" % (url)
tempFilename.unlink()
return False
return True
# Couldn't download the file. Maybe we should look for a
# previously-downloaded copy already on disk?
return False
def redownloadContentsFile(self, http):
""" Downloads a new contents.xml file in case it has changed.
Returns true if the file has indeed changed, false if it has
@ -141,6 +143,7 @@ class HostInfo:
print "Redownloading %s" % (url)
# Get the hash of the original file.
assert self.hostDir
filename = Filename(self.hostDir, 'contents.xml')
hv1 = HashVal()
hv1.hashFile(filename)
@ -161,21 +164,19 @@ class HostInfo:
return False
def readContentsFile(self):
def readContentsFile(self, tempFilename):
""" Reads the contents.xml file for this particular host, once
it has been downloaded. Returns true on success, false if the
contents file is not already on disk or is unreadable. """
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. """
if self.hasContentsFile:
# No need to read it again.
return True
filename = Filename(self.hostDir, 'contents.xml')
assert not self.hasContentsFile
if not hasattr(PandaModules, 'TiXmlDocument'):
return False
doc = PandaModules.TiXmlDocument(filename.toOsSpecific())
doc = PandaModules.TiXmlDocument(tempFilename.toOsSpecific())
if not doc.LoadFile():
return False
@ -186,6 +187,9 @@ class HostInfo:
# Look for our own entry in the hosts table.
self.__findHostXml(xcontents)
if not self.hostDir:
self.__determineHostDir(None)
# Get the list of packages available for download and/or import.
xpackage = xcontents.FirstChildElement('package')
while xpackage:
@ -212,6 +216,13 @@ class HostInfo:
self.hasContentsFile = True
# Now copy the contents.xml file into the standard location.
assert self.hostDir
filename = Filename(self.hostDir, 'contents.xml')
if filename != tempFilename:
filename.makeDir()
tempFilename.copyTo(filename)
return True
def __findHostXml(self, xcontents):
@ -244,6 +255,10 @@ class HostInfo:
if descriptiveName and not self.descriptiveName:
self.descriptiveName = descriptiveName
hostDirBasename = xhost.Attribute('host_dir')
if hostDirBasename and not self.hostDir:
self.__determineHostDir(hostDirBasename)
# Get the "download" URL, which is the source from which we
# download everything other than the contents.xml file.
downloadUrl = xhost.Attribute('download_url')
@ -333,7 +348,7 @@ class HostInfo:
return packages
def __determineHostDir(self, appRunner):
def __determineHostDir(self, hostDirBasename):
""" Hashes the host URL into a (mostly) unique directory
string, which will be the root of the host's install tree.
Stores the resulting path, as a Filename, in self.hostDir.
@ -341,6 +356,12 @@ class HostInfo:
This code is duplicated in C++, in
P3DHost::determine_host_dir(). """
if hostDirBasename:
# If the contents.xml specified a host_dir parameter, use
# it.
self.hostDir = Filename(self.appRunner.rootDir, hostDirBasename)
return
hostDir = ''
# Look for a server name in the URL. Including this string in the
@ -389,4 +410,4 @@ class HostInfo:
md.hashString(self.hostUrl)
hostDir += md.asHex()[:keepHash * 2]
self.hostDir = Filename(appRunner.rootDir, hostDir)
self.hostDir = Filename(self.appRunner.rootDir, hostDir)

View File

@ -218,10 +218,12 @@ class Packager:
class HostEntry:
def __init__(self, url = None, downloadUrl = None,
descriptiveName = None, mirrors = None):
descriptiveName = None, hostDir = None,
mirrors = None):
self.url = url
self.downloadUrl = downloadUrl
self.descriptiveName = descriptiveName
self.hostDir = hostDir
self.mirrors = mirrors or []
self.altHosts = {}
@ -229,6 +231,7 @@ class Packager:
self.url = xhost.Attribute('url')
self.downloadUrl = xhost.Attribute('download_url')
self.descriptiveName = xhost.Attribute('descriptive_name')
self.hostDir = xhost.Attribute('host_dir')
self.mirrors = []
xmirror = xhost.FirstChildElement('mirror')
while xmirror:
@ -251,6 +254,8 @@ class Packager:
xhost.SetAttribute('download_url', self.downloadUrl)
if self.descriptiveName:
xhost.SetAttribute('descriptive_name', self.descriptiveName)
if self.hostDir:
xhost.SetAttribute('host_dir', self.hostDir)
for mirror in self.mirrors:
xmirror = TiXmlElement('mirror')
@ -1823,16 +1828,18 @@ class Packager:
self.contents = {}
def setHost(self, host, downloadUrl = None,
descriptiveName = None, mirrors = None):
descriptiveName = None, hostDir = None,
mirrors = None):
""" Specifies the URL that will ultimately host these
contents. """
self.host = host
self.addHost(host, downloadUrl = downloadUrl,
descriptiveName = descriptiveName, mirrors = mirrors)
descriptiveName = descriptiveName, hostDir = hostDir,
mirrors = mirrors)
def addHost(self, host, downloadUrl = None, descriptiveName = None,
mirrors = None):
hostDir = None, mirrors = None):
""" Adds a host to the list of known download hosts. This
information will be written into any p3d files that reference
this host; this can be used to pre-define the possible mirrors
@ -1853,7 +1860,7 @@ class Packager:
# Define a new host entry
he = self.HostEntry(host, downloadUrl = downloadUrl,
descriptiveName = descriptiveName,
mirrors = mirrors)
hostDir = hostDir, mirrors = mirrors)
self.hosts[host] = he
else:
# Update an existing host entry
@ -1861,14 +1868,16 @@ class Packager:
he.downloadUrl = downloadUrl
if descriptiveName is not None:
he.descriptiveName = descriptiveName
if hostDir is not None:
he.hostDir = hostDir
if mirrors is not None:
he.mirrors = mirrors
return he
def addAltHost(self, keyword, altHost, origHost = None,
downloadUrl = None,
descriptiveName = None, mirrors = None):
downloadUrl = None, descriptiveName = None,
hostDir = None, mirrors = None):
""" Adds an alternate host to any already-known host. This
defines an alternate server that may be contacted, if
specified on the HTML page, which hosts a different version of
@ -1880,7 +1889,8 @@ class Packager:
origHost = self.host
self.addHost(altHost, downloadUrl = downloadUrl,
descriptiveName = descriptiveName, mirrors = mirrors)
descriptiveName = descriptiveName, hostDir = hostDir,
mirrors = mirrors)
he = self.addHost(origHost)
he.altHosts[keyword] = altHost

View File

@ -16,6 +16,8 @@ from pandac.PandaModules import Filename, PandaSystem, getModelPath
# Also see coreapi.pdef.
packager.setHost('file:///home/drose/p3dstage', hostDir = 'droseDir')
class panda3d(package):
# The main Panda3D package. Contains Python and most of the graphics
# code in Panda3D.

View File

@ -21,6 +21,7 @@
////////////////////////////////////////////////////////////////////
inline const string &P3DHost::
get_host_dir() const {
assert(!_host_dir.empty());
return _host_dir;
}

View File

@ -38,8 +38,6 @@ P3DHost(const string &host_url) :
_xcontents = NULL;
_contents_seq = 0;
determine_host_dir();
}
////////////////////////////////////////////////////////////////////
@ -99,20 +97,6 @@ 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() {
string standard_filename = _host_dir + "/contents.xml";
return read_contents_file(standard_filename);
}
////////////////////////////////////////////////////////////////////
// Function: P3DHost::read_contents_file
// Access: Public
@ -175,6 +159,11 @@ read_contents_file(const string &contents_filename) {
}
}
if (_host_dir.empty()) {
determine_host_dir("");
}
assert(!_host_dir.empty());
string standard_filename = _host_dir + "/contents.xml";
if (standardize_filename(standard_filename) !=
standardize_filename(contents_filename)) {
@ -389,11 +378,19 @@ add_mirror(string mirror_url) {
// HostInfo.determineHostDir().
////////////////////////////////////////////////////////////////////
void P3DHost::
determine_host_dir() {
determine_host_dir(const string &host_dir_basename) {
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
_host_dir = inst_mgr->get_root_dir();
_host_dir += "/";
if (!host_dir_basename.empty()) {
// If the contents.xml specified a host_dir parameter, use it.
_host_dir += host_dir_basename;
return;
}
// If we didn't get a host_dir parameter, we have to make one up.
string hostname;
// Look for a server name in the URL. Including this string in the
@ -471,6 +468,11 @@ read_xhost(TiXmlElement *xhost) {
_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");

View File

@ -46,7 +46,6 @@ 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);
P3DPackage *get_package(const string &package_name,
@ -64,7 +63,7 @@ public:
void add_mirror(string mirror_url);
private:
void determine_host_dir();
void determine_host_dir(const string &host_dir_basename);
void read_xhost(TiXmlElement *xhost);
static string standardize_filename(const string &filename);

View File

@ -268,12 +268,14 @@ 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