Add api endpoint to directly convert a URL to media
This commit is contained in:
parent
1973fd685d
commit
cc0d07bc90
4 changed files with 42 additions and 17 deletions
|
|
@ -21,6 +21,7 @@ func main() {
|
||||||
router.Route("/", func(r chi.Router) {
|
router.Route("/", func(r chi.Router) {
|
||||||
router.Get("/", media.Index)
|
router.Get("/", media.Index)
|
||||||
router.Get("/fetch", media.FetchMedia)
|
router.Get("/fetch", media.FetchMedia)
|
||||||
|
router.Get("/api/download", media.FetchMediaApi)
|
||||||
router.Get("/download", media.ServeMedia)
|
router.Get("/download", media.ServeMedia)
|
||||||
})
|
})
|
||||||
fileServer(router, "/static", "static/")
|
fileServer(router, "/static", "static/")
|
||||||
|
|
|
||||||
|
|
@ -52,10 +52,37 @@ func Index(w http.ResponseWriter, _ *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func FetchMedia(w http.ResponseWriter, r *http.Request) {
|
func FetchMedia(w http.ResponseWriter, r *http.Request) {
|
||||||
|
response, err := getMediaResults(r)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := fetchResponseTmpl.Execute(w, response); err != nil {
|
||||||
|
log.Error().Msgf("Error rendering template: %v", err)
|
||||||
|
http.Error(w, "Internal error", http.StatusInternalServerError)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func FetchMediaApi(w http.ResponseWriter, r *http.Request) {
|
||||||
|
response, err := getMediaResults(r)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(response.Medias) == 0 {
|
||||||
|
http.Error(w, "Media not found", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// just take the first one
|
||||||
|
streamFileToClientById(w, response.Medias[0].Id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getMediaResults(r *http.Request) (MediaResults, error) {
|
||||||
url := r.URL.Query().Get("url")
|
url := r.URL.Query().Get("url")
|
||||||
if url == "" {
|
if url == "" {
|
||||||
http.Error(w, "Missing URL", http.StatusBadRequest)
|
return MediaResults{}, errors.New("Missing URL")
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: This system is for a simple use case, meant to run at home. This is not a great design for a robust system.
|
// NOTE: This system is for a simple use case, meant to run at home. This is not a great design for a robust system.
|
||||||
|
|
@ -67,30 +94,23 @@ func FetchMedia(w http.ResponseWriter, r *http.Request) {
|
||||||
medias, err := getAllFilesForId(id)
|
medias, err := getAllFilesForId(id)
|
||||||
if len(medias) == 0 {
|
if len(medias) == 0 {
|
||||||
// We don't, so go fetch it
|
// We don't, so go fetch it
|
||||||
id, err = fetch(url)
|
id, err = downloadMedia(url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
return MediaResults{}, err
|
||||||
return
|
|
||||||
}
|
}
|
||||||
medias, err = getAllFilesForId(id)
|
medias, err = getAllFilesForId(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
return MediaResults{}, err
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
response := MediaResults{
|
return MediaResults{
|
||||||
Medias: medias,
|
Medias: medias,
|
||||||
}
|
}, nil
|
||||||
|
|
||||||
if err := fetchResponseTmpl.Execute(w, response); err != nil {
|
|
||||||
log.Error().Msgf("Error rendering template: %v", err)
|
|
||||||
http.Error(w, "Internal error", http.StatusInternalServerError)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns the ID of the file
|
// returns the ID of the file
|
||||||
func fetch(url string) (string, error) {
|
func downloadMedia(url string) (string, error) {
|
||||||
// The id will be used as the name of the parent directory of the output files
|
// The id will be used as the name of the parent directory of the output files
|
||||||
id := GetMD5Hash(url)
|
id := GetMD5Hash(url)
|
||||||
name := getMediaDirectory(id) + "%(title)s.%(ext)s"
|
name := getMediaDirectory(id) + "%(title)s.%(ext)s"
|
||||||
|
|
@ -144,7 +164,7 @@ func fetch(url string) (string, error) {
|
||||||
return id, nil
|
return id, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the relative directory containing the media file, with a trailing slash
|
// Returns the relative directory containing the media file, with a trailing slash.
|
||||||
// Id is expected to be pre validated
|
// Id is expected to be pre validated
|
||||||
func getMediaDirectory(id string) string {
|
func getMediaDirectory(id string) string {
|
||||||
return downloadDir + id + "/"
|
return downloadDir + id + "/"
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,10 @@ func ServeMedia(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
streamFileToClientById(w, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func streamFileToClientById(w http.ResponseWriter, id string) {
|
||||||
filename, err := getFileFromId(id)
|
filename, err := getFileFromId(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
<div>
|
<div>
|
||||||
<h2>Done!</h2>
|
<h2>Done!</h2>
|
||||||
{{range .Medias}}
|
{{range .Medias}}
|
||||||
<a style="color: dodgerblue" href="download?id={{.Id}}">{{.Name}}</a> <small>{{.HumanSize}}</small>
|
<a style="color: dodgerblue" href="/download?id={{.Id}}">{{.Name}}</a> <small>{{.HumanSize}}</small>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue