mirror of
https://github.com/jazzband/django-ddp.git
synced 2026-05-15 19:13:15 +00:00
Merge branch 'release/0.12.0'
This commit is contained in:
commit
98878281f2
6 changed files with 133 additions and 106 deletions
|
|
@ -1,6 +1,12 @@
|
|||
Change Log
|
||||
==========
|
||||
|
||||
0.12.0
|
||||
------
|
||||
* Get path to `star.json` from view config (defined in your urls.py)
|
||||
instead of from settings.
|
||||
* Dropped `dddp.server.views`, use `dddp.views` instead.
|
||||
|
||||
0.11.0
|
||||
------
|
||||
* Support more than 8KB of change data by splitting large payloads into
|
||||
|
|
|
|||
63
README.rst
63
README.rst
|
|
@ -103,6 +103,19 @@ Add ddp.py to your Django application:
|
|||
[Book, Author, AllBooks, BooksByAuthorEmail]
|
||||
)
|
||||
|
||||
Start the Django DDP service:
|
||||
|
||||
.. code:: sh
|
||||
|
||||
DJANGO_SETTINGS_MODULE=myproject.settings dddp
|
||||
|
||||
|
||||
Using django-ddp as a secondary DDP connection (RAPID DEVELOPMENT)
|
||||
------------------------------------------------------------------
|
||||
|
||||
Running in this manner allows rapid development through use of the hot
|
||||
code push features provided by Meteor.
|
||||
|
||||
Connect your Meteor application to the Django DDP service:
|
||||
|
||||
.. code:: javascript
|
||||
|
|
@ -118,19 +131,53 @@ Connect your Meteor application to the Django DDP service:
|
|||
Django.subscribe('BooksByAuthorEmail', 'janet@evanovich.com');
|
||||
}
|
||||
|
||||
Start the Django DDP service:
|
||||
|
||||
.. code:: sh
|
||||
|
||||
DJANGO_SETTINGS_MODULE=myproject.settings dddp
|
||||
|
||||
In a separate terminal, start Meteor (from within your meteor
|
||||
application directory):
|
||||
Start Meteor (from within your meteor application directory):
|
||||
|
||||
.. code:: sh
|
||||
|
||||
meteor
|
||||
|
||||
Using django-ddp as the primary DDP connection (RECOMMENDED)
|
||||
------------------------------------------------------------
|
||||
|
||||
If you'd prefer to not have two DDP connections (one to Meteor and one
|
||||
to django-ddp) you can set the `DDP_DEFAULT_CONNECTION_URL` environment
|
||||
variable to use the specified URL as the primary DDP connection in
|
||||
Meteor. When doing this, you won't need to use `DDP.connect(...)` or
|
||||
specify `{connection: Django}` on your collections. Running with
|
||||
django-ddp as the primary connection is recommended, and indeed required
|
||||
if you wish to use `dddp.accounts` to provide authentication using
|
||||
`django.contrib.auth` to your meteor app.
|
||||
|
||||
.. code:: sh
|
||||
|
||||
DDP_DEFAULT_CONNECTION_URL=http://localhost:8000/ meteor
|
||||
|
||||
|
||||
Serving your Meteor applications from django-ddp
|
||||
------------------------------------------------
|
||||
|
||||
First, you will need to build your meteor app into a directory (examples
|
||||
below assume target directory named `myapp`):
|
||||
|
||||
.. code:: sh
|
||||
|
||||
meteor build ../myapp
|
||||
|
||||
Then, add a MeteorView to your urls.py:
|
||||
|
||||
.. code:: python
|
||||
|
||||
from dddp.views import MeteorView
|
||||
|
||||
urlpatterns = patterns(
|
||||
url('^(?P<path>/.*)$', MeteorView.as_view(
|
||||
json_path=os.path.join(
|
||||
settings.PROJ_ROOT, 'myapp', 'bundle', 'star.json',
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
Adding API endpoints (server method definitions)
|
||||
------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
default_app_config = 'dddp.server.apps.ServerConfig'
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
"""Django DDP Server views."""
|
||||
from __future__ import print_function, absolute_import, unicode_literals
|
||||
from ejson import dumps
|
||||
from django.apps import apps
|
||||
from django.conf import settings
|
||||
from django.http import HttpResponse
|
||||
from django.views.generic import View
|
||||
|
||||
|
||||
STAR_JSON_SETTING_NAME = 'METEOR_STAR_JSON'
|
||||
|
||||
|
||||
class MeteorView(View):
|
||||
|
||||
"""Django DDP Meteor server view."""
|
||||
|
||||
http_method_names = ['get', 'head']
|
||||
|
||||
app = None
|
||||
runtime_config = None
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
"""Initialisation for Django DDP server view."""
|
||||
super(MeteorView, self).__init__(**kwargs)
|
||||
self.app = apps.get_app_config('server')
|
||||
|
||||
def get(self, request, path):
|
||||
"""Return HTML (or other related content) for Meteor."""
|
||||
if path == '/meteor_runtime_config.js':
|
||||
config = {
|
||||
'DDP_DEFAULT_CONNECTION_URL': request.build_absolute_uri('/'),
|
||||
'ROOT_URL': request.build_absolute_uri(
|
||||
'%s/' % self.runtime_config.get('ROOT_URL_PATH_PREFIX', ''),
|
||||
),
|
||||
'ROOT_URL_PATH_PREFIX': '',
|
||||
}
|
||||
# Use HTTPS instead of HTTP if SECURE_SSL_REDIRECT is set
|
||||
if config['DDP_DEFAULT_CONNECTION_URL'].startswith('http:') \
|
||||
and settings.SECURE_SSL_REDIRECT:
|
||||
config['DDP_DEFAULT_CONNECTION_URL'] = 'https:%s' % (
|
||||
config['DDP_DEFAULT_CONNECTION_URL'].split(':', 1)[1],
|
||||
)
|
||||
config.update(self.runtime_config)
|
||||
return HttpResponse(
|
||||
'__meteor_runtime_config__ = %s;' % dumps(config),
|
||||
content_type='text/javascript',
|
||||
)
|
||||
try:
|
||||
file_path, content_type = self.app.url_map[path]
|
||||
with open(file_path, 'r') as content:
|
||||
return HttpResponse(
|
||||
content.read(),
|
||||
content_type=content_type,
|
||||
)
|
||||
except KeyError:
|
||||
print(path)
|
||||
return HttpResponse(self.app.html)
|
||||
# raise Http404
|
||||
|
|
@ -1,20 +1,18 @@
|
|||
"""Django DDP Server app config."""
|
||||
"""Django DDP Server views."""
|
||||
from __future__ import print_function, absolute_import, unicode_literals
|
||||
|
||||
import io
|
||||
import mimetypes
|
||||
import os.path
|
||||
|
||||
from django.apps import AppConfig
|
||||
from django.conf import settings
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from ejson import dumps, loads
|
||||
from django.conf import settings
|
||||
from django.http import HttpResponse
|
||||
from django.views.generic import View
|
||||
|
||||
import pybars
|
||||
|
||||
|
||||
STAR_JSON_SETTING_NAME = 'METEOR_STAR_JSON'
|
||||
|
||||
|
||||
def read(path, default=None, encoding='utf8'):
|
||||
"""Read encoded contents from specified path or return default."""
|
||||
if not path:
|
||||
|
|
@ -34,12 +32,14 @@ def read_json(path):
|
|||
return loads(json_file.read())
|
||||
|
||||
|
||||
class ServerConfig(AppConfig):
|
||||
class MeteorView(View):
|
||||
|
||||
"""Django config for dddp.server app."""
|
||||
"""Django DDP Meteor server view."""
|
||||
|
||||
name = 'dddp.server'
|
||||
verbose_name = 'Django DDP Meteor Web Server'
|
||||
http_method_names = ['get', 'head']
|
||||
|
||||
json_path = None
|
||||
runtime_config = None
|
||||
|
||||
manifest = None
|
||||
program_json = None
|
||||
|
|
@ -47,8 +47,6 @@ class ServerConfig(AppConfig):
|
|||
runtime_config = None
|
||||
|
||||
star_json = None # top level layout
|
||||
server_json = None # web server layout
|
||||
web_browser_json = None # web.browser (client) layout
|
||||
|
||||
url_map = None
|
||||
internal_map = None
|
||||
|
|
@ -57,21 +55,21 @@ class ServerConfig(AppConfig):
|
|||
client_map = None # web.browser (client) URL to path map
|
||||
html = '<!DOCTYPE html>\n<html><head><title>DDP App</title></head></html>'
|
||||
|
||||
def ready(self):
|
||||
"""Configure Django DDP server app."""
|
||||
mimetypes.init() # read and process /etc/mime.types
|
||||
root_url_path_prefix = ''
|
||||
bundled_js_css_prefix = '/'
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
"""Initialisation for Django DDP server view."""
|
||||
# super(...).__init__ assigns kwargs to instance.
|
||||
super(MeteorView, self).__init__(**kwargs)
|
||||
|
||||
# read and process /etc/mime.types
|
||||
mimetypes.init()
|
||||
|
||||
self.url_map = {}
|
||||
|
||||
try:
|
||||
json_path = getattr(settings, STAR_JSON_SETTING_NAME)
|
||||
except AttributeError:
|
||||
raise ImproperlyConfigured(
|
||||
'%s setting required by dddp.server.view.' % (
|
||||
STAR_JSON_SETTING_NAME,
|
||||
),
|
||||
)
|
||||
|
||||
self.star_json = read_json(json_path)
|
||||
# process `star_json`
|
||||
self.star_json = read_json(self.json_path)
|
||||
star_format = self.star_json['format']
|
||||
if star_format != 'site-archive-pre1':
|
||||
raise ValueError(
|
||||
|
|
@ -82,19 +80,20 @@ class ServerConfig(AppConfig):
|
|||
for program in self.star_json['programs']
|
||||
}
|
||||
|
||||
# process `bundle/programs/server/program.json` from build dir
|
||||
server_json_path = os.path.join(
|
||||
os.path.dirname(json_path),
|
||||
os.path.dirname(self.json_path),
|
||||
os.path.dirname(programs['server']['path']),
|
||||
'program.json',
|
||||
)
|
||||
self.server_json = read_json(server_json_path)
|
||||
server_format = self.server_json['format']
|
||||
server_json = read_json(server_json_path)
|
||||
server_format = server_json['format']
|
||||
if server_format != 'javascript-image-pre1':
|
||||
raise ValueError(
|
||||
'Unknown Meteor server format: %r' % server_format,
|
||||
)
|
||||
self.server_load_map = {}
|
||||
for item in self.server_json['load']:
|
||||
for item in server_json['load']:
|
||||
item['path_full'] = os.path.join(
|
||||
os.path.dirname(server_json_path),
|
||||
item['path'],
|
||||
|
|
@ -124,12 +123,13 @@ class ServerConfig(AppConfig):
|
|||
],
|
||||
)
|
||||
|
||||
# process `bundle/programs/web.browser/program.json` from build dir
|
||||
web_browser_json_path = os.path.join(
|
||||
os.path.dirname(json_path),
|
||||
os.path.dirname(self.json_path),
|
||||
programs['web.browser']['path'],
|
||||
)
|
||||
self.web_browser_json = read_json(web_browser_json_path)
|
||||
web_browser_format = self.web_browser_json['format']
|
||||
web_browser_json = read_json(web_browser_json_path)
|
||||
web_browser_format = web_browser_json['format']
|
||||
if web_browser_format != 'web-program-pre1':
|
||||
raise ValueError(
|
||||
'Unknown Meteor web.browser format: %r' % (
|
||||
|
|
@ -138,7 +138,7 @@ class ServerConfig(AppConfig):
|
|||
)
|
||||
self.client_map = {}
|
||||
self.internal_map = {}
|
||||
for item in self.web_browser_json['manifest']:
|
||||
for item in web_browser_json['manifest']:
|
||||
item['path_full'] = os.path.join(
|
||||
os.path.dirname(web_browser_json_path),
|
||||
item['path'],
|
||||
|
|
@ -159,19 +159,19 @@ class ServerConfig(AppConfig):
|
|||
config = {
|
||||
'css': [
|
||||
{'url': item['path']}
|
||||
for item in self.web_browser_json['manifest']
|
||||
for item in web_browser_json['manifest']
|
||||
if item['type'] == 'css' and item['where'] == 'client'
|
||||
],
|
||||
'js': [
|
||||
{'url': item['path']}
|
||||
for item in self.web_browser_json['manifest']
|
||||
for item in web_browser_json['manifest']
|
||||
if item['type'] == 'js' and item['where'] == 'client'
|
||||
],
|
||||
'meteorRuntimeConfig': '"%s"' % (
|
||||
dumps(self.runtime_config)
|
||||
),
|
||||
'rootUrlPathPrefix': '/app',
|
||||
'bundledJsCssPrefix': '/app/',
|
||||
'rootUrlPathPrefix': self.root_url_path_prefix,
|
||||
'bundledJsCssPrefix': self.bundled_js_css_prefix,
|
||||
'inlineScriptsAllowed': False,
|
||||
'inline': None,
|
||||
'head': read(
|
||||
|
|
@ -187,3 +187,36 @@ class ServerConfig(AppConfig):
|
|||
compiler = pybars.Compiler()
|
||||
tmpl = compiler.compile(tmpl_raw)
|
||||
self.html = '<!DOCTYPE html>\n%s' % tmpl(config)
|
||||
|
||||
def get(self, request, path):
|
||||
"""Return HTML (or other related content) for Meteor."""
|
||||
if path == '/meteor_runtime_config.js':
|
||||
config = {
|
||||
'DDP_DEFAULT_CONNECTION_URL': request.build_absolute_uri('/'),
|
||||
'ROOT_URL': request.build_absolute_uri(
|
||||
'%s/' % self.runtime_config.get('ROOT_URL_PATH_PREFIX', ''),
|
||||
),
|
||||
'ROOT_URL_PATH_PREFIX': '',
|
||||
}
|
||||
# Use HTTPS instead of HTTP if SECURE_SSL_REDIRECT is set
|
||||
if config['DDP_DEFAULT_CONNECTION_URL'].startswith('http:') \
|
||||
and settings.SECURE_SSL_REDIRECT:
|
||||
config['DDP_DEFAULT_CONNECTION_URL'] = 'https:%s' % (
|
||||
config['DDP_DEFAULT_CONNECTION_URL'].split(':', 1)[1],
|
||||
)
|
||||
config.update(self.runtime_config)
|
||||
return HttpResponse(
|
||||
'__meteor_runtime_config__ = %s;' % dumps(config),
|
||||
content_type='text/javascript',
|
||||
)
|
||||
try:
|
||||
file_path, content_type = self.url_map[path]
|
||||
with open(file_path, 'r') as content:
|
||||
return HttpResponse(
|
||||
content.read(),
|
||||
content_type=content_type,
|
||||
)
|
||||
except KeyError:
|
||||
print(path)
|
||||
return HttpResponse(self.html)
|
||||
# raise Http404
|
||||
2
setup.py
2
setup.py
|
|
@ -5,7 +5,7 @@ from setuptools import setup, find_packages
|
|||
|
||||
setup(
|
||||
name='django-ddp',
|
||||
version='0.11.0',
|
||||
version='0.12.0',
|
||||
description=__doc__,
|
||||
long_description=open('README.rst').read(),
|
||||
author='Tyson Clugg',
|
||||
|
|
|
|||
Loading…
Reference in a new issue