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) host = self.getHost(hostUrl)
if not host.readContentsFile():
if not host.downloadContentsFile(self.http): if not host.downloadContentsFile(self.http):
message = "Host %s cannot be downloaded, cannot preload %s." % (hostUrl, name) message = "Host %s cannot be downloaded, cannot preload %s." % (hostUrl, name)
raise OSError, message raise OSError, message

View File

@ -30,6 +30,10 @@ class HostInfo:
self.hostDir = hostDir self.hostDir = hostDir
self.asMirror = asMirror 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 # hostUrlPrefix is the host URL, but it is guaranteed to end
# with a slash. # with a slash.
self.hostUrlPrefix = hostUrl self.hostUrlPrefix = hostUrl
@ -64,12 +68,6 @@ class HostInfo:
# will be filled in when the contents file is read. # will be filled in when the contents file is read.
self.packages = {} self.packages = {}
if appRunner:
self.__determineHostDir(appRunner)
assert self.hostDir
self.importsDir = Filename(self.hostDir, 'imports')
def downloadContentsFile(self, http, redownload = False): def downloadContentsFile(self, http, redownload = False):
""" Downloads the contents.xml file for this particular host, """ Downloads the contents.xml file for this particular host,
synchronously, and then reads it. Returns true on success, synchronously, and then reads it. Returns true on success,
@ -118,19 +116,23 @@ class HostInfo:
print "Unable to download %s" % (url) print "Unable to download %s" % (url)
rf = None rf = None
filename = Filename(self.hostDir, 'contents.xml') tempFilename = Filename.temporary('', 'p3d_', '.xml')
if rf: if rf:
filename.makeDir() f = open(tempFilename.toOsSpecific(), 'wb')
f = open(filename.toOsSpecific(), 'wb')
f.write(rf.getData()) f.write(rf.getData())
f.close() f.close()
if not self.readContentsFile(): if not self.readContentsFile(tempFilename):
print "Failure reading %s" % (filename) print "Failure reading %s" % (url)
tempFilename.unlink()
return False return False
return True 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): def redownloadContentsFile(self, http):
""" Downloads a new contents.xml file in case it has changed. """ Downloads a new contents.xml file in case it has changed.
Returns true if the file has indeed changed, false if it has Returns true if the file has indeed changed, false if it has
@ -141,6 +143,7 @@ class HostInfo:
print "Redownloading %s" % (url) print "Redownloading %s" % (url)
# Get the hash of the original file. # Get the hash of the original file.
assert self.hostDir
filename = Filename(self.hostDir, 'contents.xml') filename = Filename(self.hostDir, 'contents.xml')
hv1 = HashVal() hv1 = HashVal()
hv1.hashFile(filename) hv1.hashFile(filename)
@ -161,21 +164,19 @@ class HostInfo:
return False return False
def readContentsFile(self): def readContentsFile(self, tempFilename):
""" Reads the contents.xml file for this particular host, once """ Reads the contents.xml file for this particular host, once
it has been downloaded. Returns true on success, false if the it has been downloaded into the indicated temporary file.
contents file is not already on disk or is unreadable. """ 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: assert not self.hasContentsFile
# No need to read it again.
return True
filename = Filename(self.hostDir, 'contents.xml')
if not hasattr(PandaModules, 'TiXmlDocument'): if not hasattr(PandaModules, 'TiXmlDocument'):
return False return False
doc = PandaModules.TiXmlDocument(filename.toOsSpecific()) doc = PandaModules.TiXmlDocument(tempFilename.toOsSpecific())
if not doc.LoadFile(): if not doc.LoadFile():
return False return False
@ -186,6 +187,9 @@ class HostInfo:
# Look for our own entry in the hosts table. # Look for our own entry in the hosts table.
self.__findHostXml(xcontents) self.__findHostXml(xcontents)
if not self.hostDir:
self.__determineHostDir(None)
# Get the list of packages available for download and/or import. # Get the list of packages available for download and/or import.
xpackage = xcontents.FirstChildElement('package') xpackage = xcontents.FirstChildElement('package')
while xpackage: while xpackage:
@ -212,6 +216,13 @@ class HostInfo:
self.hasContentsFile = True 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 return True
def __findHostXml(self, xcontents): def __findHostXml(self, xcontents):
@ -244,6 +255,10 @@ class HostInfo:
if descriptiveName and not self.descriptiveName: if descriptiveName and not self.descriptiveName:
self.descriptiveName = 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 # 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.
downloadUrl = xhost.Attribute('download_url') downloadUrl = xhost.Attribute('download_url')
@ -333,7 +348,7 @@ class HostInfo:
return packages return packages
def __determineHostDir(self, appRunner): def __determineHostDir(self, hostDirBasename):
""" Hashes the host URL into a (mostly) unique directory """ Hashes the host URL into a (mostly) unique directory
string, which will be the root of the host's install tree. string, which will be the root of the host's install tree.
Stores the resulting path, as a Filename, in self.hostDir. Stores the resulting path, as a Filename, in self.hostDir.
@ -341,6 +356,12 @@ class HostInfo:
This code is duplicated in C++, in This code is duplicated in C++, in
P3DHost::determine_host_dir(). """ 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 = '' hostDir = ''
# Look for a server name in the URL. Including this string in the # Look for a server name in the URL. Including this string in the
@ -389,4 +410,4 @@ class HostInfo:
md.hashString(self.hostUrl) md.hashString(self.hostUrl)
hostDir += md.asHex()[:keepHash * 2] 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: class HostEntry:
def __init__(self, url = None, downloadUrl = None, def __init__(self, url = None, downloadUrl = None,
descriptiveName = None, mirrors = None): descriptiveName = None, hostDir = None,
mirrors = None):
self.url = url self.url = url
self.downloadUrl = downloadUrl self.downloadUrl = downloadUrl
self.descriptiveName = descriptiveName self.descriptiveName = descriptiveName
self.hostDir = hostDir
self.mirrors = mirrors or [] self.mirrors = mirrors or []
self.altHosts = {} self.altHosts = {}
@ -229,6 +231,7 @@ class Packager:
self.url = xhost.Attribute('url') self.url = xhost.Attribute('url')
self.downloadUrl = xhost.Attribute('download_url') self.downloadUrl = xhost.Attribute('download_url')
self.descriptiveName = xhost.Attribute('descriptive_name') self.descriptiveName = xhost.Attribute('descriptive_name')
self.hostDir = xhost.Attribute('host_dir')
self.mirrors = [] self.mirrors = []
xmirror = xhost.FirstChildElement('mirror') xmirror = xhost.FirstChildElement('mirror')
while xmirror: while xmirror:
@ -251,6 +254,8 @@ class Packager:
xhost.SetAttribute('download_url', self.downloadUrl) xhost.SetAttribute('download_url', self.downloadUrl)
if self.descriptiveName: if self.descriptiveName:
xhost.SetAttribute('descriptive_name', self.descriptiveName) xhost.SetAttribute('descriptive_name', self.descriptiveName)
if self.hostDir:
xhost.SetAttribute('host_dir', self.hostDir)
for mirror in self.mirrors: for mirror in self.mirrors:
xmirror = TiXmlElement('mirror') xmirror = TiXmlElement('mirror')
@ -1823,16 +1828,18 @@ class Packager:
self.contents = {} self.contents = {}
def setHost(self, host, downloadUrl = None, def setHost(self, host, downloadUrl = None,
descriptiveName = None, mirrors = None): descriptiveName = None, hostDir = None,
mirrors = None):
""" Specifies the URL that will ultimately host these """ Specifies the URL that will ultimately host these
contents. """ contents. """
self.host = host self.host = host
self.addHost(host, downloadUrl = downloadUrl, self.addHost(host, downloadUrl = downloadUrl,
descriptiveName = descriptiveName, mirrors = mirrors) descriptiveName = descriptiveName, hostDir = hostDir,
mirrors = mirrors)
def addHost(self, host, downloadUrl = None, descriptiveName = None, 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 """ Adds a host to the list of known download hosts. This
information will be written into any p3d files that reference information will be written into any p3d files that reference
this host; this can be used to pre-define the possible mirrors this host; this can be used to pre-define the possible mirrors
@ -1853,7 +1860,7 @@ class Packager:
# Define a new host entry # Define a new host entry
he = self.HostEntry(host, downloadUrl = downloadUrl, he = self.HostEntry(host, downloadUrl = downloadUrl,
descriptiveName = descriptiveName, descriptiveName = descriptiveName,
mirrors = mirrors) hostDir = hostDir, mirrors = mirrors)
self.hosts[host] = he self.hosts[host] = he
else: else:
# Update an existing host entry # Update an existing host entry
@ -1861,14 +1868,16 @@ class Packager:
he.downloadUrl = downloadUrl he.downloadUrl = downloadUrl
if descriptiveName is not None: if descriptiveName is not None:
he.descriptiveName = descriptiveName he.descriptiveName = descriptiveName
if hostDir is not None:
he.hostDir = hostDir
if mirrors is not None: if mirrors is not None:
he.mirrors = mirrors he.mirrors = mirrors
return he return he
def addAltHost(self, keyword, altHost, origHost = None, def addAltHost(self, keyword, altHost, origHost = None,
downloadUrl = None, downloadUrl = None, descriptiveName = None,
descriptiveName = None, mirrors = None): hostDir = None, mirrors = None):
""" Adds an alternate host to any already-known host. This """ Adds an alternate host to any already-known host. This
defines an alternate server that may be contacted, if defines an alternate server that may be contacted, if
specified on the HTML page, which hosts a different version of specified on the HTML page, which hosts a different version of
@ -1880,7 +1889,8 @@ class Packager:
origHost = self.host origHost = self.host
self.addHost(altHost, downloadUrl = downloadUrl, self.addHost(altHost, downloadUrl = downloadUrl,
descriptiveName = descriptiveName, mirrors = mirrors) descriptiveName = descriptiveName, hostDir = hostDir,
mirrors = mirrors)
he = self.addHost(origHost) he = self.addHost(origHost)
he.altHosts[keyword] = altHost he.altHosts[keyword] = altHost

View File

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

View File

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

View File

@ -38,8 +38,6 @@ P3DHost(const string &host_url) :
_xcontents = NULL; _xcontents = NULL;
_contents_seq = 0; _contents_seq = 0;
determine_host_dir();
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -99,20 +97,6 @@ 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() {
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
@ -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"; 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)) {
@ -389,11 +378,19 @@ add_mirror(string mirror_url) {
// HostInfo.determineHostDir(). // HostInfo.determineHostDir().
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void P3DHost:: void P3DHost::
determine_host_dir() { determine_host_dir(const string &host_dir_basename) {
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr(); P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
_host_dir = inst_mgr->get_root_dir(); _host_dir = inst_mgr->get_root_dir();
_host_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; string hostname;
// Look for a server name in the URL. Including this string in the // 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; _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 // 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.
const char *download_url = xhost->Attribute("download_url"); const char *download_url = xhost->Attribute("download_url");

View File

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

View File

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