hooks.go

  1package plugin
  2
  3import (
  4	"log"
  5	"time"
  6
  7	lua "github.com/yuin/gopher-lua"
  8)
  9
 10// Hook event names.
 11const (
 12	HookStartup         = "startup"
 13	HookShutdown        = "shutdown"
 14	HookEmailReceived   = "email_received"
 15	HookEmailSendBefore = "email_send_before"
 16	HookEmailSendAfter  = "email_send_after"
 17	HookEmailViewed     = "email_viewed"
 18	HookFolderChanged   = "folder_changed"
 19	HookComposerUpdated = "composer_updated"
 20)
 21
 22// Status area names.
 23const (
 24	StatusInbox     = "inbox"
 25	StatusComposer  = "composer"
 26	StatusEmailView = "email_view"
 27)
 28
 29// registerHook adds a callback for the given event.
 30func (m *Manager) registerHook(event string, fn *lua.LFunction) {
 31	m.hooks[event] = append(m.hooks[event], fn)
 32}
 33
 34// CallHook invokes all callbacks registered for the given event.
 35func (m *Manager) CallHook(event string, args ...lua.LValue) {
 36	callbacks, ok := m.hooks[event]
 37	if !ok {
 38		return
 39	}
 40
 41	for _, fn := range callbacks {
 42		if err := m.state.CallByParam(lua.P{
 43			Fn:      fn,
 44			NRet:    0,
 45			Protect: true,
 46		}, args...); err != nil {
 47			log.Printf("plugin hook %q error: %v", event, err)
 48		}
 49	}
 50}
 51
 52// CallSendHook calls a hook with email send metadata.
 53func (m *Manager) CallSendHook(event string, to, cc, subject, accountID string) {
 54	callbacks, ok := m.hooks[event]
 55	if !ok {
 56		return
 57	}
 58
 59	L := m.state
 60	t := L.NewTable()
 61	t.RawSetString("to", lua.LString(to))
 62	t.RawSetString("cc", lua.LString(cc))
 63	t.RawSetString("subject", lua.LString(subject))
 64	t.RawSetString("account_id", lua.LString(accountID))
 65
 66	for _, fn := range callbacks {
 67		if err := L.CallByParam(lua.P{
 68			Fn:      fn,
 69			NRet:    0,
 70			Protect: true,
 71		}, t); err != nil {
 72			log.Printf("plugin hook %q error: %v", event, err)
 73		}
 74	}
 75}
 76
 77// CallFolderHook calls a hook with a folder name.
 78func (m *Manager) CallFolderHook(event string, folderName string) {
 79	callbacks, ok := m.hooks[event]
 80	if !ok {
 81		return
 82	}
 83
 84	for _, fn := range callbacks {
 85		if err := m.state.CallByParam(lua.P{
 86			Fn:      fn,
 87			NRet:    0,
 88			Protect: true,
 89		}, lua.LString(folderName)); err != nil {
 90			log.Printf("plugin hook %q error: %v", event, err)
 91		}
 92	}
 93}
 94
 95// CallComposerHook calls a hook with composer state info.
 96func (m *Manager) CallComposerHook(event string, body, subject, to string) {
 97	callbacks, ok := m.hooks[event]
 98	if !ok {
 99		return
100	}
101
102	L := m.state
103	t := L.NewTable()
104	t.RawSetString("body_len", lua.LNumber(len(body)))
105	t.RawSetString("body", lua.LString(body))
106	t.RawSetString("subject", lua.LString(subject))
107	t.RawSetString("to", lua.LString(to))
108
109	for _, fn := range callbacks {
110		if err := L.CallByParam(lua.P{
111			Fn:      fn,
112			NRet:    0,
113			Protect: true,
114		}, t); err != nil {
115			log.Printf("plugin hook %q error: %v", event, err)
116		}
117	}
118}
119
120// EmailToTable converts email fields into a Lua table.
121func (m *Manager) EmailToTable(uid uint32, from string, to []string, subject string, date time.Time, isRead bool, accountID string, folder string) *lua.LTable {
122	L := m.state
123
124	t := L.NewTable()
125	t.RawSetString("uid", lua.LNumber(uid))
126	t.RawSetString("from", lua.LString(from))
127	t.RawSetString("subject", lua.LString(subject))
128	t.RawSetString("date", lua.LString(date.Format(time.RFC3339)))
129	t.RawSetString("is_read", lua.LBool(isRead))
130	t.RawSetString("account_id", lua.LString(accountID))
131	t.RawSetString("folder", lua.LString(folder))
132
133	toTable := L.NewTable()
134	for i, addr := range to {
135		toTable.RawSetInt(i+1, lua.LString(addr))
136	}
137	t.RawSetString("to", toTable)
138
139	return t
140}