standard install dirs
This commit is contained in:
parent
0c123b6bce
commit
77b6df9fd7
|
|
@ -35,6 +35,8 @@
|
|||
#define INSTALL_HEADERS \
|
||||
p3d_plugin.h
|
||||
|
||||
#define WIN_SYS_LIBS shell32.lib
|
||||
|
||||
#end lib_target
|
||||
|
||||
#begin bin_target
|
||||
|
|
|
|||
|
|
@ -38,25 +38,11 @@ import zlib
|
|||
import direct
|
||||
from pandac.PandaModules import *
|
||||
|
||||
from FileSpec import FileSpec
|
||||
|
||||
class ArgumentError(AttributeError):
|
||||
pass
|
||||
|
||||
class FileSpec:
|
||||
def __init__(self, filename, pathname):
|
||||
self.filename = filename
|
||||
self.pathname = pathname
|
||||
|
||||
self.size = pathname.getFileSize()
|
||||
self.timestamp = pathname.getTimestamp()
|
||||
|
||||
hv = HashVal()
|
||||
hv.hashFile(pathname)
|
||||
self.hash = hv.asHex()
|
||||
|
||||
def getParams(self):
|
||||
return 'filename="%s" size=%s timestamp=%s hash="%s"' % (
|
||||
self.filename, self.size, self.timestamp, self.hash)
|
||||
|
||||
class PackageMaker:
|
||||
def __init__(self):
|
||||
self.startDir = None
|
||||
|
|
@ -76,10 +62,12 @@ class PackageMaker:
|
|||
self.packageFullname = '%s_%s' % (
|
||||
self.packageName, self.packageVersion)
|
||||
|
||||
self.cleanDir(self.stageDir)
|
||||
self.packageStageDir = Filename(self.stageDir, '%s/%s' % (self.packageName, self.packageVersion))
|
||||
|
||||
self.cleanDir(self.packageStageDir)
|
||||
|
||||
uncompressedArchiveBasename = '%s.mf' % (self.packageFullname)
|
||||
uncompressedArchivePathname = Filename(self.stageDir, uncompressedArchiveBasename)
|
||||
uncompressedArchivePathname = Filename(self.packageStageDir, uncompressedArchiveBasename)
|
||||
self.archive = Multifile()
|
||||
if not self.archive.openWrite(uncompressedArchivePathname):
|
||||
raise IOError, "Couldn't open %s for writing" % (uncompressedArchivePathname)
|
||||
|
|
@ -92,7 +80,7 @@ class PackageMaker:
|
|||
uncompressedArchive = FileSpec(uncompressedArchiveBasename, uncompressedArchivePathname)
|
||||
|
||||
compressedArchiveBasename = '%s.mf.pz' % (self.packageFullname)
|
||||
compressedArchivePathname = Filename(self.stageDir, compressedArchiveBasename)
|
||||
compressedArchivePathname = Filename(self.packageStageDir, compressedArchiveBasename)
|
||||
|
||||
print "\ncompressing"
|
||||
|
||||
|
|
@ -112,7 +100,7 @@ class PackageMaker:
|
|||
uncompressedArchivePathname.unlink()
|
||||
|
||||
descFileBasename = '%s.xml' % (self.packageFullname)
|
||||
descFilePathname = Filename(self.stageDir, descFileBasename)
|
||||
descFilePathname = Filename(self.packageStageDir, descFileBasename)
|
||||
|
||||
f = open(descFilePathname.toOsSpecific(), 'w')
|
||||
print >> f, '<?xml version="1.0" ?>'
|
||||
|
|
@ -148,11 +136,11 @@ class PackageMaker:
|
|||
localpath = ''
|
||||
else:
|
||||
assert dirpath.startswith(prefix)
|
||||
localpath = dirpath[len(prefix):] + '/'
|
||||
localpath = dirpath[len(prefix):].replace(os.sep, '/') + '/'
|
||||
|
||||
for basename in filenames:
|
||||
file = FileSpec(localpath + basename,
|
||||
Filename(self.startDir, basename))
|
||||
Filename(self.startDir, localpath + basename))
|
||||
print file.filename
|
||||
self.components.append(file)
|
||||
self.archive.addSubfile(file.filename, file.pathname, 0)
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ P3DDownload() {
|
|||
_http_status_code = 0;
|
||||
_total_data = 0;
|
||||
_total_expected_data = 0;
|
||||
_last_reported_time = 0;
|
||||
|
||||
_canceled = false;
|
||||
_download_id = 0;
|
||||
|
|
@ -126,8 +127,12 @@ receive_data(const unsigned char *this_data, size_t this_data_size) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void P3DDownload::
|
||||
download_progress() {
|
||||
cerr << "Downloading " << get_url() << ": "
|
||||
<< int(get_download_progress() * 1000.0) / 10.0 << "\n";
|
||||
time_t now = time(NULL);
|
||||
if (now != _last_reported_time) {
|
||||
cerr << "Downloading " << get_url() << ": "
|
||||
<< int(get_download_progress() * 1000.0) / 10.0 << "\n";
|
||||
_last_reported_time = now;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -140,4 +145,6 @@ download_progress() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void P3DDownload::
|
||||
download_finished(bool success) {
|
||||
cerr << "Downloading " << get_url() << ": "
|
||||
<< int(get_download_progress() * 1000.0) / 10.0 << "\n";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@
|
|||
|
||||
#include "p3d_plugin_common.h"
|
||||
|
||||
#include <time.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : P3DDownload
|
||||
// Description : This represents a request to download a single file
|
||||
|
|
@ -62,6 +64,7 @@ protected:
|
|||
|
||||
size_t _total_data;
|
||||
size_t _total_expected_data;
|
||||
time_t _last_reported_time;
|
||||
|
||||
private:
|
||||
bool _canceled;
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "p3dFileDownload.h"
|
||||
#include "p3dInstanceManager.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DFileDownload::Constructor
|
||||
|
|
@ -44,6 +45,12 @@ set_filename(const string &filename) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
bool P3DFileDownload::
|
||||
open_file() {
|
||||
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
||||
if (!inst_mgr->mkfile_public(_filename)) {
|
||||
cerr << "Unable to create " << _filename << "\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
_file.open(_filename.c_str(), ios::out | ios::ate | ios::binary);
|
||||
if (!_file) {
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -17,6 +17,10 @@
|
|||
#include "p3dSession.h"
|
||||
#include "p3dPackage.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <shlobj.h>
|
||||
#endif
|
||||
|
||||
P3DInstanceManager *P3DInstanceManager::_global_ptr;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -73,13 +77,21 @@ P3DInstanceManager::
|
|||
////////////////////////////////////////////////////////////////////
|
||||
bool P3DInstanceManager::
|
||||
initialize() {
|
||||
_root_dir = find_root_dir();
|
||||
cerr << "_root_dir = " << _root_dir << "\n";
|
||||
|
||||
#ifdef _WIN32
|
||||
_root_dir = "c:/cygwin/home/drose/p3ddir";
|
||||
_download_url = "http://10.196.143.118/~drose/";
|
||||
_download_url = "http://10.196.143.118/~drose/p3d/";
|
||||
|
||||
#else
|
||||
_root_dir = "/Users/drose/p3ddir";
|
||||
_download_url = "http://orpheus.ddrose.com/~drose/";
|
||||
#endif
|
||||
|
||||
if (_root_dir.empty()) {
|
||||
cerr << "Could not find root directory.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -264,6 +276,67 @@ signal_request_ready() {
|
|||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DInstanceManager::mkdir_public
|
||||
// Access: Public, Static
|
||||
// Description: Creates a new directory with wide-open access
|
||||
// priviledges.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DInstanceManager::
|
||||
mkdir_public(const string &dirname) {
|
||||
#ifdef _WIN32
|
||||
SECURITY_DESCRIPTOR sd;
|
||||
InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
|
||||
SetSecurityDescriptorDacl(&sd, true, NULL, false);
|
||||
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
sa.nLength = sizeof(sa);
|
||||
sa.lpSecurityDescriptor = &sd;
|
||||
CreateDirectory(dirname.c_str(), &sa);
|
||||
|
||||
#else //_WIN32
|
||||
mkdir(dirname.c_str(), 0777);
|
||||
|
||||
#endif // _WIN32
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DInstanceManager::mkfile_public
|
||||
// Access: Public, Static
|
||||
// Description: Creates a new file with wide-open access
|
||||
// priviledges.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool P3DInstanceManager::
|
||||
mkfile_public(const string &filename) {
|
||||
#ifdef _WIN32
|
||||
SECURITY_DESCRIPTOR sd;
|
||||
InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
|
||||
SetSecurityDescriptorDacl(&sd, true, NULL, false);
|
||||
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
sa.nLength = sizeof(sa);
|
||||
sa.lpSecurityDescriptor = &sd;
|
||||
|
||||
HANDLE file = CreateFile(filename.c_str(), GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
&sa, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (file == INVALID_HANDLE_VALUE) {
|
||||
return false;
|
||||
}
|
||||
CloseHandle(file);
|
||||
return true;
|
||||
|
||||
#else // _WIN32
|
||||
int fd = creat(filename.c_str(), 0777);
|
||||
if (fd == -1) {
|
||||
return false;
|
||||
}
|
||||
close(fd);
|
||||
return true;
|
||||
|
||||
#endif // _WIN32
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DInstanceManager::get_global_ptr
|
||||
// Access: Public, Static
|
||||
|
|
@ -292,3 +365,120 @@ create_command_instance() {
|
|||
new P3DInstance(NULL, "", P3D_WT_hidden, 0, 0, 0, 0,
|
||||
dummy_handle, NULL, 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DInstanceManager::find_root_dir
|
||||
// Access: Private
|
||||
// Description: Returns the path to the installable Panda3D directory
|
||||
// on the user's machine.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string P3DInstanceManager::
|
||||
find_root_dir() const {
|
||||
#ifdef _WIN32
|
||||
// Try to locate a writable directory to install Panda files into.
|
||||
char buffer[MAX_PATH];
|
||||
|
||||
// First, check for a user-appdata Panda3D folder. If it already
|
||||
// exists, use it (but don't create it yet).
|
||||
if (SHGetSpecialFolderPath(NULL, buffer, CSIDL_APPDATA, true)) {
|
||||
bool isdir = false;
|
||||
DWORD results = GetFileAttributes(buffer);
|
||||
if (results != -1) {
|
||||
isdir = (results & FILE_ATTRIBUTE_DIRECTORY) != 0;
|
||||
}
|
||||
|
||||
if (isdir) {
|
||||
// The user prefix exists; do we have a Panda3D child?
|
||||
string root = buffer;
|
||||
root += string("/Panda3D");
|
||||
|
||||
// Don't attempt to create the Panda3D folder yet. Just see if
|
||||
// it exists.
|
||||
isdir = false;
|
||||
results = GetFileAttributes(root.c_str());
|
||||
if (results != -1) {
|
||||
isdir = (results & FILE_ATTRIBUTE_DIRECTORY) != 0;
|
||||
}
|
||||
|
||||
if (isdir) {
|
||||
// The directory exists!
|
||||
return root;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If there's no user-appdata Panda3D folder, look for a common one.
|
||||
// This time we'll create it if it doesn't exist, if we can. (We'd
|
||||
// prefer to create the folder in a common space if we can, since
|
||||
// that way it can be shared by multiple users.)
|
||||
if (SHGetSpecialFolderPath(NULL, buffer, CSIDL_COMMON_APPDATA, true)) {
|
||||
bool isdir = false;
|
||||
DWORD results = GetFileAttributes(buffer);
|
||||
if (results != -1) {
|
||||
isdir = (results & FILE_ATTRIBUTE_DIRECTORY) != 0;
|
||||
}
|
||||
|
||||
if (isdir) {
|
||||
// The common prefix exists; do we have a Panda3D child?
|
||||
string root = buffer;
|
||||
root += string("/Panda3D");
|
||||
|
||||
// Attempt to make it first, if possible. Make sure the
|
||||
// security attributes are wide open; this is a shared resource.
|
||||
mkdir_public(root);
|
||||
|
||||
isdir = false;
|
||||
results = GetFileAttributes(root.c_str());
|
||||
if (results != -1) {
|
||||
isdir = (results & FILE_ATTRIBUTE_DIRECTORY) != 0;
|
||||
}
|
||||
|
||||
if (isdir) {
|
||||
// The directory exists!
|
||||
return root;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now try again to create a Panda3D folder in user-specific
|
||||
// directory. Presumably we'll have write permission to this one.
|
||||
if (SHGetSpecialFolderPath(NULL, buffer, CSIDL_APPDATA, true)) {
|
||||
bool isdir = false;
|
||||
DWORD results = GetFileAttributes(buffer);
|
||||
if (results != -1) {
|
||||
isdir = (results & FILE_ATTRIBUTE_DIRECTORY) != 0;
|
||||
}
|
||||
|
||||
if (isdir) {
|
||||
// The user prefix exists; do we have a Panda3D child?
|
||||
string root = buffer;
|
||||
root += string("/Panda3D");
|
||||
|
||||
// Attempt to make it first, if possible. This time we don't
|
||||
// attempt to make it public, since this is a private space.
|
||||
CreateDirectory(root.c_str(), NULL);
|
||||
|
||||
isdir = false;
|
||||
results = GetFileAttributes(root.c_str());
|
||||
if (results != -1) {
|
||||
isdir = (results & FILE_ATTRIBUTE_DIRECTORY) != 0;
|
||||
}
|
||||
|
||||
if (isdir) {
|
||||
// The directory exists!
|
||||
return root;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Couldn't find a directory. Bail.
|
||||
cerr << "Couldn't find a root directory.\n";
|
||||
return string();
|
||||
|
||||
#else // _WIN32
|
||||
return "/Users/drose/p3ddir";
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -64,10 +64,14 @@ public:
|
|||
int get_unique_session_index();
|
||||
void signal_request_ready();
|
||||
|
||||
static void mkdir_public(const string &dirname);
|
||||
static bool mkfile_public(const string &dirname);
|
||||
|
||||
static P3DInstanceManager *get_global_ptr();
|
||||
|
||||
private:
|
||||
void create_command_instance();
|
||||
string find_root_dir() const;
|
||||
|
||||
private:
|
||||
string _root_dir;
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "p3dMultifileReader.h"
|
||||
#include "p3dInstanceManager.h"
|
||||
|
||||
// This sequence of bytes begins each Multifile to identify it as a
|
||||
// Multifile.
|
||||
|
|
@ -77,6 +78,8 @@ extract(const string &pathname, const string &to_dir) {
|
|||
return false;
|
||||
}
|
||||
|
||||
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
||||
|
||||
// Now walk through all of the files.
|
||||
Subfiles::iterator si;
|
||||
for (si = _subfiles.begin(); si != _subfiles.end(); ++si) {
|
||||
|
|
@ -84,12 +87,17 @@ extract(const string &pathname, const string &to_dir) {
|
|||
cerr << s._filename << "\n";
|
||||
|
||||
string output_pathname = to_dir + "/" + s._filename;
|
||||
ofstream out(output_pathname.c_str(), ios::out | ios::trunc | ios::binary);
|
||||
if (!out) {
|
||||
if (!inst_mgr->mkfile_public(output_pathname)) {
|
||||
cerr << "Unable to create " << output_pathname << "\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
ofstream out(output_pathname.c_str(), ios::out | ios::binary);
|
||||
if (!out) {
|
||||
cerr << "Unable to write to " << output_pathname << "\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
_in.seekg(s._start);
|
||||
|
||||
static const size_t buffer_size = 1024;
|
||||
|
|
|
|||
|
|
@ -58,18 +58,10 @@ P3DPackage(const string &package_name, const string &package_version) :
|
|||
|
||||
// Ensure the package directory exists; create it if it does not.
|
||||
_package_dir = inst_mgr->get_root_dir() + string("/") + _package_name;
|
||||
#ifdef _WIN32
|
||||
_mkdir(_package_dir.c_str());
|
||||
#else
|
||||
mkdir(_package_dir.c_str(), 0777);
|
||||
#endif
|
||||
inst_mgr->mkdir_public(_package_dir);
|
||||
|
||||
_package_dir += string("/") + _package_version;
|
||||
#ifdef _WIN32
|
||||
_mkdir(_package_dir.c_str());
|
||||
#else
|
||||
mkdir(_package_dir.c_str(), 0777);
|
||||
#endif
|
||||
inst_mgr->mkdir_public(_package_dir);
|
||||
|
||||
_desc_file_basename = _package_fullname + ".xml";
|
||||
_desc_file_pathname = _package_dir + "/" + _desc_file_basename;
|
||||
|
|
@ -77,6 +69,9 @@ P3DPackage(const string &package_name, const string &package_version) :
|
|||
// TODO: we should check the desc file for updates with the server.
|
||||
// Perhaps this should be done in a parent class.
|
||||
|
||||
// TODO: if the desc file exists, and is consistent with the server
|
||||
// contents file, don't re-download it.
|
||||
/*
|
||||
// Load the desc file, if it exists.
|
||||
TiXmlDocument doc(_desc_file_pathname.c_str());
|
||||
if (!doc.LoadFile()) {
|
||||
|
|
@ -84,6 +79,9 @@ P3DPackage(const string &package_name, const string &package_version) :
|
|||
} else {
|
||||
got_desc_file(&doc, false);
|
||||
}
|
||||
*/
|
||||
|
||||
download_desc_file();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -312,6 +310,13 @@ uncompress_archive() {
|
|||
return;
|
||||
}
|
||||
|
||||
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
||||
if (!inst_mgr->mkfile_public(target_pathname)) {
|
||||
cerr << "Unable to create " << target_pathname << "\n";
|
||||
report_done(false);
|
||||
return;
|
||||
}
|
||||
|
||||
ofstream target(target_pathname.c_str(), ios::out | ios::binary);
|
||||
if (!target) {
|
||||
cerr << "Couldn't write to " << target_pathname << "\n";
|
||||
|
|
|
|||
Loading…
Reference in New Issue