First version to show (raw) email bodies.
Made xwebmail work with new handlers package. Pulls important headers from the database and provides extremely basic folder view on webpage. Reverted layout customizations returning folder view to original wider width. JS App now handles all the rendering, index.html only contains placeholder with background to indicate loading.
This commit is contained in:
81
db/util.go
81
db/util.go
@@ -42,7 +42,7 @@ type Original struct {
|
||||
}
|
||||
|
||||
func (c *Conn) Originals(oCh chan<- Original, errc chan<- error, donec <-chan struct{}) {
|
||||
query := `
|
||||
const query = `
|
||||
SELECT
|
||||
uid,
|
||||
hash,
|
||||
@@ -224,7 +224,7 @@ VALUES
|
||||
return nil
|
||||
}
|
||||
|
||||
var MagicAllLabel = "[all]"
|
||||
const MagicAllLabel = "[all]"
|
||||
|
||||
type Paginator struct {
|
||||
Label string
|
||||
@@ -232,11 +232,84 @@ type Paginator struct {
|
||||
Count int
|
||||
}
|
||||
|
||||
type Address mail.Address
|
||||
|
||||
type MessageHeader struct {
|
||||
Hash string
|
||||
From *Address
|
||||
To []*Address
|
||||
Cc []*Address
|
||||
Subject string
|
||||
Date time.Time
|
||||
Seen bool
|
||||
// TODO
|
||||
Summary, ListId string
|
||||
}
|
||||
|
||||
// Index returns ranges of metadata for messages as defined by paginator.
|
||||
func (c *Conn) Index(p *Paginator) error {
|
||||
func (c *Conn) Index(p *Paginator) ([]*MessageHeader, error) {
|
||||
const query = `
|
||||
SELECT
|
||||
hash, name, value
|
||||
FROM
|
||||
search_header
|
||||
WHERE
|
||||
name IN ('Date', 'Subject', 'To', 'From', 'Cc')
|
||||
ORDER BY
|
||||
hash
|
||||
LIMIT
|
||||
100
|
||||
-- TODO add offset based on Paginator
|
||||
;
|
||||
`
|
||||
var res []*MessageHeader
|
||||
if p.Label == MagicAllLabel {
|
||||
// Paginate all messages.
|
||||
}
|
||||
|
||||
// Else, filter by label.
|
||||
return nil
|
||||
rows, err := c.Query(query)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
var mh *MessageHeader
|
||||
for rows.Next() {
|
||||
var hash, name, value string
|
||||
if err := rows.Scan(&hash, &name, &value); err != nil {
|
||||
return res, err
|
||||
}
|
||||
if mh == nil {
|
||||
// First Row
|
||||
mh = new(MessageHeader)
|
||||
mh.Hash = hash
|
||||
}
|
||||
|
||||
if hash != mh.Hash {
|
||||
res = append(res, mh)
|
||||
mh = new(MessageHeader)
|
||||
mh.Hash = hash
|
||||
}
|
||||
switch name {
|
||||
case "Date":
|
||||
t, err := time.Parse(time.RFC3339Nano, value)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
mh.Date = t
|
||||
case "Subject":
|
||||
mh.Subject = value
|
||||
case "To":
|
||||
mh.To = append(mh.To, &Address{Address: value})
|
||||
case "From":
|
||||
mh.From = &Address{Address: value}
|
||||
case "Cc":
|
||||
mh.Cc = append(mh.Cc, &Address{Address: value})
|
||||
}
|
||||
}
|
||||
// Intentionally don't handle the last MessageHeader, it is likely
|
||||
// incomplete if LIMIT in the query cuts off a message midstream.
|
||||
if err := rows.Err(); err != nil {
|
||||
return res, err
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user