Skip to content

Commit

Permalink
finalized web structure and first working test page. Still a lot of s…
Browse files Browse the repository at this point in the history
…tuff to do....
  • Loading branch information
danwos committed Sep 15, 2016
1 parent aa9a3dd commit 5e72be8
Show file tree
Hide file tree
Showing 11 changed files with 313 additions and 20 deletions.
1 change: 1 addition & 0 deletions groundwork_web/applications/configuration.py
Expand Up @@ -6,5 +6,6 @@

PLUGINS = [
"GwPluginsInfo",
"GwWeb",
"GwWebFlask"
]
55 changes: 55 additions & 0 deletions groundwork_web/patterns/gw_web_pattern/context.py
@@ -0,0 +1,55 @@
from groundwork.util import gw_get


class ContextManagerPlugin:

def __init__(self, plugin):
self.plugin = plugin
self.log = plugin.log
self.app = plugin.app

def register(self, name, template_folder, static_folder, url_prefix, description):
return self.app.web.contexts.register(name, template_folder, static_folder,
url_prefix, description, self.plugin)


class ContextManagerApplication:
def __init__(self, app):
self._contexts = {}
self.app = app
self.default_context = None

def register(self, name, template_folder, static_folder, url_prefix, description, plugin):
if name not in self._contexts.keys():
self._contexts[name] = Context(name, template_folder, static_folder, url_prefix, description, plugin)
if name == self.app.config.get("DEFAULT_CONTEXT", None) or self.default_context is None:
self.default_context = self._contexts[name]

for name, provider in self.app.web.providers.get().items():
provider.register_context()

def get(self, name=None, plugin=None):
return gw_get(self._contexts, name, plugin)


class Context:
"""
Contexts are used to collect common objects in a single place and make it easy for new web routes to reuse
these objects.
Common objects are:
* A template folder
* A static folder
* A url_prefix
* A static folder web route, which gets automatically calculated based on given context name
They are similar to flask blueprint concept.
"""
def __init__(self, name, template_folder, static_folder, url_prefix, description, plugin):
self.name = name
self.template_folder = template_folder
self.static_folder = static_folder
self.url_prefix = url_prefix
self.description = description
self.plugin = plugin
11 changes: 8 additions & 3 deletions groundwork_web/patterns/gw_web_pattern/gw_web_pattern.py
Expand Up @@ -3,6 +3,8 @@

from groundwork_web.patterns.gw_web_pattern.provider import ProviderManagerApplication, ProviderManagerPlugin
from groundwork_web.patterns.gw_web_pattern.server import ServerManagerApplication, ServerManagerPlugin
from groundwork_web.patterns.gw_web_pattern.context import ContextManagerApplication, ContextManagerPlugin
from groundwork_web.patterns.gw_web_pattern.route import RouteManagerApplication, RouteManagerPlugin


class GwWebPattern(GwBasePattern):
Expand All @@ -22,8 +24,10 @@ def __init__(self, plugin):
self.plugin = plugin
self.app = plugin.app
self.log = plugin.log
self.providers = ProviderManagerPlugin(self)
self.servers = ServerManagerPlugin
self.providers = ProviderManagerPlugin(plugin)
self.servers = ServerManagerPlugin(plugin)
self.contexts = ContextManagerPlugin(plugin)
self.routes = RouteManagerPlugin(plugin)


class WebApplication:
Expand All @@ -32,6 +36,7 @@ def __init__(self, app):
self.log = logging.getLogger(__name__)
self.providers = ProviderManagerApplication(app)
self.servers = ServerManagerApplication(app)

self.contexts = ContextManagerApplication(app)
self.routes = RouteManagerApplication(app)


68 changes: 67 additions & 1 deletion groundwork_web/patterns/gw_web_pattern/provider.py
@@ -1,3 +1,6 @@
from groundwork.util import gw_get


class ProviderManagerPlugin:

def __init__(self, plugin):
Expand All @@ -8,21 +11,84 @@ def __init__(self, plugin):
def register(self, name, instance, description):
return self.app.web.providers.register(name, instance, description, self.plugin)

def render(self, *args, **kwargs):
return self.app.web.providers.render(*args, **kwargs)


class ProviderManagerApplication:
def __init__(self, app):
self._providers = {}
self.app = app
self._default_provider = None

def register(self, name, instance, description, plugin):
if name not in self._providers.keys():
self._providers[name] = Provider(name, instance, description, plugin)
self._load_context(self._providers[name])
self._load_routes(self._providers[name])

if name == self.app.config.get("DEFAULT_PROVIDER", None) or self._default_provider is None:
self._default_provider = self._providers[name]

def render(self, template, provider=None, **kwargs):
if self._default_provider is None:
raise RuntimeError("No default provider is set")
if provider is None:
return self._default_provider.instance.render(template, **kwargs)
if provider not in self._providers.keys():
raise NameError("Provider %s does not exist" % provider)

return self._providers[provider].instance.render(template, **kwargs)

def set_default_provider(self, name):
if name not in self._providers.keys():
raise NameError("Provider %s does not exist" % name)
self._default_provider = self._providers[name]

def get(self, name=None, plugin=None):
return gw_get(self._providers, name, plugin)

def _load_routes(self, provider):
if provider.instance is not None:
for name, route in self.app.web.routes.get().items():
provider.instance.register_route(route.url, route.methods, route.endpoint, route.context)

def _load_context(self, provider):
if provider.instance is not None:
for name, context in self.app.web.contexts.get().items():
provider.instance.register_context(context.name, context.template_folder,
context.static_folder, context.url_prefix)


class Provider:
def __init__(self, name, instance, description, plugin):
self.name = name
self.instance = instance

if isinstance(instance, BaseProvider):
self.instance = instance
else:
raise TypeError("instance must be of type BaseProvider, got %s instead" % str(type(instance)))

self.description = description
self.plugin = plugin


class BaseProvider:
def __init__(self, instance=None):
self.instance = instance

def register_route(self, url, methods, endpoint, context, *arg, **kwargs):
pass

def unregister_route(self, url, methods, context, *arg, **kwargs):
pass

def register_context(self, name, template_folder, static_folder, url_prefix, *arg, **kwargs):
pass

def unregister_context(self, name):
pass

def render(self, template, **kwargs):
pass

48 changes: 48 additions & 0 deletions groundwork_web/patterns/gw_web_pattern/route.py
@@ -0,0 +1,48 @@
from groundwork.util import gw_get


class RouteManagerPlugin:

def __init__(self, plugin):
self.plugin = plugin
self.log = plugin.log
self.app = plugin.app

def register(self, url, methods, endpoint, context=None, name=None, description=None):
return self.app.web.routes.register(url, methods, endpoint, self.plugin, context, name, description)


class RouteManagerApplication:
def __init__(self, app):
self._routes = {}
self.app = app

def register(self, url, methods, endpoint, plugin, context=None, name=None, description=None,):
if context is None and self.app.web.contexts.default_context is None:
raise RuntimeError("Context not give and no default context is available.")

if context is None:
context = self.app.web.contexts.default_context.name

if name not in self._routes.keys():
self._routes[name] = Route(url, methods, endpoint, context, name, description, plugin)

for provider in self.app.web.providers.get():
provider.instance.register_route()

def get(self, name=None, plugin=None):
return gw_get(self._routes, name, plugin)


class Route:
"""
"""
def __init__(self, url, methods, endpoint, context, name, description, plugin):
self.url = url
self.methods = methods
self.endpoint = endpoint
self.context = context
self.name = name
self.description = description
self.plugin = plugin

40 changes: 32 additions & 8 deletions groundwork_web/patterns/gw_web_pattern/server.py
@@ -1,27 +1,51 @@
class ServerManagerPlugin:
from groundwork.util import gw_get


class ServerManagerPlugin():

def __init__(self, plugin):
self.plugin = plugin
self.log = plugin.log
self.app = plugin.app

def register(self, name, description):
return self.app.web.server.register(name, description, self.plugin)
def register(self, name, function, description):
return self.app.web.servers.register(name, function, description, self.plugin)

def get(self, name=None):
"""
Returns servers, which can be filtered by name.
:param name: name of the server
:type name: str
:return: None, single server or dict of servers
"""
return self.app.web.servers.get(name, self.plugin)


class ServerManagerApplication:
def __init__(self, app):
self._servers = {}
self.app = app

def register(self, name, description, plugin):
def register(self, name, function, description, plugin):
if name not in self._servers.keys():
self._servers[name] = Server(name, description, plugin)
self._servers[name] = Server(name, function, description, plugin)

def get(self, name=None, plugin=None):
"""
Returns servers, which can be filtered by name or plugin.
:param name: name of the server
:type name: str
:param plugin: plugin name, which registers the servers
:return: None, single server or dict of servers
"""
return gw_get(self._servers, name, plugin)


class Server:
def __init__(self, name, start, description, plugin):
class Server():
def __init__(self, name, function, description, plugin):
self.name = name
self.start = start
self.function = function
self.description = description
self.plugin = plugin
1 change: 1 addition & 0 deletions groundwork_web/plugins/gw_web/__init__.py
@@ -0,0 +1 @@
__author__ = 'daniel'
60 changes: 60 additions & 0 deletions groundwork_web/plugins/gw_web/gw_web.py
@@ -0,0 +1,60 @@
import os
from click import Argument, echo

from groundwork.patterns import GwCommandsPattern


from groundwork_web.patterns import GwWebPattern


class GwWeb(GwWebPattern, GwCommandsPattern):
def __init__(self, *args, **kwargs):
self.name = self.__class__.__name__
super().__init__(*args, **kwargs)

def activate(self):
self.commands.register("server_start", "starts a given server",
self.__server_start,
params=[Argument(("server",), required=True)])

self.commands.register("server_list", "prints a list of registered server",
self.__server_list)

template_folder = os.path.join(os.path.abspath(os.path.dirname(__file__)), "templates")
static_folder = os.path.join(os.path.abspath(os.path.dirname(__file__)), "static")
self.web.contexts.register("web",
template_folder=template_folder,
static_folder=static_folder,
url_prefix=None,
description="web context, which was created by GwWeb as initial context")

if self.app.config.get("SHOW_WEB_TEST_PAGE", True):
self.web.routes.register("/test", ["GET"], self.__test_view,
name="Test", description="Test view of GwWeb")

def deactivate(self):
self.commands.unregister("server_start")
self.commands.unregister("server_list")

def __server_start(self, server):
servers = self.app.web.servers.get()
if server not in servers.keys():
echo("Server '%s' not found.")
echo("Available servers: %s" % ",".join(servers.keys()))
else:
echo("Starting server %s" % server)
servers[server].function()

def __server_list(self):
servers = self.app.web.servers.get()
echo("List of registered servers\n")
for name, server in servers.items():
echo(name)
echo("*"*len(name))
echo(" Description: %s" % server.description)
echo(" Plugin: %s" % server.plugin.name)

def __test_view(self):
return self.web.providers.render("test.html")


1 change: 1 addition & 0 deletions groundwork_web/plugins/gw_web/templates/test.html
@@ -0,0 +1 @@
Hello there!

0 comments on commit 5e72be8

Please sign in to comment.