3
0

Implements /search/threads

This commit is contained in:
Denis Arh
2019-04-27 19:31:45 +02:00
parent d96a6c8abc
commit 0c919d9146
6 changed files with 151 additions and 0 deletions

View File

@@ -858,6 +858,28 @@
}
]
}
},
{
"method": "GET",
"name": "threads",
"path": "/threads",
"title": "Search for threads",
"parameters": {
"get": [
{
"name": "channelID",
"type": "[]uint64",
"required": false,
"title": "Filter by channels"
},
{
"name": "limit",
"type": "uint",
"required": false,
"title": "Max number of messages"
}
]
}
}
]
},

View File

@@ -94,6 +94,28 @@
}
]
}
},
{
"Name": "threads",
"Method": "GET",
"Title": "Search for threads",
"Path": "/threads",
"Parameters": {
"get": [
{
"name": "channelID",
"required": false,
"title": "Filter by channels",
"type": "[]uint64"
},
{
"name": "limit",
"required": false,
"title": "Max number of messages",
"type": "uint"
}
]
}
}
]
}

View File

@@ -561,6 +561,7 @@ The following event types may be sent with a message event:
| Method | Endpoint | Purpose |
| ------ | -------- | ------- |
| `GET` | `/search/messages` | Search for messages |
| `GET` | `/search/threads` | Search for threads |
## Search for messages
@@ -587,6 +588,22 @@ The following event types may be sent with a message event:
| limit | uint | GET | Max number of messages | N/A | NO |
| query | string | GET | Search query | N/A | NO |
## Search for threads
#### Method
| URI | Protocol | Method | Authentication |
| --- | -------- | ------ | -------------- |
| `/search/threads` | HTTP/S | GET | Client ID, Session ID |
#### Request parameters
| Parameter | Type | Method | Description | Default | Required? |
| --------- | ---- | ------ | ----------- | ------- | --------- |
| channelID | []uint64 | GET | Filter by channels | N/A | NO |
| limit | uint | GET | Max number of messages | N/A | NO |
| query | string | GET | Search query | N/A | NO |
---

View File

@@ -29,11 +29,13 @@ import (
// Internal API interface
type SearchAPI interface {
Messages(context.Context, *request.SearchMessages) (interface{}, error)
Threads(context.Context, *request.SearchThreads) (interface{}, error)
}
// HTTP API interface
type Search struct {
Messages func(http.ResponseWriter, *http.Request)
Threads func(http.ResponseWriter, *http.Request)
}
func NewSearch(sh SearchAPI) *Search {
@@ -58,6 +60,26 @@ func NewSearch(sh SearchAPI) *Search {
return
}
},
Threads: func(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
params := request.NewSearchThreads()
if err := params.Fill(r); err != nil {
resputil.JSON(w, err)
return
}
if value, err := sh.Threads(r.Context(), params); err != nil {
resputil.JSON(w, err)
return
} else {
switch fn := value.(type) {
case func(http.ResponseWriter, *http.Request):
fn(w, r)
return
}
resputil.JSON(w, value)
return
}
},
}
}
@@ -65,5 +87,6 @@ func (sh *Search) MountRoutes(r chi.Router, middlewares ...func(http.Handler) ht
r.Group(func(r chi.Router) {
r.Use(middlewares...)
r.Get("/search/messages", sh.Messages)
r.Get("/search/threads", sh.Threads)
})
}

View File

@@ -133,3 +133,61 @@ func (sReq *SearchMessages) Fill(r *http.Request) (err error) {
}
var _ RequestFiller = NewSearchMessages()
// Search threads request parameters
type SearchThreads struct {
ChannelID []uint64 `json:",string"`
Limit uint
Query string
}
func NewSearchThreads() *SearchThreads {
return &SearchThreads{}
}
func (sReq *SearchThreads) Fill(r *http.Request) (err error) {
if strings.ToLower(r.Header.Get("content-type")) == "application/json" {
err = json.NewDecoder(r.Body).Decode(sReq)
switch {
case err == io.EOF:
err = nil
case err != nil:
return errors.Wrap(err, "error parsing http request body")
}
}
if err = r.ParseForm(); err != nil {
return err
}
get := map[string]string{}
post := map[string]string{}
urlQuery := r.URL.Query()
for name, param := range urlQuery {
get[name] = string(param[0])
}
postVars := r.Form
for name, param := range postVars {
post[name] = string(param[0])
}
if val, ok := urlQuery["channelID[]"]; ok {
sReq.ChannelID = parseUInt64A(val)
} else if val, ok = urlQuery["channelID"]; ok {
sReq.ChannelID = parseUInt64A(val)
}
if val, ok := get["limit"]; ok {
sReq.Limit = parseUint(val)
}
if val, ok := get["query"]; ok {
sReq.Query = val
}
return err
}
var _ RequestFiller = NewSearchThreads()

View File

@@ -45,6 +45,15 @@ func (ctrl *Search) Messages(ctx context.Context, r *request.SearchMessages) (in
}))
}
func (ctrl *Search) Threads(ctx context.Context, r *request.SearchThreads) (interface{}, error) {
return ctrl.wrapSet(ctx)(ctrl.svc.msg.With(ctx).FindThreads(&types.MessageFilter{
ChannelID: r.ChannelID,
Limit: r.Limit,
Query: r.Query,
}))
}
func (ctrl *Search) wrapSet(ctx context.Context) func(mm types.MessageSet, err error) (*outgoing.MessageSet, error) {
return func(mm types.MessageSet, err error) (*outgoing.MessageSet, error) {
if err != nil {