Skip to content

Commit

Permalink
Merge pull request #28 from pybee/topic/im
Browse files Browse the repository at this point in the history
Initial cut for django briefcase target
  • Loading branch information
glasnt committed Mar 14, 2017
2 parents d03e082 + 7bc04eb commit 5c19fcf
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 5 deletions.
38 changes: 34 additions & 4 deletions briefcase/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import os
import json
import random
import re
import sys
import uuid
Expand All @@ -28,6 +29,8 @@ class app(Command):
"Directory to put the project in"),
('formal-name=', None,
"Formal name for the project"),
('class-name=', None,
"Entry class name for the project"),
('organization-name=', None,
"Name of the organization managing the project"),
('template=', None,
Expand All @@ -38,6 +41,8 @@ class app(Command):
"Name of the icon file."),
('guid=', None,
"GUID identifying the app."),
('secret-key=', None,
"Secret key for the app."),
('splash=', None,
"Name of the splash screen file."),
('app-requires', None,
Expand All @@ -51,6 +56,7 @@ class app(Command):
def initialize_options(self):
self.dir = None
self.formal_name = None
self.class_name = None
self.organization_name = None
self.template = None
self.bundle = None
Expand All @@ -61,11 +67,15 @@ def initialize_options(self):
self.download_dir = None
self.version_code = None
self.guid = None
self.secret_key = None

def finalize_options(self):
if self.formal_name is None:
self.formal_name = self.distribution.get_name().title()

if self.class_name is None:
self.class_name = self.formal_name.replace(' ', '')

if self.organization_name is None:
self.organization_name = self.distribution.get_author().title()

Expand Down Expand Up @@ -93,6 +103,10 @@ def finalize_options(self):
if self.guid is None:
self.guid = uuid.uuid3(uuid.NAMESPACE_URL, self.distribution.get_url())

# The secret key is 40 characters of entropy
if self.secret_key is None:
self.secret_key = ''.join(random.choice("abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)") for i in range(40))

pip.utils.ensure_dir(self.download_dir)

def find_support_pkg(self):
Expand Down Expand Up @@ -120,6 +134,14 @@ def find_support_pkg(self):
except IndexError:
return None

@property
def app_dir(self):
return os.path.join(os.getcwd(), self.resource_dir, 'app')

@property
def app_packages_dir(self):
return os.path.join(os.getcwd(), self.resource_dir, 'app_packages')

def generate_app_template(self):
print(" * Writing application template...")

Expand All @@ -134,14 +156,18 @@ def generate_app_template(self):
extra_context={
'app_name': self.distribution.get_name(),
'formal_name': self.formal_name,
'class_name': self.class_name,
'organization_name': self.organization_name,
'author': self.distribution.get_author(),
'description': self.distribution.get_description(),
'dir_name': self.dir,
'bundle': self.bundle,
'year': date.today().strftime('%Y'),
'month': date.today().strftime('%B'),
'version': self.distribution.get_version(),
'version_code': self.version_code,
'guid': self.guid,
'secret_key': self.secret_key,
}
)

Expand All @@ -152,8 +178,8 @@ def install_app_requirements(self):
'install',
'--upgrade',
'--force-reinstall',
'--target=%s' % os.path.join(os.getcwd(), self.resource_dir, 'app_packages')
] + self.distribution.install_requires
'--target=%s' % self.app_packages_dir
] + self.distribution.install_requires,
)
else:
print("No requirements.")
Expand All @@ -165,7 +191,7 @@ def install_platform_requirements(self):
'install',
'--upgrade',
'--force-reinstall',
'--target=%s' % os.path.join(os.getcwd(), self.resource_dir, 'app_packages')
'--target=%s' % self.app_packages_dir,
] + self.app_requires
)
else:
Expand All @@ -178,7 +204,7 @@ def install_code(self):
'--upgrade',
'--force-reinstall',
'--no-dependencies', # We just want the code, not the dependencies
'--target=%s' % os.path.join(os.getcwd(), self.resource_dir, 'app'),
'--target=%s' % self.app_dir,
'.'
])

Expand Down Expand Up @@ -218,6 +244,9 @@ def install_support_package(self):
print(" python setup.py %s --support-pkg=<path to tarball>" % self.platform.lower())
print()

def install_extras(self):
pass

def post_run(self):
print()
print("Installation complete.")
Expand All @@ -229,5 +258,6 @@ def run(self):
self.install_code()
self.install_resources()
self.install_support_package()
self.install_extras()

self.post_run()
71 changes: 71 additions & 0 deletions briefcase/django.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import os
import shutil
import subprocess

try:
from urllib.request import urlopen
except ImportError: # Python 2 compatibility
from urllib2 import urlopen

import pip

from .app import app


class django(app):
description = "Create a django app to wrap this project"

def finalize_options(self):
# Copy over all the options from the base 'app' command
finalized = self.get_finalized_command('app')
for attr in ('formal_name', 'bundle', 'icon', 'guid', 'description', 'class_name', 'secret_key'):
if getattr(self, attr) is None:
setattr(self, attr, getattr(finalized, attr))

# Set platform-specific options
self.platform = 'Django'

if self.dir is None:
self.dir = "django"

self.resource_dir = self.dir

# Django has no support package
self.skip_support_pkg = True

@property
def app_dir(self):
return os.path.join(os.getcwd(), self.dir)

def install_icon(self):
raise RuntimeError("Django doesn't support icons.")

def install_splash(self):
raise RuntimeError("Django doesn't support splash screens.")

def install_support_package(self):
pass

def install_platform_requirements(self):
print(" * Installing plaform requirements...")

if self.app_requires:
pip.main([
'install',
'--upgrade',
'--force-reinstall',
] + self.app_requires
)
else:
print("No platform requirements.")

def install_extras(self):
# Install additional elements required for Django
print(" * Installing extras...")
print(" - Installing NPM requirements...")

npm = shutil.which("npm")
subprocess.Popen([npm, "install"], cwd=os.path.abspath(self.dir)).wait()

print(" - Building Webpack assets...")
subprocess.Popen([npm, "run", "build"], cwd=os.path.abspath(self.dir)).wait()
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@
entry_points={
'distutils.commands': [
'android = briefcase.android:android',
'app = briefcase.app:app',
'app = briefcase.app:app', # Don't call directly, but registration required
'django = briefcase.django:django',
'ios = briefcase.ios:ios',
'macos = briefcase.macos:macos',
'tvos = briefcase.tvos:tvos',
Expand Down

0 comments on commit 5c19fcf

Please sign in to comment.