rookeries/rookeries/views.py

99 lines
2.7 KiB
Python

"""
Core web application views.
:copyright: Copyright 2013-2017, Dorian Pula <dorian.pula@amber-penguin-software.ca>
:license: AGPL v3+
"""
import http
import io
import json
import logging
import os
import flask
import invoke
import rookeries
from rookeries.main import rookeries_app
from rookeries.pages import views as page_views
from rookeries.sites import views as site_views
logger = logging.getLogger(__name__)
GIT_REVISION_INFO_FILE = './git-info'
def get_git_revision():
if not os.path.exists(GIT_REVISION_INFO_FILE):
return 'UNKNOWN'
with io.open(GIT_REVISION_INFO_FILE) as git_info:
revision_info = git_info.readlines()[0].strip()
return revision_info or 'UNKNOWN'
@rookeries_app.route('/status')
def app_status():
"""
Simple view that returns the status of the application.
Useful as a part of a heartbeat mechanism.
"""
app_status_info = {
'app': 'rookeries',
'version': rookeries.__version__,
'gitRevision': get_git_revision(),
}
return flask.jsonify(app_status_info)
@rookeries_app.route('/api')
@rookeries_app.route('/api/<path:some_path>')
def render_catch_all_for_api_calls(some_path=''):
flask.abort(http.HTTPStatus.NOT_FOUND)
def extract_json_response(response: flask.Response):
return json.loads(response.get_data().decode())
@rookeries_app.route('/')
@rookeries_app.route('/<path:some_path>')
def render_single_page_app(some_path=''):
# TODO: Clean this rendering significantly.
# TODO: Check if site and page are present. If not exit early.
# TODO: Consider using internal calls to site and page views::
# TODO: https://gist.github.com/lost-theory/3005268
status_code = http.HTTPStatus.OK
page_info = {
'path': some_path,
}
site_info = {}
server_side_response = ''
site_response = site_views.get_site()
try:
page_response = page_views.serve_page(slug=some_path)
page_info['title'] = page_response['title']
site_info = extract_json_response(site_response)
# TODO: If no page given, use the default page of a site.
response = invoke.run(f'node dist/server.js /{some_path}')
server_side_response = response.stdout
except Exception:
logger.warning(Exception)
# TODO: Update site and page info with good defaults
site_info['name'] = 'Rookeries'
site_info['favicon'] = site_info.get(
'favicon',
'/static/images/mr-penguin-amber-favicon.ico')
page_info['title'] = page_info.get('title', 'Unknown Page')
# TODO: Handle errors when calling the server side code better.
return flask.render_template(
'base.html', react_render=server_side_response, site=site_info,
page=page_info), status_code