mirror of
https://github.com/axllent/mailpit.git
synced 2025-02-13 13:58:48 +02:00
API: Provide structs of API v1 responses for use in client code
See #21
This commit is contained in:
parent
ec95e58e13
commit
43bd2a18ea
@ -13,17 +13,8 @@ import (
|
|||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MessagesResult struct
|
// GetMessages returns a paginated list of messages as JSON
|
||||||
type MessagesResult struct {
|
func GetMessages(w http.ResponseWriter, r *http.Request) {
|
||||||
Total int `json:"total"`
|
|
||||||
Unread int `json:"unread"`
|
|
||||||
Count int `json:"count"`
|
|
||||||
Start int `json:"start"`
|
|
||||||
Messages []storage.Summary `json:"messages"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Messages returns a paginated list of messages as JSON
|
|
||||||
func Messages(w http.ResponseWriter, r *http.Request) {
|
|
||||||
start, limit := getStartLimit(r)
|
start, limit := getStartLimit(r)
|
||||||
|
|
||||||
messages, err := storage.List(start, limit)
|
messages, err := storage.List(start, limit)
|
||||||
@ -34,7 +25,7 @@ func Messages(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
stats := storage.StatsGet()
|
stats := storage.StatsGet()
|
||||||
|
|
||||||
var res MessagesResult
|
var res MessagesSummary
|
||||||
|
|
||||||
res.Start = start
|
res.Start = start
|
||||||
res.Messages = messages
|
res.Messages = messages
|
||||||
@ -65,7 +56,7 @@ func Search(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
stats := storage.StatsGet()
|
stats := storage.StatsGet()
|
||||||
|
|
||||||
var res MessagesResult
|
var res MessagesSummary
|
||||||
|
|
||||||
res.Start = 0
|
res.Start = 0
|
||||||
res.Messages = messages
|
res.Messages = messages
|
||||||
@ -78,8 +69,8 @@ func Search(w http.ResponseWriter, r *http.Request) {
|
|||||||
_, _ = w.Write(bytes)
|
_, _ = w.Write(bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Message (method: GET) returns the *data.Message as JSON
|
// GetMessage (method: GET) returns the *data.Message as JSON
|
||||||
func Message(w http.ResponseWriter, r *http.Request) {
|
func GetMessage(w http.ResponseWriter, r *http.Request) {
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
|
|
||||||
id := vars["id"]
|
id := vars["id"]
|
||||||
|
24
server/apiv1/structs.go
Normal file
24
server/apiv1/structs.go
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package apiv1
|
||||||
|
|
||||||
|
import "github.com/axllent/mailpit/storage"
|
||||||
|
|
||||||
|
// The following structs & aliases are provided for easy import
|
||||||
|
// and understanding of the JSON structure.
|
||||||
|
|
||||||
|
// MessageSummary - summary of a single message
|
||||||
|
type MessageSummary = storage.MessageSummary
|
||||||
|
|
||||||
|
// MessagesSummary - summary of a list of messages
|
||||||
|
type MessagesSummary struct {
|
||||||
|
Total int `json:"total"`
|
||||||
|
Unread int `json:"unread"`
|
||||||
|
Count int `json:"count"`
|
||||||
|
Start int `json:"start"`
|
||||||
|
Messages []MessageSummary `json:"messages"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Message data
|
||||||
|
type Message = storage.Message
|
||||||
|
|
||||||
|
// Attachment summary
|
||||||
|
type Attachment = storage.Attachment
|
@ -57,7 +57,7 @@ func defaultRoutes() *mux.Router {
|
|||||||
r := mux.NewRouter()
|
r := mux.NewRouter()
|
||||||
|
|
||||||
// API V1
|
// API V1
|
||||||
r.HandleFunc("/api/v1/messages", middleWareFunc(apiv1.Messages)).Methods("GET")
|
r.HandleFunc("/api/v1/messages", middleWareFunc(apiv1.GetMessages)).Methods("GET")
|
||||||
r.HandleFunc("/api/v1/messages", middleWareFunc(apiv1.SetReadStatus)).Methods("PUT")
|
r.HandleFunc("/api/v1/messages", middleWareFunc(apiv1.SetReadStatus)).Methods("PUT")
|
||||||
r.HandleFunc("/api/v1/messages", middleWareFunc(apiv1.DeleteMessages)).Methods("DELETE")
|
r.HandleFunc("/api/v1/messages", middleWareFunc(apiv1.DeleteMessages)).Methods("DELETE")
|
||||||
r.HandleFunc("/api/v1/search", middleWareFunc(apiv1.Search)).Methods("GET")
|
r.HandleFunc("/api/v1/search", middleWareFunc(apiv1.Search)).Methods("GET")
|
||||||
@ -65,7 +65,7 @@ func defaultRoutes() *mux.Router {
|
|||||||
r.HandleFunc("/api/v1/message/{id}/part/{partID}/thumb", middleWareFunc(apiv1.Thumbnail)).Methods("GET")
|
r.HandleFunc("/api/v1/message/{id}/part/{partID}/thumb", middleWareFunc(apiv1.Thumbnail)).Methods("GET")
|
||||||
r.HandleFunc("/api/v1/message/{id}/raw", middleWareFunc(apiv1.DownloadRaw)).Methods("GET")
|
r.HandleFunc("/api/v1/message/{id}/raw", middleWareFunc(apiv1.DownloadRaw)).Methods("GET")
|
||||||
r.HandleFunc("/api/v1/message/{id}/headers", middleWareFunc(apiv1.Headers)).Methods("GET")
|
r.HandleFunc("/api/v1/message/{id}/headers", middleWareFunc(apiv1.Headers)).Methods("GET")
|
||||||
r.HandleFunc("/api/v1/message/{id}", middleWareFunc(apiv1.Message)).Methods("GET")
|
r.HandleFunc("/api/v1/message/{id}", middleWareFunc(apiv1.GetMessage)).Methods("GET")
|
||||||
r.HandleFunc("/api/v1/info", middleWareFunc(apiv1.AppInfo)).Methods("GET")
|
r.HandleFunc("/api/v1/info", middleWareFunc(apiv1.AppInfo)).Methods("GET")
|
||||||
|
|
||||||
return r
|
return r
|
||||||
|
@ -160,7 +160,7 @@ func setup() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func assertStatsEqual(t *testing.T, uri string, unread, total int) {
|
func assertStatsEqual(t *testing.T, uri string, unread, total int) {
|
||||||
m := apiv1.MessagesResult{}
|
m := apiv1.MessagesSummary{}
|
||||||
|
|
||||||
data, err := clientGet(uri)
|
data, err := clientGet(uri)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -179,7 +179,7 @@ func assertStatsEqual(t *testing.T, uri string, unread, total int) {
|
|||||||
|
|
||||||
func assertSearchEqual(t *testing.T, uri, query string, count int) {
|
func assertSearchEqual(t *testing.T, uri, query string, count int) {
|
||||||
t.Logf("Test search: %s", query)
|
t.Logf("Test search: %s", query)
|
||||||
m := apiv1.MessagesResult{}
|
m := apiv1.MessagesSummary{}
|
||||||
|
|
||||||
limit := fmt.Sprintf("%d", count)
|
limit := fmt.Sprintf("%d", count)
|
||||||
|
|
||||||
@ -226,8 +226,8 @@ func insertEmailData(t *testing.T) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetchMessages(url string) (apiv1.MessagesResult, error) {
|
func fetchMessages(url string) (apiv1.MessagesSummary, error) {
|
||||||
m := apiv1.MessagesResult{}
|
m := apiv1.MessagesSummary{}
|
||||||
|
|
||||||
data, err := clientGet(url)
|
data, err := clientGet(url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -230,8 +230,7 @@ func Store(body []byte) (string, error) {
|
|||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
// return summary
|
c := &MessageSummary{}
|
||||||
c := &Summary{}
|
|
||||||
if err := json.Unmarshal(b, c); err != nil {
|
if err := json.Unmarshal(b, c); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@ -247,8 +246,8 @@ func Store(body []byte) (string, error) {
|
|||||||
|
|
||||||
// List returns a subset of messages from the mailbox,
|
// List returns a subset of messages from the mailbox,
|
||||||
// sorted latest to oldest
|
// sorted latest to oldest
|
||||||
func List(start, limit int) ([]Summary, error) {
|
func List(start, limit int) ([]MessageSummary, error) {
|
||||||
results := []Summary{}
|
results := []MessageSummary{}
|
||||||
|
|
||||||
q := sqlf.From("mailbox").
|
q := sqlf.From("mailbox").
|
||||||
Select(`ID, Data, Read`).
|
Select(`ID, Data, Read`).
|
||||||
@ -260,7 +259,7 @@ func List(start, limit int) ([]Summary, error) {
|
|||||||
var id string
|
var id string
|
||||||
var summary string
|
var summary string
|
||||||
var read int
|
var read int
|
||||||
em := Summary{}
|
em := MessageSummary{}
|
||||||
|
|
||||||
if err := row.Scan(&id, &summary, &read); err != nil {
|
if err := row.Scan(&id, &summary, &read); err != nil {
|
||||||
logger.Log().Error(err)
|
logger.Log().Error(err)
|
||||||
@ -291,8 +290,8 @@ func List(start, limit int) ([]Summary, error) {
|
|||||||
// The search is broken up by segments (exact phrases can be quoted), and interprits specific terms such as:
|
// The search is broken up by segments (exact phrases can be quoted), and interprits specific terms such as:
|
||||||
// is:read, is:unread, has:attachment, to:<term>, from:<term> & subject:<term>
|
// is:read, is:unread, has:attachment, to:<term>, from:<term> & subject:<term>
|
||||||
// Negative searches also also included by prefixing the search term with a `-` or `!`
|
// Negative searches also also included by prefixing the search term with a `-` or `!`
|
||||||
func Search(search string, start, limit int) ([]Summary, error) {
|
func Search(search string, start, limit int) ([]MessageSummary, error) {
|
||||||
results := []Summary{}
|
results := []MessageSummary{}
|
||||||
tsStart := time.Now()
|
tsStart := time.Now()
|
||||||
|
|
||||||
s := strings.ToLower(search)
|
s := strings.ToLower(search)
|
||||||
@ -316,7 +315,7 @@ func Search(search string, start, limit int) ([]Summary, error) {
|
|||||||
var summary string
|
var summary string
|
||||||
var read int
|
var read int
|
||||||
var ignore string
|
var ignore string
|
||||||
em := Summary{}
|
em := MessageSummary{}
|
||||||
|
|
||||||
if err := row.Scan(&id, &summary, &read, &ignore, &ignore, &ignore, &ignore); err != nil {
|
if err := row.Scan(&id, &summary, &read, &ignore, &ignore, &ignore, &ignore); err != nil {
|
||||||
logger.Log().Error(err)
|
logger.Log().Error(err)
|
||||||
|
@ -33,8 +33,8 @@ type Attachment struct {
|
|||||||
Size int
|
Size int
|
||||||
}
|
}
|
||||||
|
|
||||||
// Summary struct for frontend messages
|
// MessageSummary struct for frontend messages
|
||||||
type Summary struct {
|
type MessageSummary struct {
|
||||||
ID string
|
ID string
|
||||||
Read bool
|
Read bool
|
||||||
From *mail.Address
|
From *mail.Address
|
||||||
|
Loading…
x
Reference in New Issue
Block a user