web application base layout
This commit is contained in:
0
cmd/server/assets/test.txt
Normal file
0
cmd/server/assets/test.txt
Normal file
21
cmd/server/assets/vendor/bulma-0.7.2/LICENSE
vendored
Normal file
21
cmd/server/assets/vendor/bulma-0.7.2/LICENSE
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2018 Jeremy Thomas
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
1
cmd/server/assets/vendor/bulma-0.7.2/css/bulma.css.map
vendored
Normal file
1
cmd/server/assets/vendor/bulma-0.7.2/css/bulma.css.map
vendored
Normal file
File diff suppressed because one or more lines are too long
1
cmd/server/assets/vendor/bulma-0.7.2/css/bulma.min.css
vendored
Normal file
1
cmd/server/assets/vendor/bulma-0.7.2/css/bulma.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -5,8 +5,10 @@ import (
|
||||
)
|
||||
|
||||
type config struct {
|
||||
HTTPHost string `env:"ORION_HTTP_HOST"`
|
||||
HTTPPort string `env:"ORION_HTTP_PORT"`
|
||||
HTTPHost string `env:"ORION_HTTP_HOST"`
|
||||
HTTPPort string `env:"ORION_HTTP_PORT"`
|
||||
TemplateDir string `env:"ORION_TEMPLATE_DIR"`
|
||||
AssetDir string `env:"ORION_ASSET_DIR"`
|
||||
}
|
||||
|
||||
func overwriteFromEnv(conf *config) error {
|
||||
@ -18,7 +20,9 @@ func overwriteFromEnv(conf *config) error {
|
||||
|
||||
func newDefaultConfig() *config {
|
||||
return &config{
|
||||
HTTPHost: "0.0.0.0",
|
||||
HTTPPort: "8888",
|
||||
HTTPHost: "0.0.0.0",
|
||||
HTTPPort: "8888",
|
||||
TemplateDir: "./templates",
|
||||
AssetDir: "./assets",
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
package rpc
|
||||
package jsonrpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
@ -7,10 +7,10 @@ import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"forge.cadoles.com/Cadoles/owrt"
|
||||
"forge.cadoles.com/Pyxis/orion/emlid"
|
||||
"forge.cadoles.com/Pyxis/orion/emlid/reachview"
|
||||
"forge.cadoles.com/Pyxis/orion/emlid/updater"
|
||||
"forge.cadoles.com/Pyxis/orion/openwrt"
|
||||
"github.com/gorilla/rpc"
|
||||
"github.com/gorilla/rpc/json"
|
||||
"github.com/pkg/errors"
|
||||
@ -18,12 +18,12 @@ import (
|
||||
|
||||
// OrionService is the JSON-RPC API
|
||||
type OrionService struct {
|
||||
UCI *openwrt.UCI
|
||||
UCI *owrt.UCI
|
||||
}
|
||||
|
||||
// NewOrionService create a new OrionService !
|
||||
func NewOrionService() *OrionService {
|
||||
uci := openwrt.NewUCI()
|
||||
uci := owrt.NewUCI()
|
||||
return &OrionService{
|
||||
UCI: uci,
|
||||
}
|
||||
@ -50,7 +50,7 @@ type ListIfaceArgs struct{}
|
||||
|
||||
// ListIfaceResponse is the response structure for exposed method OwrtListWifiDevices
|
||||
type ListIfaceResponse struct {
|
||||
Interfaces []*openwrt.UCIWirelessInterface
|
||||
Interfaces map[int]*owrt.UCIWirelessInterface
|
||||
}
|
||||
|
||||
// OwrtListWifiInterfaces offers an RPC Method to list wifi interfaces in a OpenWRT device.
|
||||
@ -63,13 +63,13 @@ func (o *OrionService) OwrtListWifiInterfaces(r *http.Request, args *ListIfaceAr
|
||||
// CreateIfaceArgs argument structure for exported method OwrtCreateWifiInterface
|
||||
type CreateIfaceArgs struct {
|
||||
Cleanup bool
|
||||
Iface *openwrt.UCIWirelessInterface
|
||||
Iface *owrt.UCIWirelessInterface
|
||||
}
|
||||
|
||||
// CreateIfaceResponse argument structure for exported method OwrtCreateWifiInterface
|
||||
type CreateIfaceResponse struct {
|
||||
Errors []*openwrt.Action
|
||||
Iface *openwrt.UCIWirelessInterface
|
||||
Errors []*owrt.Action
|
||||
Iface *owrt.UCIWirelessInterface
|
||||
}
|
||||
|
||||
// OwrtCreateWifiInterface Create a WifiInterface in openwrt
|
||||
@ -124,7 +124,7 @@ func (o *OrionService) OwrtCreateWifiInterface(r *http.Request,
|
||||
|
||||
// ConnectIfaceArgs argument structure for exported method OwrtCreateWifiInterface
|
||||
type ConnectIfaceArgs struct {
|
||||
Iface *openwrt.UCIWirelessInterface
|
||||
Iface *owrt.UCIWirelessInterface
|
||||
SSID string
|
||||
Key string
|
||||
}
|
||||
@ -175,7 +175,7 @@ type OrionServer struct {
|
||||
SSID string
|
||||
Security string
|
||||
WifiKey string
|
||||
ClientIface *openwrt.UCIWirelessInterface
|
||||
ClientIface *owrt.UCIWirelessInterface
|
||||
}
|
||||
|
||||
// UpdateOrionBoxArgs argument structure for exported method OwrtCreateWifiInterface
|
||||
@ -212,7 +212,7 @@ func (o *OrionService) connectBox(box *OrionBox, server *OrionServer) error {
|
||||
if cn.ReturnCode != 0 {
|
||||
return fmt.Errorf("%s\n%s", cn.Stdout, cn.Stderr)
|
||||
}
|
||||
dhcli := openwrt.NewDhcpClient(iface.SysDevName)
|
||||
dhcli := owrt.NewDhcpClient(iface.SysDevName)
|
||||
dhres := dhcli.AskForIP()
|
||||
if dhres.CmdRes.ReturnCode != 0 {
|
||||
return fmt.Errorf("%s\n%s", cn.Stdout, cn.Stderr)
|
34
cmd/server/jsonrpc/service.go
Normal file
34
cmd/server/jsonrpc/service.go
Normal file
@ -0,0 +1,34 @@
|
||||
package jsonrpc
|
||||
|
||||
import (
|
||||
"forge.cadoles.com/wpetit/goweb/service"
|
||||
"github.com/gorilla/rpc"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const ServiceName service.Name = "jsonrpc"
|
||||
|
||||
// From retrieves the JSONRPC service in the given container or panic
|
||||
func From(container *service.Container) (*rpc.Server, error) {
|
||||
|
||||
service, err := container.Service(ServiceName)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "error while retrieving '%s' service", ServiceName)
|
||||
}
|
||||
|
||||
jsonRPCService, ok := service.(*rpc.Server)
|
||||
if !ok {
|
||||
return nil, errors.Errorf("retrieved service is not a valid '%s' service", ServiceName)
|
||||
}
|
||||
|
||||
return jsonRPCService, nil
|
||||
}
|
||||
|
||||
// Must retrieves the json-rpc service in the given container or panic otherwise
|
||||
func Must(container *service.Container) *rpc.Server {
|
||||
service, err := From(container)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return service
|
||||
}
|
@ -4,15 +4,28 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/rpc"
|
||||
|
||||
"github.com/gorilla/sessions"
|
||||
|
||||
"forge.cadoles.com/wpetit/goweb/static"
|
||||
|
||||
"forge.cadoles.com/wpetit/goweb/session/gorilla"
|
||||
"forge.cadoles.com/wpetit/goweb/template/html"
|
||||
|
||||
"forge.cadoles.com/Pyxis/orion/cmd/server/rpc"
|
||||
"github.com/go-chi/chi"
|
||||
"github.com/go-chi/chi/middleware"
|
||||
|
||||
goweb "forge.cadoles.com/wpetit/goweb/middleware"
|
||||
"forge.cadoles.com/wpetit/goweb/service/session"
|
||||
"forge.cadoles.com/wpetit/goweb/service/template"
|
||||
|
||||
"forge.cadoles.com/Pyxis/orion/cmd/server/jsonrpc"
|
||||
"forge.cadoles.com/wpetit/goweb/service"
|
||||
"github.com/go-chi/chi"
|
||||
)
|
||||
|
||||
var (
|
||||
conf = newDefaultConfig()
|
||||
jsonrpc = rpc.NewServer()
|
||||
conf = newDefaultConfig()
|
||||
)
|
||||
|
||||
func main() {
|
||||
@ -21,24 +34,80 @@ func main() {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
r := chi.NewRouter()
|
||||
// Create service container
|
||||
container := service.NewContainer()
|
||||
container.Provide(jsonrpc.ServiceName, getJSONRPCServiceProvider())
|
||||
container.Provide(template.ServiceName, getTemplateServiceProvider(conf.TemplateDir))
|
||||
container.Provide(session.ServiceName, getSessionServiceProvider())
|
||||
|
||||
r.Use(middleware.Recoverer)
|
||||
r.Use(middleware.RequestID)
|
||||
r.Use(middleware.RealIP)
|
||||
r.Use(middleware.Logger)
|
||||
router := chi.NewRouter()
|
||||
|
||||
r.Post("/rpc", handleRPC)
|
||||
router.Use(middleware.Recoverer)
|
||||
router.Use(middleware.RequestID)
|
||||
router.Use(middleware.Logger)
|
||||
router.Use(goweb.ServiceContainer(container))
|
||||
|
||||
// Define routes
|
||||
router.Get("/", serveHomepage)
|
||||
router.Post("/rpc", handleJSONRPC)
|
||||
router.Get("/**", static.Dir(conf.AssetDir, "", router.NotFoundHandler()))
|
||||
|
||||
hostStr := fmt.Sprintf("%s:%s", conf.HTTPHost, conf.HTTPPort)
|
||||
log.Printf("listening on http://%s", hostStr)
|
||||
|
||||
if err := http.ListenAndServe(hostStr, r); err != nil {
|
||||
log.Printf("listening on http://%s", hostStr)
|
||||
if err := http.ListenAndServe(hostStr, router); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func handleRPC(w http.ResponseWriter, r *http.Request) {
|
||||
jsonrpc.ServeHTTP(w, r)
|
||||
func getJSONRPCServiceProvider() service.Provider {
|
||||
jsonrpc := rpc.NewServer()
|
||||
return func(c *service.Container) (interface{}, error) {
|
||||
return jsonrpc, nil
|
||||
}
|
||||
}
|
||||
|
||||
func getTemplateServiceProvider(templateDir string) service.Provider {
|
||||
|
||||
// Create templateService at application startup
|
||||
templateService := html.NewTemplateService()
|
||||
|
||||
// Load templates and keep error in cache
|
||||
err := templateService.LoadTemplates(templateDir)
|
||||
|
||||
return func(c *service.Container) (interface{}, error) {
|
||||
|
||||
// If an error occured during the templates loading
|
||||
// return the error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return templateService, nil
|
||||
}
|
||||
}
|
||||
|
||||
func getSessionServiceProvider() service.Provider {
|
||||
|
||||
// Create a new encrypted/authenticated cookie store for the session
|
||||
cookieStore, err := gorilla.CreateCookieSessionStore(32, 64)
|
||||
|
||||
var sessionService session.Service
|
||||
if err == nil {
|
||||
sessionService = gorilla.NewSessionService(
|
||||
"orion",
|
||||
cookieStore,
|
||||
&sessions.Options{
|
||||
HttpOnly: true,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
return func(c *service.Container) (interface{}, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return sessionService, nil
|
||||
}
|
||||
|
||||
}
|
||||
|
33
cmd/server/route.go
Normal file
33
cmd/server/route.go
Normal file
@ -0,0 +1,33 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"forge.cadoles.com/wpetit/goweb/middleware"
|
||||
"forge.cadoles.com/wpetit/goweb/service"
|
||||
"forge.cadoles.com/wpetit/goweb/service/template"
|
||||
|
||||
"forge.cadoles.com/Pyxis/orion/cmd/server/jsonrpc"
|
||||
)
|
||||
|
||||
func serveHomepage(w http.ResponseWriter, r *http.Request) {
|
||||
container := getServiceContainer(r)
|
||||
templateService := template.Must(container)
|
||||
if err := templateService.RenderPage(w, "home.html.tmpl", nil); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func handleJSONRPC(w http.ResponseWriter, r *http.Request) {
|
||||
container := getServiceContainer(r)
|
||||
rpcServer := jsonrpc.Must(container)
|
||||
rpcServer.ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
func getServiceContainer(r *http.Request) *service.Container {
|
||||
container, err := middleware.GetServiceContainer(r.Context())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return container
|
||||
}
|
23
cmd/server/templates/blocks/base.html.tmpl
Normal file
23
cmd/server/templates/blocks/base.html.tmpl
Normal file
@ -0,0 +1,23 @@
|
||||
{{define "base"}}
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Orion</title>
|
||||
<link rel="stylesheet" href="/vendor/bulma-0.7.2/css/bulma.min.css">
|
||||
</head>
|
||||
<body>
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<h1 class="title">
|
||||
Hello World
|
||||
</h1>
|
||||
<p class="subtitle">
|
||||
My first website with <strong>Bulma</strong>!
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
</body>
|
||||
</html>
|
||||
{{end}}
|
1
cmd/server/templates/layouts/home.html.tmpl
Normal file
1
cmd/server/templates/layouts/home.html.tmpl
Normal file
@ -0,0 +1 @@
|
||||
{{template "base" .}}
|
Reference in New Issue
Block a user