weblite
|
|
|
|
package weblite
import ( "amp/optparse" "amp/runtime" "amp/structure" "bytes" "fmt" "os" "path/filepath" "template" )
type Response interface{} type Handler func(*Context) Response type Renderer func(*Context, Response) Response
|
|
Context
|
type Context struct { Args []string Kwargs map[string]string Env map[string]interface{} Host string Method string }
func (ctx *Context) Error(message string) { }
func (ctx *Context) Redirect(url string) { }
func (ctx *Context) GetCookie(key string) (value string) { return }
func (ctx *Context) SetCookie(key string, value string) { return } |
|
Auth Provider
|
type AuthProvider interface { GetUser(ctx *Context) interface{} GetUsername(ctx *Context) string IsAdmin(ctx *Context) bool } |
|
Service
|
type Service struct { Handler Handler Renderers []Renderer admin bool auth bool stream bool xsrf bool wildcard bool }
func (service *Service) AdminOnly() *Service { service.admin = true service.auth = true return service }
func (service *Service) AuthOnly() *Service { service.auth = true return service }
func (service *Service) DisableXSRF() *Service { service.xsrf = true return service }
func (service *Service) Stream() *Service { service.stream = true return service } |
|
Templating Provider
|
type TemplatingProvider interface { GenerateRenderer(string) Renderer }
type Templating struct { Debug bool Cache map[string]*template.Template Directory string }
func (templating *Templating) Load(path string) (template *template.Template) { return }
func (templating *Templating) GenerateRenderer(path string) Renderer { return func(ctx *Context, input Response) (resp Response) { template := templating.Load(path) buffer := &bytes.Buffer{} template.Execute(buffer, input) return buffer.String() } } |
|
Standard Application Config
|
type AppConfig struct { assetManifest *string debug *bool genConfig *bool host *string port *int errorDirectory *string frontendHost *string frontendPort *int frontendConnections *int frontendTLS *bool logDirectory *string logRotate *string noConsoleLog *bool runDirectory *string templatesDirectory *string } |
|
Application
|
type Application struct { Auth AuthProvider Name string Config *AppConfig Debug bool Hooks []func() Opts *optparse.OptionParser Path string Services *structure.PrefixTree Templating TemplatingProvider }
func (app *Application) Register(path string, handler Handler, renderers ...interface{}) (service *Service) { list := make([]Renderer, len(renderers)) for i, r := range renderers { switch r.(type) { case string: if app.Templating == nil { panic("Templating used without being enabled: " + r.(string)) } list[i] = app.Templating.GenerateRenderer(r.(string)) case Renderer: list[i] = r.(Renderer) default: panic("Unknown renderer type!") } } service = &Service{Handler: handler, Renderers: list} if path[len(path)-1] == '*' { service.wildcard = true path = path[:len(path)-1] } app.Services.Insert(path, service) return service }
func (app *Application) RegisterAuthProvider(provider AuthProvider) { app.Auth = provider }
func (app *Application) RegisterTemplatingProvider(provider TemplatingProvider) { app.Templating = provider }
func (app *Application) RegisterHook(hook func()) { app.Hooks = append(app.Hooks, hook) }
func (app *Application) ParseOpts() {
opts := app.Opts conf := app.Config
conf.host = opts.StringConfig("weblite-host", "localhost", "the host to bind this weblite server to [localhost]")
conf.port = opts.IntConfig("weblite-port", 8080, "the port to bind this weblite server to [8080]")
conf.frontendHost = opts.StringConfig("frontend-host", "localhost", "the frontend host to connect to [localhost]")
conf.frontendPort = opts.IntConfig("frontend-port", 9040, "the frontend port to connect to [9040]")
conf.frontendConnections = opts.IntConfig("frontend-cxns", 5, "the number of frontend connections to maintain [5]")
conf.frontendTLS = opts.BoolConfig("frontend-tls", false, "use TLS when connecting to the frontend [false]")
conf.runDirectory = opts.StringConfig("run-dir", "run", "the path to the run directory to store locks, pid files, etc. [run]")
conf.errorDirectory = opts.StringConfig("error-dir", "error", "the path to the error templates directory [error]")
conf.logDirectory = opts.StringConfig("log-dir", "log", "the path to the log directory [log]")
conf.logRotate = opts.StringConfig("log-rotate", "never", "specify one of 'hourly', 'daily' or 'never' [never]")
conf.noConsoleLog = opts.BoolConfig("no-console-log", false, "disable server requests being logged to the console [false]")
extraConfig := opts.StringConfig("extra-config", "", "path to a YAML config file with additional options") |
|
Parse the command line options.
|
os.Args[0] = app.Name args := opts.Parse(os.Args) |
|
Print the default YAML config file if the -g flag was specified.
|
if *conf.genConfig { opts.PrintDefaultConfigFile() runtime.Exit(0) }
var instanceDirectory string |
|
Assume the parent directory of the config as the instance directory.
|
if len(args) >= 1 { if args[0] == "help" { opts.PrintUsage() runtime.Exit(0) } configPath, err := filepath.Abs(filepath.Clean(args[0])) if err != nil { runtime.StandardError(err) } err = opts.ParseConfig(configPath, os.Args) if err != nil { runtime.StandardError(err) } instanceDirectory, _ = filepath.Split(configPath) } else { opts.PrintUsage() runtime.Exit(0) } |
|
Load the extra config file with additional options if one has been
specified.
|
if *extraConfig != "" { extraConfigPath, err := filepath.Abs(filepath.Clean(*extraConfig)) if err != nil { runtime.StandardError(err) } extraConfigPath = runtime.JoinPath(instanceDirectory, extraConfigPath) err = opts.ParseConfig(extraConfigPath, os.Args) if err != nil { runtime.StandardError(err) } } |
|
Set the debug mode flag if the -d flag was specified.
|
app.Debug = *conf.debug app.Path = instanceDirectory
for _, hook := range app.Hooks { hook() }
}
func (app *Application) EnableTemplating() *Application {
templating := &Templating{} templatesDirectory := app.Opts.StringConfig("templates-dir", "templates", "the path to the templates directory [templates]")
assetManifest := app.Opts.StringConfig("asset-manifest", "assets.json", "the path to the JSON asset manifest file [assets.json]")
app.RegisterTemplatingProvider(templating) app.RegisterHook(func() { templating.Debug = app.Debug templating.Directory = runtime.JoinPath(app.Path, *templatesDirectory) _ = *assetManifest })
return app
}
func (app *Application) Init(env map[string]interface{}) {
conf := app.Config |
|
Create the log directory if it doesn't exist.
|
logPath := runtime.JoinPath(app.Path, *conf.logDirectory) err := os.MkdirAll(logPath, 0755) if err != nil { runtime.StandardError(err) } |
|
Create the run directory if it doesn't exist.
|
runPath := runtime.JoinPath(app.Path, *conf.runDirectory) err = os.MkdirAll(runPath, 0755) if err != nil { runtime.StandardError(err) } |
|
Initialise the process-related resources.
|
runtime.Init() runtime.InitProcess(app.Name, runPath)
fmt.Printf("Running %s on %s:%d\n", app.Name, *conf.host, *conf.port) app.HandleRequests()
}
func (app *Application) HandleRequests() { for {
} }
func (app *Application) HandleRequest(path string) { ctx := &Context{} matches := app.Services.MatchPrefix(path) if len(matches) == 0 { panic("no match") } var service *Service for i := len(matches); i >= 0; i-- { match := matches[0] service = match.Value.(*Service) if match.Suffix != "" && match.Suffix[0] != '/' && !service.wildcard { continue } break } resp := service.Handler(ctx) renderers := service.Renderers var output map[string]interface{} switch typ := resp.(type) { case map[string]interface{}: output = resp.(map[string]interface{}) case int: output = make(map[string]interface{}) output["output"] = resp.(int) case string: output = make(map[string]interface{}) output["output"] = resp.(string) case nil: output = make(map[string]interface{}) output["output"] = nil } if len(renderers) != 0 { } } |
|
Constructor
|
func App(name, version string) *Application { |
|
Initialise the options parser.
|
opts := optparse.Parser( fmt.Sprintf("Usage: %s <config.yaml> [options]\n", name), fmt.Sprintf("%s %s", name, version))
conf := &AppConfig{} |
|
Create the Application object.
|
app := &Application{ Config: conf, Name: name, Opts: opts, }
app.Hooks = make([]func(), 0) app.Services = structure.NewPrefixTree() |
|
Setup default command line options.
|
conf.debug = opts.Bool([]string{"-d", "--debug"}, false, "enable debug mode")
conf.genConfig = opts.Bool([]string{"-g", "--gen-config"}, false, "show the default yaml config")
return app
}
|
|
|
This file was last updated by tav on July 08, 2011 @ 05:17
|