list.go (4407B)
1 // GoToSocial 2 // Copyright (C) GoToSocial Authors admin@gotosocial.org 3 // SPDX-License-Identifier: AGPL-3.0-or-later 4 // 5 // This program is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Affero General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // This program is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Affero General Public License for more details. 14 // 15 // You should have received a copy of the GNU Affero General Public License 16 // along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18 package timelines 19 20 import ( 21 "errors" 22 "net/http" 23 24 "github.com/gin-gonic/gin" 25 apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util" 26 "github.com/superseriousbusiness/gotosocial/internal/gtserror" 27 "github.com/superseriousbusiness/gotosocial/internal/oauth" 28 ) 29 30 // ListTimelineGETHandler swagger:operation GET /api/v1/timelines/list/{id} listTimeline 31 // 32 // See statuses/posts from the given list timeline. 33 // 34 // The statuses will be returned in descending chronological order (newest first), with sequential IDs (bigger = newer). 35 // 36 // The returned Link header can be used to generate the previous and next queries when scrolling up or down a timeline. 37 // 38 // Example: 39 // 40 // ``` 41 // <https://example.org/api/v1/timelines/list/01H0W619198FX7J54NF7EH1NG2?limit=20&max_id=01FC3GSQ8A3MMJ43BPZSGEG29M>; rel="next", <https://example.org/api/v1/timelines/list/01H0W619198FX7J54NF7EH1NG2?limit=20&min_id=01FC3KJW2GYXSDDRA6RWNDM46M>; rel="prev" 42 // ```` 43 // 44 // --- 45 // tags: 46 // - timelines 47 // 48 // produces: 49 // - application/json 50 // 51 // parameters: 52 // - 53 // name: id 54 // type: string 55 // description: ID of the list 56 // in: path 57 // required: true 58 // - 59 // name: max_id 60 // type: string 61 // description: >- 62 // Return only statuses *OLDER* than the given max status ID. 63 // The status with the specified ID will not be included in the response. 64 // in: query 65 // required: false 66 // - 67 // name: since_id 68 // type: string 69 // description: >- 70 // Return only statuses *NEWER* than the given since status ID. 71 // The status with the specified ID will not be included in the response. 72 // in: query 73 // - 74 // name: min_id 75 // type: string 76 // description: >- 77 // Return only statuses *NEWER* than the given since status ID. 78 // The status with the specified ID will not be included in the response. 79 // in: query 80 // required: false 81 // - 82 // name: limit 83 // type: integer 84 // description: Number of statuses to return. 85 // default: 20 86 // in: query 87 // required: false 88 // 89 // security: 90 // - OAuth2 Bearer: 91 // - read:lists 92 // 93 // responses: 94 // '200': 95 // name: statuses 96 // description: Array of statuses. 97 // schema: 98 // type: array 99 // items: 100 // "$ref": "#/definitions/status" 101 // headers: 102 // Link: 103 // type: string 104 // description: Links to the next and previous queries. 105 // '401': 106 // description: unauthorized 107 // '400': 108 // description: bad request 109 func (m *Module) ListTimelineGETHandler(c *gin.Context) { 110 authed, err := oauth.Authed(c, true, true, true, true) 111 if err != nil { 112 apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGetV1) 113 return 114 } 115 116 if _, err := apiutil.NegotiateAccept(c, apiutil.JSONAcceptHeaders...); err != nil { 117 apiutil.ErrorHandler(c, gtserror.NewErrorNotAcceptable(err, err.Error()), m.processor.InstanceGetV1) 118 return 119 } 120 121 targetListID := c.Param(IDKey) 122 if targetListID == "" { 123 err := errors.New("no list id specified") 124 apiutil.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGetV1) 125 return 126 } 127 128 limit, errWithCode := apiutil.ParseLimit(c.Query(apiutil.LimitKey), 20, 40, 1) 129 if errWithCode != nil { 130 apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1) 131 return 132 } 133 134 resp, errWithCode := m.processor.Timeline().ListTimelineGet( 135 c.Request.Context(), 136 authed, 137 targetListID, 138 c.Query(MaxIDKey), 139 c.Query(SinceIDKey), 140 c.Query(MinIDKey), 141 limit, 142 ) 143 if errWithCode != nil { 144 apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1) 145 return 146 } 147 148 if resp.LinkHeader != "" { 149 c.Header("Link", resp.LinkHeader) 150 } 151 c.JSON(http.StatusOK, resp.Items) 152 }