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, cc, bcc 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	t.RawSetString("cc", lua.LString(cc))
109	t.RawSetString("bcc", lua.LString(bcc))
110
111	for _, fn := range callbacks {
112		if err := L.CallByParam(lua.P{
113			Fn:      fn,
114			NRet:    0,
115			Protect: true,
116		}, t); err != nil {
117			log.Printf("plugin hook %q error: %v", event, err)
118		}
119	}
120}
121
122// CallKeyBinding invokes a plugin key binding callback with the given arguments.
123func (m *Manager) CallKeyBinding(binding KeyBinding, args ...lua.LValue) {
124	if err := m.state.CallByParam(lua.P{
125		Fn:      binding.Fn,
126		NRet:    0,
127		Protect: true,
128	}, args...); err != nil {
129		log.Printf("plugin keybinding %q error: %v", binding.Key, err)
130	}
131}
132
133// EmailToTable converts email fields into a Lua table.
134func (m *Manager) EmailToTable(uid uint32, from string, to []string, subject string, date time.Time, isRead bool, accountID string, folder string) *lua.LTable {
135	L := m.state
136
137	t := L.NewTable()
138	t.RawSetString("uid", lua.LNumber(uid))
139	t.RawSetString("from", lua.LString(from))
140	t.RawSetString("subject", lua.LString(subject))
141	t.RawSetString("date", lua.LString(date.Format(time.RFC3339)))
142	t.RawSetString("is_read", lua.LBool(isRead))
143	t.RawSetString("account_id", lua.LString(accountID))
144	t.RawSetString("folder", lua.LString(folder))
145
146	toTable := L.NewTable()
147	for i, addr := range to {
148		toTable.RawSetInt(i+1, lua.LString(addr))
149	}
150	t.RawSetString("to", toTable)
151
152	return t
153}