Add Server.Reload
This only reloads templates for now. In the future it'll also reload Lua plugins.
This commit is contained in:
parent
f6758264b2
commit
97b314b6e7
3 changed files with 38 additions and 18 deletions
|
@ -239,7 +239,7 @@ func searchMessages(conn *imapclient.Client, mboxName, query string, page int) (
|
||||||
}
|
}
|
||||||
total = len(nums)
|
total = len(nums)
|
||||||
|
|
||||||
from := page*messagesPerPage
|
from := page * messagesPerPage
|
||||||
to := from + messagesPerPage
|
to := from + messagesPerPage
|
||||||
if from >= len(nums) {
|
if from >= len(nums) {
|
||||||
return nil, total, nil
|
return nil, total, nil
|
||||||
|
|
10
server.go
10
server.go
|
@ -14,6 +14,7 @@ const cookieName = "koushin_session"
|
||||||
|
|
||||||
// Server holds all the koushin server state.
|
// Server holds all the koushin server state.
|
||||||
type Server struct {
|
type Server struct {
|
||||||
|
renderer *renderer
|
||||||
Sessions *SessionManager
|
Sessions *SessionManager
|
||||||
Plugins []Plugin
|
Plugins []Plugin
|
||||||
|
|
||||||
|
@ -72,6 +73,10 @@ func (s *Server) parseSMTPURL(smtpURL string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Server) Reload() error {
|
||||||
|
return s.renderer.reload(s.Plugins)
|
||||||
|
}
|
||||||
|
|
||||||
func newServer(imapURL, smtpURL string) (*Server, error) {
|
func newServer(imapURL, smtpURL string) (*Server, error) {
|
||||||
s := &Server{}
|
s := &Server{}
|
||||||
|
|
||||||
|
@ -150,8 +155,9 @@ func New(e *echo.Echo, options *Options) (*Server, error) {
|
||||||
}
|
}
|
||||||
s.Plugins = append(s.Plugins, luaPlugins...)
|
s.Plugins = append(s.Plugins, luaPlugins...)
|
||||||
|
|
||||||
e.Renderer, err = loadTemplates(e.Logger, options.Theme, s.Plugins)
|
s.renderer = newRenderer(e.Logger, options.Theme)
|
||||||
if err != nil {
|
e.Renderer = s.renderer
|
||||||
|
if err := s.renderer.reload(s.Plugins); err != nil {
|
||||||
return nil, fmt.Errorf("failed to load templates: %v", err)
|
return nil, fmt.Errorf("failed to load templates: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
44
template.go
44
template.go
|
@ -6,6 +6,7 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
)
|
)
|
||||||
|
@ -77,12 +78,18 @@ func NewBaseRenderData(ctx *Context) *BaseRenderData {
|
||||||
}
|
}
|
||||||
|
|
||||||
type renderer struct {
|
type renderer struct {
|
||||||
base *template.Template
|
logger echo.Logger
|
||||||
themes map[string]*template.Template
|
|
||||||
defaultTheme string
|
defaultTheme string
|
||||||
|
|
||||||
|
mutex sync.RWMutex
|
||||||
|
base *template.Template
|
||||||
|
themes map[string]*template.Template
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *renderer) Render(w io.Writer, name string, data interface{}, ectx echo.Context) error {
|
func (r *renderer) Render(w io.Writer, name string, data interface{}, ectx echo.Context) error {
|
||||||
|
r.mutex.RLock()
|
||||||
|
defer r.mutex.RUnlock()
|
||||||
|
|
||||||
// ectx is the raw *echo.context, not our own *Context
|
// ectx is the raw *echo.context, not our own *Context
|
||||||
ctx := ectx.Get("context").(*Context)
|
ctx := ectx.Get("context").(*Context)
|
||||||
|
|
||||||
|
@ -114,12 +121,12 @@ func loadTheme(name string, base *template.Template) (*template.Template, error)
|
||||||
return theme, nil
|
return theme, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadTemplates(logger echo.Logger, defaultTheme string, plugins []Plugin) (*renderer, error) {
|
func (r *renderer) reload(plugins []Plugin) error {
|
||||||
base := template.New("")
|
base := template.New("")
|
||||||
|
|
||||||
for _, p := range plugins {
|
for _, p := range plugins {
|
||||||
if err := p.LoadTemplate(base); err != nil {
|
if err := p.LoadTemplate(base); err != nil {
|
||||||
return nil, fmt.Errorf("failed to load template for plugin '%v': %v", p.Name(), err)
|
return fmt.Errorf("failed to load template for plugin '%v': %v", p.Name(), err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,7 +134,7 @@ func loadTemplates(logger echo.Logger, defaultTheme string, plugins []Plugin) (*
|
||||||
|
|
||||||
files, err := ioutil.ReadDir(themesDir)
|
files, err := ioutil.ReadDir(themesDir)
|
||||||
if err != nil && !os.IsNotExist(err) {
|
if err != nil && !os.IsNotExist(err) {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, fi := range files {
|
for _, fi := range files {
|
||||||
|
@ -135,22 +142,29 @@ func loadTemplates(logger echo.Logger, defaultTheme string, plugins []Plugin) (*
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Printf("Loading theme '%v'", fi.Name())
|
r.logger.Printf("Loading theme '%v'", fi.Name())
|
||||||
var err error
|
var err error
|
||||||
if themes[fi.Name()], err = loadTheme(fi.Name(), base); err != nil {
|
if themes[fi.Name()], err = loadTheme(fi.Name(), base); err != nil {
|
||||||
return nil, fmt.Errorf("failed to load theme '%v': %v", fi.Name(), err)
|
return fmt.Errorf("failed to load theme '%v': %v", fi.Name(), err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if defaultTheme != "" {
|
if r.defaultTheme != "" {
|
||||||
if _, ok := themes[defaultTheme]; !ok {
|
if _, ok := themes[r.defaultTheme]; !ok {
|
||||||
return nil, fmt.Errorf("failed to find default theme '%v'", defaultTheme)
|
return fmt.Errorf("failed to find default theme '%v'", r.defaultTheme)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &renderer{
|
r.mutex.Lock()
|
||||||
base: base,
|
r.base = base
|
||||||
themes: themes,
|
r.themes = themes
|
||||||
defaultTheme: defaultTheme,
|
r.mutex.Unlock()
|
||||||
}, nil
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func newRenderer(logger echo.Logger, defaultTheme string) *renderer {
|
||||||
|
return &renderer{
|
||||||
|
logger: logger,
|
||||||
|
defaultTheme: defaultTheme,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue