diff options
author | 2024-07-31 16:03:34 +0200 | |
---|---|---|
committer | 2024-07-31 15:03:34 +0100 | |
commit | 38f041cea1ba0cd3492f351353a29aa5b73e2731 (patch) | |
tree | bdd055d5cf7d9c06523c694cb4abe86d220960d0 /internal/api/util | |
parent | [feature] Object store custom URL (S3) (#3046) (diff) | |
download | gotosocial-38f041cea1ba0cd3492f351353a29aa5b73e2731.tar.xz |
[feature] Allow users to export data via the settings panel (#3140)
* [feature] Allow users to export data via the settings panel
* rename/move some stuff
Diffstat (limited to 'internal/api/util')
-rw-r--r-- | internal/api/util/mime.go | 1 | ||||
-rw-r--r-- | internal/api/util/negotiate.go | 6 | ||||
-rw-r--r-- | internal/api/util/response.go | 42 |
3 files changed, 49 insertions, 0 deletions
diff --git a/internal/api/util/mime.go b/internal/api/util/mime.go index 8dcbfc28c..4d8946e5d 100644 --- a/internal/api/util/mime.go +++ b/internal/api/util/mime.go @@ -35,6 +35,7 @@ const ( TextXML = `text/xml` TextHTML = `text/html` TextCSS = `text/css` + TextCSV = `text/csv` ) // JSONContentType returns whether is application/json(;charset=utf-8)? content-type. diff --git a/internal/api/util/negotiate.go b/internal/api/util/negotiate.go index 5b4f54bc6..4910b7aef 100644 --- a/internal/api/util/negotiate.go +++ b/internal/api/util/negotiate.go @@ -88,6 +88,12 @@ var HostMetaHeaders = []string{ AppXML, } +// CSVHeaders just contains the text/csv +// MIME type, used for import/export. +var CSVHeaders = []string{ + TextCSV, +} + // NegotiateAccept takes the *gin.Context from an incoming request, and a // slice of Offers, and performs content negotiation for the given request // with the given content-type offers. It will return a string representation diff --git a/internal/api/util/response.go b/internal/api/util/response.go index afdc578aa..01f15ccfb 100644 --- a/internal/api/util/response.go +++ b/internal/api/util/response.go @@ -18,6 +18,7 @@ package util import ( + "encoding/csv" "encoding/json" "encoding/xml" "io" @@ -213,6 +214,47 @@ func EncodeXMLResponse( putBuf(buf) } +// EncodeCSVResponse encodes 'records' as CSV HTTP response +// to ResponseWriter with given status code, using CSV content-type. +func EncodeCSVResponse( + rw http.ResponseWriter, + r *http.Request, + statusCode int, + records [][]string, +) { + // Acquire buffer. + buf := getBuf() + + // Wrap buffer in CSV writer. + csvWriter := csv.NewWriter(buf) + + // Write all the records to the buffer. + if err := csvWriter.WriteAll(records); err == nil { + // Respond with the now-known + // size byte slice within buf. + WriteResponseBytes(rw, r, + statusCode, + TextCSV, + buf.B, + ) + } else { + // This will always be an csv error, we + // can't really add any more useful context. + log.Error(r.Context(), err) + + // Any error returned here is unrecoverable, + // set Internal Server Error JSON response. + WriteResponseBytes(rw, r, + http.StatusInternalServerError, + AppJSON, + StatusInternalServerErrorJSON, + ) + } + + // Release. + putBuf(buf) +} + // writeResponseUnknownLength handles reading data of unknown legnth // efficiently into memory, and passing on to WriteResponseBytes(). func writeResponseUnknownLength( |