Skip to content

Commit

Permalink
allow deployment of graphics from archive using paths
Browse files Browse the repository at this point in the history
  • Loading branch information
jjelosua committed Mar 13, 2017
1 parent 57f2ad1 commit afabd01
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 40 deletions.
28 changes: 13 additions & 15 deletions fabfile/__init__.py
Expand Up @@ -81,13 +81,13 @@ def deploy(*slugs):
for slug in slugs:
deploy_single(slug)

def deploy_single(slug):
def deploy_single(path):
"""
Deploy a single project to S3 and, if configured, to our servers.
"""
require('settings', provided_by=[production, staging])

graphic_root = '%s/%s' % (app_config.GRAPHICS_PATH, slug)
slug, abspath = utils.parse_path(path)
graphic_root = '%s/%s' % (abspath, slug)
s3_root = '%s/graphics/%s' % (app_config.PROJECT_SLUG, slug)
graphic_assets = '%s/assets' % graphic_root
s3_assets = '%s/assets' % s3_root
Expand All @@ -98,14 +98,11 @@ def deploy_single(slug):
use_assets = getattr(graphic_config, 'USE_ASSETS', True)
default_max_age = getattr(graphic_config, 'DEFAULT_MAX_AGE', None) or app_config.DEFAULT_MAX_AGE
assets_max_age = getattr(graphic_config, 'ASSETS_MAX_AGE', None) or app_config.ASSETS_MAX_AGE

update_copy(slug)

update_copy(path)
if use_assets:
assets.sync(slug)

render.render(slug)
assets.sync(path)

render.render(path)
flat.deploy_folder(
graphic_root,
s3_root,
Expand All @@ -114,7 +111,7 @@ def deploy_single(slug):
},
ignore=['%s/*' % graphic_assets, '%s/*' % graphic_node_modules,
# Ignore files unused on static S3 server
'*.xls', '*.xlsx', '*.pyc', '*.py', '*.less',
'*.xls', '*.xlsx', '*.pyc', '*.py', '*.less', '*.bak',
'%s/base_template.html' % graphic_root,
'%s/child_template.html' % graphic_root]
)
Expand All @@ -136,11 +133,12 @@ def deploy_single(slug):
print ''
print '%s URL: %s/graphics/%s/%s' % (env.settings.capitalize(), app_config.S3_BASE_URL, slug, file_suffix)

def download_copy(slug):
def download_copy(path):
"""
Downloads a Google Doc as an .xlsx file.
"""
graphic_path = '%s/%s' % (app_config.GRAPHICS_PATH, slug)
slug, abspath = utils.parse_path(path)
graphic_path = '%s/%s' % (abspath, slug)

try:
graphic_config = load_graphic_config(graphic_path)
Expand All @@ -156,12 +154,12 @@ def download_copy(slug):
get_document(graphic_config.COPY_GOOGLE_DOC_KEY, copy_path)

@task
def update_copy(slug=None):
def update_copy(path=None):
"""
Fetches the latest Google Doc and updates local JSON.
"""
if slug:
download_copy(slug)
if path:
download_copy(path)
return

slugs = os.listdir(app_config.GRAPHICS_PATH)
Expand Down
8 changes: 4 additions & 4 deletions fabfile/assets.py
Expand Up @@ -14,17 +14,17 @@
import utils

@task
def sync(slug):
def sync(path):
"""
Intelligently synchronize assets between S3 and local folder.
"""
ignore_globs = []

if not os.path.exists('%s/%s' % (app_config.GRAPHICS_PATH, slug)):
slug, abspath = utils.parse_path(path)
if not os.path.exists('%s/%s' % (abspath, slug)):
print 'Slug "%s" does not exist!' % slug
return

assets_root = '%s/%s/assets' % (app_config.GRAPHICS_PATH, slug)
assets_root = '%s/%s/assets' % (abspath, slug)
s3_root = '%s/%s' % (app_config.ASSETS_SLUG, slug)

try:
Expand Down
29 changes: 19 additions & 10 deletions fabfile/render.py
Expand Up @@ -4,22 +4,29 @@

from fabric.api import task
from fabric.state import env
from fabric.tasks import execute
from glob import glob

import app
import app_config
import utils


@task(default=True)
def render(slug=''):
def render(path=''):
"""
Render HTML templates and compile assets.
"""
if slug:
_render_graphics(['%s/%s' % (app_config.GRAPHICS_PATH, slug)])
archive = False
if path:
slug, abspath = utils.parse_path(path)
if abspath != app_config.GRAPHICS_PATH:
archive = True
_render_graphics(['%s/%s' % (abspath, slug)], archive)
else:
_render_graphics(glob('%s/*' % app_config.GRAPHICS_PATH))

def _render_graphics(paths):

def _render_graphics(paths, archive=False):
"""
Render a set of graphics
"""
Expand All @@ -29,12 +36,12 @@ def _render_graphics(paths):
app_config.configure_targets(env.get('settings', None))

for path in paths:
slug = path.split('%s/' % app_config.GRAPHICS_PATH)[1].split('/')[0]

slug = path.split('/')[-1]
with app.app.test_request_context(path='graphics/%s/' % slug):
g.compile_includes = True
g.compiled_includes = {}

if archive:
g.alt_path = path
view = app.graphic.__dict__['_graphics_detail']
content = view(slug).data

Expand All @@ -45,10 +52,12 @@ def _render_graphics(paths):
if not os.path.exists('%s/child_template.html' % path):
continue

with app.app.test_request_context(path='graphics/%s/child.html' % slug):
with app.app.test_request_context(path='graphics/%s/child.html' % (
slug)):
g.compile_includes = True
g.compiled_includes = {}

if archive:
g.alt_path = path
view = app.graphic.__dict__['_graphics_child']
content = view(slug).data

Expand Down
18 changes: 18 additions & 0 deletions fabfile/utils.py
@@ -1,8 +1,11 @@
#!/usr/bin/env python

import os
import boto
from boto.s3.connection import OrdinaryCallingFormat
from fabric.api import prompt
import app_config


def confirm(message):
"""
Expand Down Expand Up @@ -32,3 +35,18 @@ def get_bucket(bucket_name):
s3 = boto.connect_s3()

return s3.get_bucket(bucket_name)


def parse_path(path):
"""
Parse the path into abspath and slug
"""
bits = path.split('/')
if len(bits) > 1:
slug = bits[-1]
path = '/'.join(bits[:-1])
abspath = os.path.abspath(path)
else:
slug = path
abspath = app_config.GRAPHICS_PATH
return slug, abspath
30 changes: 25 additions & 5 deletions graphic.py
Expand Up @@ -21,9 +21,13 @@ def _graphics_detail(slug):
"""
Renders a parent.html index with child.html embedded as iframe.
"""
from flask import request
from flask import request, g

graphic_path = '%s/%s' % (app_config.GRAPHICS_PATH, slug)
alt_path = getattr(g, 'alt_path', None)
if alt_path:
graphic_path = alt_path
else:
graphic_path = '%s/%s' % (app_config.GRAPHICS_PATH, slug)

# NOTE: Parent must load pym.js from same source as child to prevent version conflicts!
context = make_context(asset_depth=2, root_path=graphic_path)
Expand Down Expand Up @@ -59,7 +63,12 @@ def _graphics_child(slug):
"""
Renders a child.html for embedding.
"""
graphic_path = '%s/%s' % (app_config.GRAPHICS_PATH, slug)
from flask import g
alt_path = getattr(g, 'alt_path', None)
if alt_path:
graphic_path = alt_path
else:
graphic_path = '%s/%s' % (app_config.GRAPHICS_PATH, slug)
print graphic_path

# Fallback for legacy projects w/o child templates
Expand Down Expand Up @@ -102,7 +111,12 @@ def _graphic_less(slug, filename):
"""
Compiles LESS for a graphic.
"""
graphic_path = '%s/%s' % (app_config.GRAPHICS_PATH, slug)
from flask import g
alt_path = getattr(g, 'alt_path', None)
if alt_path:
graphic_path = alt_path
else:
graphic_path = '%s/%s' % (app_config.GRAPHICS_PATH, slug)
less_path = '%s/css/%s.less' % (graphic_path, filename)

if not os.path.exists(less_path):
Expand All @@ -115,7 +129,13 @@ def _graphic_less(slug, filename):
# Serve arbitrary static files on-demand
@graphic.route('/<slug>/<path:path>')
def _static(slug, path):
real_path = '%s/%s/%s' % (app_config.GRAPHICS_PATH, slug, path)
from flask import g
alt_path = getattr(g, 'alt_path', None)
if alt_path:
graphic_path = alt_path
else:
graphic_path = '%s/%s' % (app_config.GRAPHICS_PATH, slug)
real_path = '%s/%s' % (graphic_path, path)

try:
with open(real_path) as f:
Expand Down
9 changes: 6 additions & 3 deletions oauth.py
Expand Up @@ -63,11 +63,14 @@ def oauth_required(f):
"""
@wraps(f)
def decorated_function(*args, **kwargs):
from flask import request

from flask import request, g
alt_path = getattr(g, 'alt_path', None)
if request.path.startswith('/graphics/'):
slug = request.path.split('/')[-2]
graphic_path = '%s/%s' % (app_config.GRAPHICS_PATH, slug)
if alt_path:
graphic_path = alt_path
else:
graphic_path = '%s/%s' % (app_config.GRAPHICS_PATH, slug)

try:
graphic_config = load_graphic_config(graphic_path)
Expand Down
11 changes: 8 additions & 3 deletions render_utils.py
Expand Up @@ -163,9 +163,14 @@ def load_graphic_config(graphic_path, base_paths=[]):

paths = [graphic_path] + base_paths

f, path, desc = imp.find_module('graphic_config', paths)
graphic_config = imp.load_module('graphic_config', f, path, desc)
f.close()
try:
f, path, desc = imp.find_module('graphic_config', paths)
graphic_config = imp.load_module('graphic_config', f, path, desc)
f.close()
except ImportError:
class EmptyConfig:
pass
graphic_config = EmptyConfig()

sys.path.pop(0)

Expand Down

0 comments on commit afabd01

Please sign in to comment.