aboutsummaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'plugins')
-rw-r--r--plugins/base/handlers.go24
-rw-r--r--plugins/base/imap.go51
-rw-r--r--plugins/base/plugin.go1
-rw-r--r--plugins/base/public/login.html2
-rw-r--r--plugins/base/public/mailbox.html5
5 files changed, 74 insertions, 9 deletions
diff --git a/plugins/base/handlers.go b/plugins/base/handlers.go
index d0ba9ba..133052c 100644
--- a/plugins/base/handlers.go
+++ b/plugins/base/handlers.go
@@ -23,6 +23,7 @@ type MailboxRenderData struct {
Mailboxes []*imap.MailboxInfo
Messages []imapMessage
PrevPage, NextPage int
+ Query string
}
func handleGetMailbox(ectx echo.Context) error {
@@ -41,6 +42,8 @@ func handleGetMailbox(ectx echo.Context) error {
}
}
+ query := ctx.FormValue("query")
+
var mailboxes []*imap.MailboxInfo
var msgs []imapMessage
var mbox *imap.MailboxStatus
@@ -49,7 +52,12 @@ func handleGetMailbox(ectx echo.Context) error {
if mailboxes, err = listMailboxes(c); err != nil {
return err
}
- if msgs, err = listMessages(c, mboxName, page); err != nil {
+ if query != "" {
+ msgs, err = searchMessages(c, mboxName, query)
+ } else {
+ msgs, err = listMessages(c, mboxName, page)
+ }
+ if err != nil {
return err
}
mbox = c.Mailbox()
@@ -60,11 +68,14 @@ func handleGetMailbox(ectx echo.Context) error {
}
prevPage, nextPage := -1, -1
- if page > 0 {
- prevPage = page - 1
- }
- if (page+1)*messagesPerPage < int(mbox.Messages) {
- nextPage = page + 1
+ if query == "" {
+ // TODO: paging for search
+ if page > 0 {
+ prevPage = page - 1
+ }
+ if (page+1)*messagesPerPage < int(mbox.Messages) {
+ nextPage = page + 1
+ }
}
return ctx.Render(http.StatusOK, "mailbox.html", &MailboxRenderData{
@@ -74,6 +85,7 @@ func handleGetMailbox(ectx echo.Context) error {
Messages: msgs,
PrevPage: prevPage,
NextPage: nextPage,
+ Query: query,
})
}
diff --git a/plugins/base/imap.go b/plugins/base/imap.go
index 93f3c4e..b1e36a6 100644
--- a/plugins/base/imap.go
+++ b/plugins/base/imap.go
@@ -189,7 +189,7 @@ func listMessages(conn *imapclient.Client, mboxName string, page int) ([]imapMes
return nil, nil
}
- seqSet := new(imap.SeqSet)
+ var seqSet imap.SeqSet
seqSet.AddRange(uint32(from), uint32(to))
fetch := []imap.FetchItem{imap.FetchEnvelope, imap.FetchUid, imap.FetchBodyStructure}
@@ -197,7 +197,7 @@ func listMessages(conn *imapclient.Client, mboxName string, page int) ([]imapMes
ch := make(chan *imap.Message, 10)
done := make(chan error, 1)
go func() {
- done <- conn.Fetch(seqSet, fetch, ch)
+ done <- conn.Fetch(&seqSet, fetch, ch)
}()
msgs := make([]imapMessage, 0, to-from)
@@ -218,6 +218,53 @@ func listMessages(conn *imapclient.Client, mboxName string, page int) ([]imapMes
return msgs, nil
}
+func searchMessages(conn *imapclient.Client, mboxName, query string) ([]imapMessage, error) {
+ if err := ensureMailboxSelected(conn, mboxName); err != nil {
+ return nil, err
+ }
+
+ criteria := imap.SearchCriteria{Text: []string{query}}
+ nums, err := conn.Search(&criteria)
+ if err != nil {
+ return nil, fmt.Errorf("UID SEARCH failed: %v", err)
+ }
+ if len(nums) == 0 {
+ return nil, nil
+ }
+
+ indexes := make(map[uint32]int)
+ for i, num := range nums {
+ indexes[num] = i
+ }
+
+ // TODO: paging
+ var seqSet imap.SeqSet
+ seqSet.AddNum(nums...)
+
+ fetch := []imap.FetchItem{imap.FetchEnvelope, imap.FetchUid, imap.FetchBodyStructure}
+
+ ch := make(chan *imap.Message, 10)
+ done := make(chan error, 1)
+ go func() {
+ done <- conn.Fetch(&seqSet, fetch, ch)
+ }()
+
+ msgs := make([]imapMessage, len(nums))
+ for msg := range ch {
+ i, ok := indexes[msg.SeqNum]
+ if !ok {
+ continue
+ }
+ msgs[i] = imapMessage{msg}
+ }
+
+ if err := <-done; err != nil {
+ return nil, fmt.Errorf("failed to fetch message list: %v", err)
+ }
+
+ return msgs, nil
+}
+
func getMessagePart(conn *imapclient.Client, mboxName string, uid uint32, partPath []int) (*imapMessage, *message.Entity, error) {
if err := ensureMailboxSelected(conn, mboxName); err != nil {
return nil, nil, err
diff --git a/plugins/base/plugin.go b/plugins/base/plugin.go
index 906730d..7c2aeaf 100644
--- a/plugins/base/plugin.go
+++ b/plugins/base/plugin.go
@@ -23,6 +23,7 @@ func init() {
})
p.GET("/mailbox/:mbox", handleGetMailbox)
+ p.POST("/mailbox/:mbox", handleGetMailbox)
p.GET("/message/:mbox/:uid", func(ectx echo.Context) error {
ctx := ectx.(*koushin.Context)
diff --git a/plugins/base/public/login.html b/plugins/base/public/login.html
index 8ce5f25..7378935 100644
--- a/plugins/base/public/login.html
+++ b/plugins/base/public/login.html
@@ -2,7 +2,7 @@
<h1>koushin</h1>
-<form method="post" action="/login">
+<form method="post" action="">
<label for="username">Username:</label>
<input type="text" name="username" id="username"/>
<br><br>
diff --git a/plugins/base/public/mailbox.html b/plugins/base/public/mailbox.html
index ddd1260..53cf697 100644
--- a/plugins/base/public/mailbox.html
+++ b/plugins/base/public/mailbox.html
@@ -8,6 +8,11 @@
<h2>{{.Mailbox.Name}}</h2>
+<form method="post" action="">
+ <input type="search" name="query" value="{{.Query}}">
+ <input type="submit" value="Search">
+</form>
+
<p>Mailboxes:</p>
<ul>
{{range .Mailboxes}}