You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

149 lines
3.5 KiB

package apiServer
import (
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"path"
"strconv"
"dread.land/deepgram-demo/internal/audio"
"dread.land/deepgram-demo/internal/metadata"
"github.com/go-chi/chi/v5"
)
type ApiServer struct {
Audio *audio.AudioServer
Metadata *metadata.MetadataServer
}
func (apiServer *ApiServer) chunkHandler(w http.ResponseWriter, r *http.Request) {
// chunkIndex starts at 0
chunkIndexString := r.URL.Query().Get("chunkindex")
chunkSizeString := r.URL.Query().Get("chunksize")
chunkIndex := 0
var err error
if chunkIndexString != "" {
chunkIndex, err = strconv.Atoi(chunkIndexString)
}
if err != nil {
http.Error(w, fmt.Sprint(err), http.StatusBadRequest)
}
chunkSize := 0
if chunkSizeString != "" {
chunkSize, err = strconv.Atoi(chunkSizeString)
}
if err != nil {
http.Error(w, fmt.Sprint(err), http.StatusBadRequest)
}
filename := path.Base(path.Dir(r.URL.Path))
contents, err := apiServer.Audio.Download(filename)
if err != nil {
http.Error(w, fmt.Sprint(err), http.StatusNotFound)
return
}
startIndex := chunkIndex * chunkSize
if startIndex > len(contents) {
http.Error(w, "index out of bounds", http.StatusBadRequest)
}
endIndex := startIndex + chunkSize
if endIndex > len(contents) {
endIndex = len(contents)
}
w.Write(contents[startIndex:endIndex])
}
func (apiServer *ApiServer) filesHandler(w http.ResponseWriter, r *http.Request) {
filename := path.Base(r.URL.Path)
switch r.Method {
case "GET":
// get file
contents, err := apiServer.Audio.Download(filename)
if err != nil {
http.Error(w, fmt.Sprint(err), http.StatusNotFound)
return
}
w.Write(contents)
return
case "POST": // save file
contents, err := io.ReadAll(r.Body)
if err != nil {
http.Error(w, fmt.Sprint(err), http.StatusBadRequest)
}
err = apiServer.Audio.Upload(filename, contents)
if err != nil {
http.Error(w, fmt.Sprint(err), http.StatusConflict)
}
return
default:
// error unsupported
http.Error(w, "unsupported", http.StatusMethodNotAllowed)
return
}
}
func (apiServer *ApiServer) metadataHandler(w http.ResponseWriter, r *http.Request) {
filename := path.Base(path.Dir(r.URL.Path))
switch r.Method {
case "GET":
// get metadata
meta, err := apiServer.Metadata.Info(filename)
if err != nil {
http.Error(w, fmt.Sprint(err), http.StatusNotFound)
return
}
response, err := json.Marshal(meta)
if err != nil {
http.Error(w, fmt.Sprint(err), http.StatusInternalServerError)
return
}
fmt.Fprint(w, string(response))
return
default:
http.Error(w, "unsupported", http.StatusMethodNotAllowed)
return
}
}
func (apiServer *ApiServer) listHandler(w http.ResponseWriter, r *http.Request) {
maxdurationString := r.URL.Query().Get("maxduration")
maxduration := 0
var err error
if maxdurationString != "" {
maxduration, err = strconv.Atoi(maxdurationString)
}
if err != nil {
http.Error(w, fmt.Sprint(err), http.StatusBadRequest)
return // error Bad Request
}
list := apiServer.Metadata.List(maxduration)
response, err := json.Marshal(list)
if err != nil {
http.Error(w, fmt.Sprint(err), http.StatusInternalServerError)
return
}
fmt.Fprint(w, string(response))
}
func (apiServer *ApiServer) Serve() {
r := chi.NewRouter()
r.Get("/files", apiServer.listHandler)
r.Get("/files/{filename}", apiServer.filesHandler)
r.Post("/files/{filename}", apiServer.filesHandler)
r.Get("/files/{filename}/metadata", apiServer.metadataHandler)
// chunkNumber
r.Get("/files/{filename}/chunk", apiServer.chunkHandler)
log.Fatal(http.ListenAndServe(":3030", r))
}