mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
Port pdeploy to Python 3
This commit is contained in:
parent
532bee3b9e
commit
1ccf1cf29b
@ -5,7 +5,7 @@ to build for as many platforms as possible. """
|
|||||||
__all__ = ["Standalone", "Installer"]
|
__all__ = ["Standalone", "Installer"]
|
||||||
|
|
||||||
import os, sys, subprocess, tarfile, shutil, time, zipfile, socket, getpass, struct
|
import os, sys, subprocess, tarfile, shutil, time, zipfile, socket, getpass, struct
|
||||||
from cStringIO import StringIO
|
from io import BytesIO, TextIOWrapper
|
||||||
from direct.directnotify.DirectNotifyGlobal import *
|
from direct.directnotify.DirectNotifyGlobal import *
|
||||||
from direct.showbase.AppRunnerGlobal import appRunner
|
from direct.showbase.AppRunnerGlobal import appRunner
|
||||||
from panda3d.core import PandaSystem, HTTPClient, Filename, VirtualFileSystem, Multifile
|
from panda3d.core import PandaSystem, HTTPClient, Filename, VirtualFileSystem, Multifile
|
||||||
@ -21,8 +21,8 @@ try:
|
|||||||
except ImportError:
|
except ImportError:
|
||||||
pwd = None
|
pwd = None
|
||||||
|
|
||||||
# Make sure this matches with the magic in p3dEmbed.cxx.
|
# Make sure this matches with the magic in p3dEmbedMain.cxx.
|
||||||
P3DEMBED_MAGIC = "\xFF\x3D\x3D\x00"
|
P3DEMBED_MAGIC = 0xFF3D3D00
|
||||||
|
|
||||||
# This filter function is used when creating
|
# This filter function is used when creating
|
||||||
# an archive that should be owned by root.
|
# an archive that should be owned by root.
|
||||||
@ -161,10 +161,10 @@ class Standalone:
|
|||||||
|
|
||||||
# Find the magic size string and replace it with the real size,
|
# Find the magic size string and replace it with the real size,
|
||||||
# regardless of the endianness of the p3dembed executable.
|
# regardless of the endianness of the p3dembed executable.
|
||||||
hex_size = hex(size)[2:].rjust(8, "0")
|
p3dembed_data = p3dembed_data.replace(struct.pack('>I', P3DEMBED_MAGIC),
|
||||||
enc_size = "".join([chr(int(hex_size[i] + hex_size[i + 1], 16)) for i in range(0, len(hex_size), 2)])
|
struct.pack('>I', size))
|
||||||
p3dembed_data = p3dembed_data.replace(P3DEMBED_MAGIC, enc_size)
|
p3dembed_data = p3dembed_data.replace(struct.pack('<I', P3DEMBED_MAGIC),
|
||||||
p3dembed_data = p3dembed_data.replace(P3DEMBED_MAGIC[::-1], enc_size[::-1])
|
struct.pack('<I', size))
|
||||||
|
|
||||||
# Write the output file
|
# Write the output file
|
||||||
Standalone.notify.info("Creating %s..." % output)
|
Standalone.notify.info("Creating %s..." % output)
|
||||||
@ -173,12 +173,15 @@ class Standalone:
|
|||||||
ohandle.write(p3dembed_data)
|
ohandle.write(p3dembed_data)
|
||||||
|
|
||||||
# Write out the tokens. Set log_basename to the basename by default
|
# Write out the tokens. Set log_basename to the basename by default
|
||||||
tokens = {"log_basename" : self.basename}
|
tokens = {"log_basename": self.basename}
|
||||||
tokens.update(self.tokens)
|
tokens.update(self.tokens)
|
||||||
tokens.update(extraTokens)
|
tokens.update(extraTokens)
|
||||||
for token in tokens.items():
|
for key, value in tokens.items():
|
||||||
ohandle.write("\0%s=%s" % token)
|
ohandle.write(b"\0")
|
||||||
ohandle.write("\0\0")
|
ohandle.write(key.encode('ascii'))
|
||||||
|
ohandle.write(b"=")
|
||||||
|
ohandle.write(value.encode())
|
||||||
|
ohandle.write(b"\0\0")
|
||||||
|
|
||||||
# Buffer the p3d file to the output file. 1 MB buffer size.
|
# Buffer the p3d file to the output file. 1 MB buffer size.
|
||||||
phandle = open(self.p3dfile.toOsSpecific(), "rb")
|
phandle = open(self.p3dfile.toOsSpecific(), "rb")
|
||||||
@ -394,7 +397,7 @@ class Icon:
|
|||||||
vfs = VirtualFileSystem.getGlobalPtr()
|
vfs = VirtualFileSystem.getGlobalPtr()
|
||||||
stream = vfs.openWriteFile(fn, False, True)
|
stream = vfs.openWriteFile(fn, False, True)
|
||||||
icns = open(stream, 'wb')
|
icns = open(stream, 'wb')
|
||||||
icns.write('icns\0\0\0\0')
|
icns.write(b'icns\0\0\0\0')
|
||||||
|
|
||||||
icon_types = {16: 'is32', 32: 'il32', 48: 'ih32', 128: 'it32'}
|
icon_types = {16: 'is32', 32: 'il32', 48: 'ih32', 128: 'it32'}
|
||||||
mask_types = {16: 's8mk', 32: 'l8mk', 48: 'h8mk', 128: 't8mk'}
|
mask_types = {16: 's8mk', 32: 'l8mk', 48: 'h8mk', 128: 't8mk'}
|
||||||
@ -407,7 +410,7 @@ class Icon:
|
|||||||
if pngtype is None:
|
if pngtype is None:
|
||||||
continue
|
continue
|
||||||
icns.write(png_types[size])
|
icns.write(png_types[size])
|
||||||
icns.write('\0\0\0\0')
|
icns.write(b'\0\0\0\0')
|
||||||
start = icns.tell()
|
start = icns.tell()
|
||||||
|
|
||||||
image.write(stream, "", pngtype)
|
image.write(stream, "", pngtype)
|
||||||
@ -800,16 +803,18 @@ class Installer:
|
|||||||
tempdir, totsize = self.__buildTempLinux(platform)
|
tempdir, totsize = self.__buildTempLinux(platform)
|
||||||
|
|
||||||
# Create a control file in memory.
|
# Create a control file in memory.
|
||||||
controlfile = StringIO()
|
controlfile = BytesIO()
|
||||||
print >>controlfile, "Package: %s" % self.shortname.lower()
|
cout = TextIOWrapper(controlfile, encoding='utf-8', newline='')
|
||||||
print >>controlfile, "Version: %s" % self.version
|
cout.write(u"Package: %s\n" % self.shortname.lower())
|
||||||
print >>controlfile, "Maintainer: %s <%s>" % (self.authorname, self.authoremail)
|
cout.write(u"Version: %s\n" % self.version)
|
||||||
print >>controlfile, "Section: games"
|
cout.write(u"Maintainer: %s <%s>\n" % (self.authorname, self.authoremail))
|
||||||
print >>controlfile, "Priority: optional"
|
cout.write(u"Section: games\n")
|
||||||
print >>controlfile, "Architecture: %s" % arch
|
cout.write(u"Priority: optional\n")
|
||||||
print >>controlfile, "Installed-Size: %d" % -(-totsize / 1024)
|
cout.write(u"Architecture: %s\n" % arch)
|
||||||
print >>controlfile, "Description: %s" % self.fullname
|
cout.write(u"Installed-Size: %d\n" % -(-totsize // 1024))
|
||||||
print >>controlfile, "Depends: libc6, libgcc1, libstdc++6, libx11-6"
|
cout.write(u"Description: %s\n" % self.fullname)
|
||||||
|
cout.write(u"Depends: libc6, libgcc1, libstdc++6, libx11-6\n")
|
||||||
|
cout.flush()
|
||||||
controlinfo = TarInfoRoot("control")
|
controlinfo = TarInfoRoot("control")
|
||||||
controlinfo.mtime = modtime
|
controlinfo.mtime = modtime
|
||||||
controlinfo.size = controlfile.tell()
|
controlinfo.size = controlfile.tell()
|
||||||
@ -820,33 +825,43 @@ class Installer:
|
|||||||
if output.exists():
|
if output.exists():
|
||||||
output.unlink()
|
output.unlink()
|
||||||
debfile = open(output.toOsSpecific(), "wb")
|
debfile = open(output.toOsSpecific(), "wb")
|
||||||
debfile.write("!<arch>\x0A")
|
debfile.write(b"!<arch>\x0A")
|
||||||
debfile.write("debian-binary %-12lu0 0 100644 %-10ld\x60\x0A" % (modtime, 4))
|
pad_mtime = str(modtime).encode().ljust(12, b' ')
|
||||||
debfile.write("2.0\x0A")
|
|
||||||
|
|
||||||
# Write the control.tar.gz to the archive.
|
# The first entry is a special file that marks it a .deb.
|
||||||
debfile.write("control.tar.gz %-12lu0 0 100644 %-10ld\x60\x0A" % (modtime, 0))
|
debfile.write(b"debian-binary ")
|
||||||
|
debfile.write(pad_mtime)
|
||||||
|
debfile.write(b"0 0 100644 4 \x60\x0A")
|
||||||
|
debfile.write(b"2.0\x0A")
|
||||||
|
|
||||||
|
# Write the control.tar.gz to the archive. We'll leave the
|
||||||
|
# size 0 for now, and go back and fill it in later.
|
||||||
|
debfile.write(b"control.tar.gz ")
|
||||||
|
debfile.write(pad_mtime)
|
||||||
|
debfile.write(b"0 0 100644 0 \x60\x0A")
|
||||||
ctaroffs = debfile.tell()
|
ctaroffs = debfile.tell()
|
||||||
ctarfile = tarfile.open("control.tar.gz", "w:gz", debfile, tarinfo = TarInfoRoot)
|
ctarfile = tarfile.open("control.tar.gz", "w:gz", debfile, tarinfo = TarInfoRoot)
|
||||||
ctarfile.addfile(controlinfo, controlfile)
|
ctarfile.addfile(controlinfo, controlfile)
|
||||||
ctarfile.close()
|
ctarfile.close()
|
||||||
ctarsize = debfile.tell() - ctaroffs
|
ctarsize = debfile.tell() - ctaroffs
|
||||||
if (ctarsize & 1): debfile.write("\x0A")
|
if (ctarsize & 1): debfile.write(b"\x0A")
|
||||||
|
|
||||||
# Write the data.tar.gz to the archive.
|
# Write the data.tar.gz to the archive. Again, leave size 0.
|
||||||
debfile.write("data.tar.gz %-12lu0 0 100644 %-10ld\x60\x0A" % (modtime, 0))
|
debfile.write(b"data.tar.gz ")
|
||||||
|
debfile.write(pad_mtime)
|
||||||
|
debfile.write(b"0 0 100644 0 \x60\x0A")
|
||||||
dtaroffs = debfile.tell()
|
dtaroffs = debfile.tell()
|
||||||
dtarfile = tarfile.open("data.tar.gz", "w:gz", debfile, tarinfo = TarInfoRoot)
|
dtarfile = tarfile.open("data.tar.gz", "w:gz", debfile, tarinfo = TarInfoRoot)
|
||||||
dtarfile.add(Filename(tempdir, "usr").toOsSpecific(), "/usr")
|
dtarfile.add(Filename(tempdir, "usr").toOsSpecific(), "/usr")
|
||||||
dtarfile.close()
|
dtarfile.close()
|
||||||
dtarsize = debfile.tell() - dtaroffs
|
dtarsize = debfile.tell() - dtaroffs
|
||||||
if (dtarsize & 1): debfile.write("\x0A")
|
if (dtarsize & 1): debfile.write(b"\x0A")
|
||||||
|
|
||||||
# Write the correct sizes of the archives.
|
# Write the correct sizes of the archives.
|
||||||
debfile.seek(ctaroffs - 12)
|
debfile.seek(ctaroffs - 12)
|
||||||
debfile.write("%-10ld" % ctarsize)
|
debfile.write(str(ctarsize).encode().ljust(10, b' '))
|
||||||
debfile.seek(dtaroffs - 12)
|
debfile.seek(dtaroffs - 12)
|
||||||
debfile.write("%-10ld" % dtarsize)
|
debfile.write(str(dtarsize).encode().ljust(10, b' '))
|
||||||
|
|
||||||
debfile.close()
|
debfile.close()
|
||||||
|
|
||||||
@ -873,18 +888,20 @@ class Installer:
|
|||||||
tempdir, totsize = self.__buildTempLinux(platform)
|
tempdir, totsize = self.__buildTempLinux(platform)
|
||||||
|
|
||||||
# Create a pkginfo file in memory.
|
# Create a pkginfo file in memory.
|
||||||
pkginfo = StringIO()
|
pkginfo = BytesIO()
|
||||||
print >>pkginfo, "# Generated using pdeploy"
|
pout = TextIOWrapper(pkginfo, encoding='utf-8', newline='')
|
||||||
print >>pkginfo, "# %s" % time.ctime(modtime)
|
pout.write(u"# Generated using pdeploy\n")
|
||||||
print >>pkginfo, "pkgname = %s" % self.shortname.lower()
|
pout.write(u"# %s\n" % time.ctime(modtime))
|
||||||
print >>pkginfo, "pkgver = %s" % pkgver
|
pout.write(u"pkgname = %s\n" % self.shortname.lower())
|
||||||
print >>pkginfo, "pkgdesc = %s" % self.fullname
|
pout.write(u"pkgver = %s\n" % pkgver)
|
||||||
print >>pkginfo, "builddate = %s" % modtime
|
pout.write(u"pkgdesc = %s\n" % self.fullname)
|
||||||
print >>pkginfo, "packager = %s <%s>" % (self.authorname, self.authoremail)
|
pout.write(u"builddate = %s\n" % modtime)
|
||||||
print >>pkginfo, "size = %d" % totsize
|
pout.write(u"packager = %s <%s>\n" % (self.authorname, self.authoremail))
|
||||||
print >>pkginfo, "arch = %s" % arch
|
pout.write(u"size = %d\n" % totsize)
|
||||||
|
pout.write(u"arch = %s\n" % arch)
|
||||||
if self.licensename != "":
|
if self.licensename != "":
|
||||||
print >>pkginfo, "license = %s" % self.licensename
|
pout.write(u"license = %s\n" % self.licensename)
|
||||||
|
pout.flush()
|
||||||
pkginfoinfo = TarInfoRoot(".PKGINFO")
|
pkginfoinfo = TarInfoRoot(".PKGINFO")
|
||||||
pkginfoinfo.mtime = modtime
|
pkginfoinfo.mtime = modtime
|
||||||
pkginfoinfo.size = pkginfo.tell()
|
pkginfoinfo.size = pkginfo.tell()
|
||||||
|
@ -513,18 +513,15 @@ class HostInfo:
|
|||||||
PackageInfo, returns it. """
|
PackageInfo, returns it. """
|
||||||
|
|
||||||
if not platform:
|
if not platform:
|
||||||
# Ensure that we're on the same page with non-specified
|
platform = None
|
||||||
# platforms. We have to use the empty string, not None,
|
|
||||||
# since Python 3 can't sort lists with both strings and None.
|
|
||||||
platform = ""
|
|
||||||
|
|
||||||
platforms = self.packages.setdefault((name, version), {})
|
platforms = self.packages.setdefault((name, version or ""), {})
|
||||||
package = platforms.get(platform, None)
|
package = platforms.get("", None)
|
||||||
if not package:
|
if not package:
|
||||||
package = PackageInfo(self, name, version, platform = platform,
|
package = PackageInfo(self, name, version, platform = platform,
|
||||||
solo = solo, asMirror = self.asMirror,
|
solo = solo, asMirror = self.asMirror,
|
||||||
perPlatform = perPlatform)
|
perPlatform = perPlatform)
|
||||||
platforms[platform] = package
|
platforms[platform or ""] = package
|
||||||
|
|
||||||
return package
|
return package
|
||||||
|
|
||||||
@ -534,12 +531,12 @@ class HostInfo:
|
|||||||
platform, if one is provided by this host, or None if not. """
|
platform, if one is provided by this host, or None if not. """
|
||||||
|
|
||||||
assert self.hasContentsFile
|
assert self.hasContentsFile
|
||||||
platforms = self.packages.get((name, version or None), {})
|
platforms = self.packages.get((name, version or ""), {})
|
||||||
|
|
||||||
if platform is not None:
|
if platform:
|
||||||
# In this case, we are looking for a specific platform
|
# In this case, we are looking for a specific platform
|
||||||
# only.
|
# only.
|
||||||
return platforms.get(platform or None, None)
|
return platforms.get(platform, None)
|
||||||
|
|
||||||
# We are looking for one matching the current runtime
|
# We are looking for one matching the current runtime
|
||||||
# platform. First, look for a package matching the current
|
# platform. First, look for a package matching the current
|
||||||
@ -548,7 +545,7 @@ class HostInfo:
|
|||||||
|
|
||||||
# If not found, look for one matching no particular platform.
|
# If not found, look for one matching no particular platform.
|
||||||
if not package:
|
if not package:
|
||||||
package = platforms.get(None, None)
|
package = platforms.get("", None)
|
||||||
|
|
||||||
return package
|
return package
|
||||||
|
|
||||||
@ -564,7 +561,7 @@ class HostInfo:
|
|||||||
if name and pn != name:
|
if name and pn != name:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if platform is None:
|
if not platform:
|
||||||
for p2 in platforms:
|
for p2 in platforms:
|
||||||
package = self.getPackage(pn, version, platform = p2)
|
package = self.getPackage(pn, version, platform = p2)
|
||||||
if package:
|
if package:
|
||||||
@ -596,7 +593,7 @@ class HostInfo:
|
|||||||
# current platform, or no particular platform.
|
# current platform, or no particular platform.
|
||||||
package = platforms.get(PandaSystem.getPlatform(), None)
|
package = platforms.get(PandaSystem.getPlatform(), None)
|
||||||
if not package:
|
if not package:
|
||||||
package = platforms.get(None, None)
|
package = platforms.get("", None)
|
||||||
|
|
||||||
if package:
|
if package:
|
||||||
result.append(package)
|
result.append(package)
|
||||||
|
@ -523,7 +523,8 @@ class PackageInfo:
|
|||||||
|
|
||||||
# In case of unexpected failures on the internet, we will retry
|
# In case of unexpected failures on the internet, we will retry
|
||||||
# the full download instead of just giving up.
|
# the full download instead of just giving up.
|
||||||
for retry in range(core.ConfigVariableInt('package-full-dl-retries', 1)):
|
retries = core.ConfigVariableInt('package-full-dl-retries', 1).getValue()
|
||||||
|
for retry in range(retries):
|
||||||
self.installPlans.append(planB[:])
|
self.installPlans.append(planB[:])
|
||||||
|
|
||||||
pc.stop()
|
pc.stop()
|
||||||
|
@ -15,6 +15,7 @@ import sys
|
|||||||
import os
|
import os
|
||||||
import io
|
import io
|
||||||
import encodings
|
import encodings
|
||||||
|
from posixpath import join
|
||||||
|
|
||||||
_vfs = core.VirtualFileSystem.getGlobalPtr()
|
_vfs = core.VirtualFileSystem.getGlobalPtr()
|
||||||
|
|
||||||
@ -331,20 +332,6 @@ def walk(top, topdown = True, onerror = None, followlinks = True):
|
|||||||
if not topdown:
|
if not topdown:
|
||||||
yield (top, dirnames, filenames)
|
yield (top, dirnames, filenames)
|
||||||
|
|
||||||
def join(path, *args):
|
|
||||||
for part in args:
|
|
||||||
if part == '':
|
|
||||||
continue
|
|
||||||
|
|
||||||
if part.startswith('/'):
|
|
||||||
path = part
|
|
||||||
elif path.endswith('/'):
|
|
||||||
path = path + part
|
|
||||||
else:
|
|
||||||
path = '/'.join((path, part))
|
|
||||||
|
|
||||||
return path
|
|
||||||
|
|
||||||
def isfile(path):
|
def isfile(path):
|
||||||
return _vfs.isRegularFile(core.Filename.fromOsSpecific(path))
|
return _vfs.isRegularFile(core.Filename.fromOsSpecific(path))
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user