Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add urls.js endpoint #234

Merged
merged 12 commits into from
Nov 9, 2017
38 changes: 35 additions & 3 deletions src/ims/application/_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@
import ims.element
from ims.config import Configuration, URLs
from ims.dms import DutyManagementSystem
from ims.ext.klein import KleinRenderable
from ims.ext.json import jsonTextFromObject
from ims.ext.klein import ContentType, HeaderName, KleinRenderable, static

from ._api import APIApplication
from ._auth import AuthApplication
Expand Down Expand Up @@ -118,7 +119,8 @@ def __del__(self) -> None:
#

@router.route(URLs.root, methods=("HEAD", "GET"))
def rootResource(self, request: IRequest) -> KleinRenderable:
@static
def rootEndpoint(self, request: IRequest) -> KleinRenderable:
"""
Server root page.
Expand All @@ -128,15 +130,42 @@ def rootResource(self, request: IRequest) -> KleinRenderable:


@router.route(URLs.static, branch=True)
def static(self, request: IRequest) -> KleinRenderable:
@static
def staticEndpoint(self, request: IRequest) -> KleinRenderable:
return File(resourcesDirectory.path)


#
# URLs
#

@router.route(URLs.urlsJS, methods=("HEAD", "GET"))
@static
def urlsEndpoint(self, request: IRequest) -> KleinRenderable:
"""
JavaScript variables for service URLs.
"""
urls = {
k: getattr(URLs, k).asText() for k in URLs.__dict__
if not k.startswith("_")
}

request.setHeader(
HeaderName.contentType.value, ContentType.javascript.value
)

return "\n".join((
"var url_{} = {};".format(k, jsonTextFromObject(v))
for k, v in urls.items()
))


#
# Child application endpoints
#

@router.route(URLs.api, branch=True)
@static
def apiApplicationEndpoint(self, request: IRequest) -> KleinRenderable:
"""
API application resource.
Expand All @@ -145,6 +174,7 @@ def apiApplicationEndpoint(self, request: IRequest) -> KleinRenderable:


@router.route(URLs.auth, branch=True)
@static
def authApplicationEndpoint(self, request: IRequest) -> KleinRenderable:
"""
Auth application resource.
Expand All @@ -153,6 +183,7 @@ def authApplicationEndpoint(self, request: IRequest) -> KleinRenderable:


@router.route(URLs.external, branch=True)
@static
def externalApplicationEndpoint(
self, request: IRequest
) -> KleinRenderable:
Expand All @@ -163,6 +194,7 @@ def externalApplicationEndpoint(


@router.route(URLs.app, branch=True)
@static
def webApplicationEndpoint(self, request: IRequest) -> KleinRenderable:
"""
Web application resource.
Expand Down
1 change: 1 addition & 0 deletions src/ims/config/_urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class URLs(object):
root = URL.fromText("/")

prefix = root.child("ims").child("")
urlsJS = prefix.child("urls.js")

# Static resources
static = prefix.child("static")
Expand Down
68 changes: 62 additions & 6 deletions src/ims/element/_page.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@
Element base classes.
"""

from collections import OrderedDict
from typing import Iterable, MutableMapping

from hyperlink import URL

from twisted.web.iweb import IRequest
from twisted.web.template import Tag, renderer, tags

Expand All @@ -44,6 +49,46 @@ def __init__(self, config: Configuration, title: str) -> None:
self.titleText = title


def urlsFromImportSpec(self, spec: str) -> Iterable[URL]:
"""
Given a string specifying desired imports, return the corresponding
URLs.
"""
urls = self.config.urls

result: MutableMapping[str, URL] = OrderedDict()

def add(name: str) -> None:
if not name or name in result:
return

if name == "bootstrap":
add("jquery")

if name == "ims":
add("jquery")
add("moment")

try:
result[name] = getattr(urls, "{}JS".format(name))
except AttributeError:
raise ValueError(
"Invalid import {!r} in spec {!r}".format(name, spec)
)

if name == "dataTables":
add("dataTablesBootstrap")

# All pages use Bootstrap
add("bootstrap")
add("urls")

for name in spec.split(","):
add(name.strip())

return result.values()


@renderer
def title(
self, request: IRequest, tag: Tag = tags.title
Expand All @@ -62,14 +107,24 @@ def title(
@renderer
def head(self, request: IRequest, tag: Tag = tags.head) -> KleinRenderable:
"""
<head> element.
`<head>` element.
"""
urls = self.config.urls

children = tag.children
tag.children = []

imports = (
tags.script(src=url.asText())
for url in
self.urlsFromImportSpec(tag.attributes.get("imports", ""))
)

if "imports" in tag.attributes:
del tag.attributes["imports"]

return tag(
# Resource metadata
tags.meta(charset="utf-8"),
tags.meta(
name="viewport", content="width=device-width, initial-scale=1"
Expand All @@ -86,9 +141,10 @@ def head(self, request: IRequest, tag: Tag = tags.head) -> KleinRenderable:
type="text/css", rel="stylesheet", media="screen",
href=urls.styleSheet.asText(),
),
tags.script(src=urls.jqueryJS.asText()),
tags.script(src=urls.bootstrapJS.asText()),
self.title(request),
# JavaScript resource imports
imports,
# Child elements
children,
)

Expand Down Expand Up @@ -127,7 +183,7 @@ def bottom(
@renderer
def nav(self, request: IRequest, tag: Tag = tags.nav) -> KleinRenderable:
"""
<nav> element.
`<nav>` element.
"""
return NavElement(config=self.config)

Expand All @@ -137,7 +193,7 @@ def header(
self, request: IRequest, tag: Tag = tags.header
) -> KleinRenderable:
"""
<header> element.
`<header>` element.
"""
return HeaderElement(config=self.config)

Expand All @@ -147,6 +203,6 @@ def footer(
self, request: IRequest, tag: Tag = tags.footer
) -> KleinRenderable:
"""
<footer> element.
`<footer>` element.
"""
return FooterElement(config=self.config)
6 changes: 1 addition & 5 deletions src/ims/element/admin/template.xhtml
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
<!DOCTYPE html>
<html xmlns:t="http://twistedmatrix.com/ns/twisted.web.template/0.1" t:render="root">

<head t:render="head">
<script t:render="url" url="momentJS" />
<script t:render="url" url="imsJS" />
<script t:render="url" url="adminJS" />
</head>
<head t:render="head" imports="ims,admin" />

<body>
<div t:render="container">
Expand Down
9 changes: 2 additions & 7 deletions src/ims/element/admin_acl/template.xhtml
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
<!DOCTYPE html>
<html xmlns:t="http://twistedmatrix.com/ns/twisted.web.template/0.1" t:render="root">

<head t:render="head">
<script t:render="url" url="momentJS" />
<script t:render="url" url="imsJS" />
<script t:render="url" url="adminAccessControlJS" />
</head>
<head t:render="head" imports="ims,adminAccessControl" />

<body>
<div t:render="container">
Expand Down Expand Up @@ -39,8 +35,7 @@
</body>

<script>
var events = <json t:render="events_list" />;
var accessURL = <json t:render="url" url="acl" />;
var events = <json t:render="events_list" />;

initPage();
</script>
Expand Down
9 changes: 2 additions & 7 deletions src/ims/element/admin_streets/template.xhtml
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
<!DOCTYPE html>
<html xmlns:t="http://twistedmatrix.com/ns/twisted.web.template/0.1" t:render="root">

<head t:render="head">
<script t:render="url" url="momentJS" />
<script t:render="url" url="imsJS" />
<script t:render="url" url="adminStreetsJS" />
</head>
<head t:render="head" imports="ims,adminStreets" />

<body>
<div t:render="container">
Expand Down Expand Up @@ -41,8 +37,7 @@
</body>

<script>
var events = <json t:render="events_list" />;
var streetsURL = <json t:render="url" url="streets" />;
var events = <json t:render="events_list" />;

initPage();
</script>
Expand Down
9 changes: 2 additions & 7 deletions src/ims/element/admin_types/template.xhtml
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
<!DOCTYPE html>
<html xmlns:t="http://twistedmatrix.com/ns/twisted.web.template/0.1" t:render="root">

<head t:render="head">
<script t:render="url" url="momentJS" />
<script t:render="url" url="imsJS" />
<script t:render="url" url="adminIncidentTypesJS" />
</head>
<head t:render="head" imports="ims,adminIncidentTypes" />

<body>
<div t:render="container">
Expand Down Expand Up @@ -41,8 +37,7 @@
</body>

<script>
var events = <json t:render="events_list" />;
var incidentTypesURL = <json t:render="url" url="incidentTypes" />;
var events = <json t:render="events_list" />;

initPage();
</script>
Expand Down
24 changes: 0 additions & 24 deletions src/ims/element/incident/_incident.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,30 +77,6 @@ def incident_number(self, request: IRequest, tag: Tag) -> KleinRenderable:
return jsonTextFromObject(self.number)


@renderer
def incidents_url(self, request: IRequest, tag: Tag) -> KleinRenderable:
"""
JSON string: URL for incidents endpoint for the event.
"""
return jsonTextFromObject(
self.config.urls.incidents.asText()
.replace("<eventID>", self.event.id)
)


@renderer
def view_incidents_url(
self, request: IRequest, tag: Tag
) -> KleinRenderable:
"""
JSON string: URL for incidents page for the event.
"""
return jsonTextFromObject(
self.config.urls.viewIncidents.asText()
.replace("<eventID>", self.event.id)
)


@renderer
async def concentric_street_name_by_id(
self, request: IRequest, tag: Tag
Expand Down
26 changes: 9 additions & 17 deletions src/ims/element/incident/template.xhtml
Original file line number Diff line number Diff line change
@@ -1,28 +1,20 @@
<!DOCTYPE html>
<html xmlns:t="http://twistedmatrix.com/ns/twisted.web.template/0.1" t:render="root">

<head t:render="head">
<script t:render="url" url="momentJS" />
<script t:render="url" url="lscacheJS" />
<script t:render="url" url="imsJS" />
<script t:render="url" url="viewIncidentJS" />
</head>
<head t:render="head" imports="lscache,ims,viewIncident"
/>

<body />

<script>
<!-- FIXME: figure out how to move this to / include from incident.js -->
var editingAllowed = <json t:render="editing_allowed" />;
var eventID = <json t:render="event_id" />;
var incidentNumber = <json t:render="incident_number" />;
var incidentsURL = <json t:render="incidents_url" />;
var viewIncidentsURL = <json t:render="view_incidents_url" />;
var pageTemplateURL = <json t:render="url" url="viewIncidentTemplate" />;
var personnelURL = <json t:render="url" url="personnel" />;
var incidentTypesURL = <json t:render="url" url="incidentTypes" />;
var incidentReportsURL = <json t:render="url" url="incidentReports" />;
var viewIncidentReportsURL = <json t:render="url" url="viewIncidentReports" />;
var eventSourceURL = <json t:render="url" url="eventSource" />;
var editingAllowed = <json t:render="editing_allowed" />;
var eventID = <json t:render="event_id" />;
var incidentNumber = <json t:render="incident_number" />;

var pageTemplateURL = url_viewIncidentTemplate;
var incidentsURL = urlReplace(url_incidents, eventID);
var viewIncidentsURL = urlReplace(url_viewIncidents, eventID);

var concentricStreetNameByID = <json t:render="concentric_street_name_by_id" />;

Expand Down
Loading