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
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))
|
|
}
|
|
|