Skip to content

Commit

Permalink
Initial work for serving html/static content
Browse files Browse the repository at this point in the history
Fixed user_proxy to work with emails
Setup FeHandler and Jinja2 Environment
Added setting for cdnjs prefix
Moved common code into BaseHandler
Initial CSS, app.html, error.html
  • Loading branch information
gmjosack committed Jan 1, 2015
1 parent 0b069e5 commit 9b68b2f
Show file tree
Hide file tree
Showing 11 changed files with 223 additions and 11 deletions.
3 changes: 2 additions & 1 deletion bin/nsot-ctl
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,12 @@ def user_proxy_command(args):
if username is None:
username = getpass.getuser()
logging.debug("No username provided, using (%s)", username)
username += "@localhost"

server = BaseHTTPServer.HTTPServer(
('localhost', args.listen_port), UserProxyHandler
)
server.args = ServerArgs(args.backend_port, args.username)
server.args = ServerArgs(args.backend_port, username)
try:
logging.info(
"Starting user_proxy on port (%s) with user (%s)",
Expand Down
5 changes: 4 additions & 1 deletion bin/nsot-server
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import nsot
from nsot.app import Application
from nsot.settings import settings
from nsot.models import get_db_engine, Session
from nsot.util import get_loglevel
from nsot.util import get_loglevel, get_template_env


from sqlalchemy.exc import OperationalError
Expand Down Expand Up @@ -46,7 +46,9 @@ def main(argv):
sa_log.setLevel(logging.INFO)

tornado_settings = {
"static_path": os.path.join(os.path.dirname(nsot.__file__), "static"),
"debug": settings.debug,
"xsrf_cookies": True,
}

db_engine = get_db_engine(settings.database)
Expand All @@ -55,6 +57,7 @@ def main(argv):
my_settings = {
"db_engine": db_engine,
"db_session": Session,
"template_env": get_template_env()
}

application = Application(my_settings=my_settings, **tornado_settings)
Expand Down
5 changes: 5 additions & 0 deletions config/dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,8 @@ database: "sqlite:///nsot.sqlite"
# Header to check for Authenticated Email
# Type: str
user_auth_header: "X-NSoT-Email"

# This is the prefix url in template to cdnjs. This allows you to point at
# and internal mirror for production deployments.
# Type: str
cdnjs_prefix: "//cdnjs.cloudflare.com"
5 changes: 5 additions & 0 deletions nsot/handlers/fe.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from .util import FeHandler

class AppHandler(FeHandler):
def get(self):
return self.render("app.html")
56 changes: 49 additions & 7 deletions nsot/handlers/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,9 @@
from ..settings import settings


class ApiHandler(RequestHandler):
class BaseHandler(RequestHandler):
def initialize(self):
self.session = self.application.my_settings.get("db_session")()
self._jbody = None

def on_finish(self):
self.session.close()
Expand All @@ -27,6 +26,51 @@ def get_current_user(self):

return user

def prepare(self):
try:
if not self.current_user:
return self.unauthorized("Not logged in.")
except exc.ValidationError as err:
return self.badrequest(err.message)

def badrequest(self, message):
pass

def unauthorized(self, message):
pass


class FeHandler(BaseHandler):
def render_template(self, template_name, **kwargs):
template = self.application.my_settings["template_env"].get_template(
template_name
)
content = template.render(kwargs)
return content

def render(self, template_name, **kwargs):
context = {}
context.update(self.get_template_namespace())
context.update(kwargs)
self.write(self.render_template(template_name, **context))

def badrequest(self, message):
self.set_status(400)
self.render("error.html", code=400, message=message)
self.finish()

def unauthorized(self, message):
self.set_status(401)
self.render("error.html", code=401, message=message)
self.finish()



class ApiHandler(BaseHandler):
def initialize(self):
BaseHandler.initialize(self)
self._jbody = None

@property
def jbody(self):
if self._jbody is None:
Expand All @@ -37,11 +81,9 @@ def jbody(self):
return self._jbody

def prepare(self):
try:
if not self.current_user:
return self.unauthorized("Not logged in.")
except exc.ValidationError as err:
return self.badrequest(err.message)
rv = BaseHandler.prepare(self)
if rv is not None:
return rv

if self.request.method.lower() in ("put", "post"):
if self.request.headers.get("Content-Type").lower() != "application/json":
Expand Down
7 changes: 5 additions & 2 deletions nsot/routes.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from .handlers import api
from .handlers import api, fe

HANDLERS = [

Expand Down Expand Up @@ -32,6 +32,9 @@
api.UserPermissionHandler
),

(r"/.*", api.NotFoundHandler),
(r"/api/.*", api.NotFoundHandler),


# Frontend Handlers
(r".*", fe.AppHandler),
]
1 change: 1 addition & 0 deletions nsot/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,5 @@ def __getattr__(self, name):
"debug": False,
"port": 8990,
"user_auth_header": "X-NSoT-Email",
"cdnjs_prefix": "//cdnjs.cloudflare.com",
})
63 changes: 63 additions & 0 deletions nsot/static/css/nsot.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
.container-fluid {
margin-bottom: 20px;
}

.navbar-default {
background-color: #343434;
border-color: #a3114f;
}
.navbar-default .navbar-brand {
color: #ecf0f1;
}
.navbar-default .navbar-brand:hover, .navbar-default .navbar-brand:focus {
color: #ecdbff;
}
.navbar-default .navbar-text {
color: #ecf0f1;
}
.navbar-default .navbar-nav > li > a {
color: #ecf0f1;
}
.navbar-default .navbar-nav > li > a:hover, .navbar-default .navbar-nav > li > a:focus {
color: #ecdbff;
}
.navbar-default .navbar-nav > .active > a, .navbar-default .navbar-nav > .active > a:hover, .navbar-default .navbar-nav > .active > a:focus {
color: #ecdbff;
background-color: #a3114f;
}
.navbar-default .navbar-nav > .open > a, .navbar-default .navbar-nav > .open > a:hover, .navbar-default .navbar-nav > .open > a:focus {
color: #ecdbff;
background-color: #a3114f;
}
.navbar-default .navbar-toggle {
border-color: #a3114f;
}
.navbar-default .navbar-toggle:hover, .navbar-default .navbar-toggle:focus {
background-color: #a3114f;
}
.navbar-default .navbar-toggle .icon-bar {
background-color: #ecf0f1;
}
.navbar-default .navbar-collapse,
.navbar-default .navbar-form {
border-color: #ecf0f1;
}
.navbar-default .navbar-link {
color: #ecf0f1;
}
.navbar-default .navbar-link:hover {
color: #ecdbff;
}

@media (max-width: 767px) {
.navbar-default .navbar-nav .open .dropdown-menu > li > a {
color: #ecf0f1;
}
.navbar-default .navbar-nav .open .dropdown-menu > li > a:hover, .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {
color: #ecdbff;
}
.navbar-default .navbar-nav .open .dropdown-menu > .active > a, .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover, .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {
color: #ecdbff;
background-color: #a3114f;
}
}
39 changes: 39 additions & 0 deletions nsot/templates/app.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<!DOCTYPE html>
{% autoescape true %}
<html ng-app="nsot">
<head>
<title>NSoT</title>

<link href="{{cdnjs_prefix}}/ajax/libs/twitter-bootstrap/3.3.1/css/bootstrap.min.css"
rel="stylesheet"
media="screen">
<link href="{{cdnjs_prefix}}/ajax/libs/font-awesome/4.2.0/css/font-awesome.min.css"
rel="stylesheet"
media="screen">
<link href="/static/css/nsot.css" rel="stylesheet" media="screen">
</head>
<body>
<div class="container-fluid">
<div class="row">
<nav class="navbar navbar-static-top navbar-default" role="navigation">
<div class="col-sm-10 col-sm-offset-1">
<a class="navbar-brand" href="/">NSoT.</a>
</div>
</nav>
</div>

<div class="row content">
<div class="col-md-12 text-center">
{% block content %}
{% endblock %}
</div>
</div>
</div>

<script src="{{cdnjs_prefix}}/ajax/libs/lodash.js/2.4.1/lodash.min.js"></script>
<script src="{{cdnjs_prefix}}/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="{{cdnjs_prefix}}/ajax/libs/twitter-bootstrap/3.3.1/js/bootstrap.min.js"></script>
<script src="{{cdnjs_prefix}}/ajax/libs/moment.js/2.8.4/moment.min.js"></script>
</body>
</html>
{% endautoescape %}
23 changes: 23 additions & 0 deletions nsot/templates/error.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<!DOCTYPE html>
{% autoescape true %}
<html>
<head>
<title>NSoT Error</title>

<link href="{{cdnjs_prefix}}/ajax/libs/twitter-bootstrap/3.3.1/css/bootstrap.min.css"
rel="stylesheet"
media="screen">
</head>
<body>
<div class="container-fluid">
<div class="row content">
<div class="col-md-12 text-center">
<div class="alert alert-danger">
{{code}} - {{message}}
</div>
</div>
</div>
</div>
</body>
</html>
{% endautoescape %}
27 changes: 27 additions & 0 deletions nsot/util.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import logging
import tornado
from jinja2 import Environment, PackageLoader

from .settings import settings

_TRUTHY = set([
"true", "yes", "1", ""
Expand All @@ -14,3 +17,27 @@ def get_loglevel(args):
verbose = args.verbose * 10
quiet = args.quiet * 10
return logging.getLogger().level - verbose + quiet


def get_template_env(package="nsot", extra_filters=None, extra_globals=None):
filters = {}
j_globals = {
"cdnjs_prefix": settings["cdnjs_prefix"],
}

if extra_filters:
filters.update(extra_filters)

if extra_globals:
j_globals.update(extra_globals)

env = Environment(
loader=PackageLoader(package, "templates"),
extensions=['jinja2.ext.autoescape'],
autoescape=True

)
env.filters.update(filters)
env.globals.update(j_globals)

return env

0 comments on commit 9b68b2f

Please sign in to comment.