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}