-Installation
+NOTE ==========================================================================
-pip install panda3d-appimage
+This works on Linux only.
+
+INSTALLATION ==================================================================
+pip install panda3d-appimage
-Usage
+USAGE =========================================================================
In your setup.py file, add the following:
- # import the panda3d's bdist command
- from direct.dist.commands import bdist_apps
- # import the AppImage builder
- from p3d_appimage import AppImageBuilder
+from direct.dist.commands import bdist_apps
+from p3d_appimage import AppImageBuilder
+
+class BDistAppsCmd(bdist_apps):
+ def run(self):
+ bdist_apps.run(self)
+ AppImageBuilder('appname', self).build('execname')
+
+setup(
+ ...
+ cmdclass={"bdist_apps": BDistAppsCmd},
+ ... )
+
+EXAMPLE =======================================================================
+
+Let's build an AppImage for the Panda3D's Asteroids example.
+
+Modify the file setup.py
+(https://github.com/panda3d/panda3d/blob/master/samples/asteroids/setup.py)
+adding these lines:
+
+from direct.dist.commands import bdist_apps
+from p3d_appimage import AppImageBuilder
+
+class BDistAppsCmd(bdist_apps):
+ def run(self):
+ bdist_apps.run(self)
+ AppImageBuilder('asteroids', self).build('asteroids')
+
+setup(
+ ...
+ cmdclass={"bdist_apps": BDistAppsCmd},
+ ... )
+
+Then, launch the standard Panda3D build command:
+
+python setup.py bdist_apps
+At the end of the process, you will get the builds created by Panda3D and your
+AppImage in the dist/ folder.
- # let's override the bdist command
- class BDistAppsCmd(bdist_apps):
+UPDATING APPIMAGES ============================================================
- def run(self):
- # invoke the standard bdist command, so you get the standard behavior
- bdist_apps.run(self)
- # then, invoke the AppImage builder
- AppImageBuilder('appname').build('execname')
+The builder can also update your AppImage. If you specify a zsync_path when you
+invoke the AppImageBuilder's method build(), then you can Invoke the AppImage's
+method update() in your application and this will update your AppImage.
\ No newline at end of file
'''Tools for building AppImages.'''
from os import system, makedirs, chmod, stat, chdir, getcwd
-from shutil import rmtree, copy, copytree
+from os.path import abspath, join, isabs
+from shutil import rmtree, copy, copytree, move
from urllib.request import urlretrieve
from stat import S_IEXEC
from glob import glob
from textwrap import dedent
+from pathlib import Path
import sys
class AppImageBuilder:
- def __init__(self, name):
+ def __init__(self, name, cmd):
self._name = name
+ self._cmd = cmd
- def build(self, execname, longname=None, branch='',
- ver='0.0.0', build_path='build/', ico=None, zsync_path=None):
+ def build(self, execname, longname=None, branch='', zsync_path=None):
'''Build an AppImage.'''
+ build_cmd = self._cmd.distribution.get_command_obj('build_apps')
+ build_base = abspath(build_cmd.build_base)
+ dist_dir = self._cmd.dist_dir
longname = longname or self._name
dirname = self._name.capitalize() + '.AppDir'
- with InsideDir(build_path):
+ with InsideDir(build_base):
rmtree(dirname, ignore_errors=True)
makedirs(dirname)
- with InsideDir(build_path + '/' + dirname):
+ with InsideDir(build_base + '/' + dirname):
with open('AppRun', 'w') as f_apprun: f_apprun.write(apprun_content)
chmod('AppRun', stat('AppRun').st_mode | S_IEXEC)
desktop_content = desktop_content_tmpl % (longname, execname)
with open(self._name + '.desktop', 'w') as fdesktop:
fdesktop.write(desktop_content)
- if ico:
- copy(ico, './icon.png')
- copytree('../../%smanylinux1_x86_64' % build_path, './usr/bin')
+ if build_cmd.icons:
+ ico_path = build_cmd.icons[self._name][0]
+ if not isabs(ico_path):
+ prj_dir = Path(getcwd()).parent.parent.absolute()
+ ico_path = join(prj_dir, ico_path)
+ copy(ico_path, './icon.png')
+ else:
+ Path('icon.svg').touch()
+ copytree('%s/manylinux1_x86_64' % build_base, './usr/bin')
src = 'https://github.com/AppImage/AppImageUpdate/releases/' + \
'download/continuous/appimageupdatetool-x86_64.AppImage'
dst = './usr/bin/appimageupdatetool-x86_64.AppImage'
self._download(src, dst) # for AppImage's self-updating
- with InsideDir(build_path):
+ with InsideDir(build_base):
src = 'https://github.com/AppImage/AppImageKit/releases/' + \
'download/12/appimagetool-x86_64.AppImage'
tool = 'appimagetool-x86_64.AppImage'
self._download(src, tool)
hbranch = ('-' + branch) if branch else ''
- tgt_name = 'Yocto%s-x86_64.AppImage' % hbranch
+ tgt_name = '%s%s-x86_64.AppImage' % (self._name.capitalize(), hbranch)
with open(dirname + '/usr/bin/appimage_name.txt', 'w') as fan:
fan.write(tgt_name)
with open(dirname + '/usr/bin/appimage_version.txt', 'w') as fav:
- fav.write(ver)
+ fav.write(self._cmd.distribution.get_version())
+ tmpl = './%s %s %s'
+ cmd = tmpl % (tool, dirname, tgt_name)
if zsync_path:
- tmpl = './%s %s %s -u "zsync|%s' + \
- '%s%s-x86_64.AppImage.zsync"'
- cmd = tmpl % (tool, dirname, tgt_name, zsync_path,
- self._name.capitalize(), hbranch)
- print(cmd)
- system(cmd)
+ tmpl = ' -u "zsync|%s%s%s-x86_64.AppImage.zsync"'
+ cmd += tmpl % (zsync_path, self._name.capitalize(), hbranch)
+ print(cmd)
+ system(cmd)
+ move(tgt_name, join(dist_dir, tgt_name))
+ if zsync_path:
+ move(tgt_name + '.zsync', join(dist_dir, tgt_name + '.zsync'))
def _download(self, path, fname):
urlretrieve(path, fname)