public.go (4749B)
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 "net/http" 22 23 "github.com/gin-gonic/gin" 24 apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util" 25 "github.com/superseriousbusiness/gotosocial/internal/config" 26 "github.com/superseriousbusiness/gotosocial/internal/gtserror" 27 "github.com/superseriousbusiness/gotosocial/internal/oauth" 28 ) 29 30 // PublicTimelineGETHandler swagger:operation GET /api/v1/timelines/public publicTimeline 31 // 32 // See public statuses/posts that your instance is aware of. 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/public?limit=20&max_id=01FC3GSQ8A3MMJ43BPZSGEG29M>; rel="next", <https://example.org/api/v1/timelines/public?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: max_id 54 // type: string 55 // description: >- 56 // Return only statuses *OLDER* than the given max status ID. 57 // The status with the specified ID will not be included in the response. 58 // in: query 59 // required: false 60 // - 61 // name: since_id 62 // type: string 63 // description: >- 64 // Return only statuses *NEWER* than the given since status ID. 65 // The status with the specified ID will not be included in the response. 66 // in: query 67 // - 68 // name: min_id 69 // type: string 70 // description: >- 71 // Return only statuses *NEWER* than the given since status ID. 72 // The status with the specified ID will not be included in the response. 73 // in: query 74 // required: false 75 // - 76 // name: limit 77 // type: integer 78 // description: Number of statuses to return. 79 // default: 20 80 // in: query 81 // required: false 82 // - 83 // name: local 84 // type: boolean 85 // description: Show only statuses posted by local accounts. 86 // default: false 87 // in: query 88 // required: false 89 // 90 // security: 91 // - OAuth2 Bearer: 92 // - read:statuses 93 // 94 // responses: 95 // '200': 96 // name: statuses 97 // description: Array of statuses. 98 // schema: 99 // type: array 100 // items: 101 // "$ref": "#/definitions/status" 102 // headers: 103 // Link: 104 // type: string 105 // description: Links to the next and previous queries. 106 // '401': 107 // description: unauthorized 108 // '400': 109 // description: bad request 110 func (m *Module) PublicTimelineGETHandler(c *gin.Context) { 111 var authed *oauth.Auth 112 var err error 113 114 if config.GetInstanceExposePublicTimeline() { 115 // If the public timeline is allowed to be exposed, still check if we 116 // can extract various authentication properties, but don't require them. 117 authed, err = oauth.Authed(c, false, false, false, false) 118 } else { 119 authed, err = oauth.Authed(c, true, true, true, true) 120 } 121 122 if err != nil { 123 apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGetV1) 124 return 125 } 126 127 if _, err := apiutil.NegotiateAccept(c, apiutil.JSONAcceptHeaders...); err != nil { 128 apiutil.ErrorHandler(c, gtserror.NewErrorNotAcceptable(err, err.Error()), m.processor.InstanceGetV1) 129 return 130 } 131 132 limit, errWithCode := apiutil.ParseLimit(c.Query(apiutil.LimitKey), 20, 40, 1) 133 if errWithCode != nil { 134 apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1) 135 return 136 } 137 138 local, errWithCode := apiutil.ParseLocal(c.Query(apiutil.LocalKey), false) 139 if errWithCode != nil { 140 apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1) 141 return 142 } 143 144 resp, errWithCode := m.processor.Timeline().PublicTimelineGet( 145 c.Request.Context(), 146 authed, 147 c.Query(MaxIDKey), 148 c.Query(SinceIDKey), 149 c.Query(MinIDKey), 150 limit, 151 local, 152 ) 153 if errWithCode != nil { 154 apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1) 155 return 156 } 157 158 if resp.LinkHeader != "" { 159 c.Header("Link", resp.LinkHeader) 160 } 161 c.JSON(http.StatusOK, resp.Items) 162 }