Better error messages
This commit is contained in:
parent
ff94a96b92
commit
43230aa401
5 changed files with 43 additions and 55 deletions
|
|
@ -34,10 +34,10 @@ type Media struct {
|
||||||
|
|
||||||
type Results struct {
|
type Results struct {
|
||||||
Medias []Media
|
Medias []Media
|
||||||
|
Url string
|
||||||
|
ErrorMessage string
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Use something better than this. It's too tedious to map
|
|
||||||
var fetchResponseTmpl = template.Must(template.ParseFiles("templates/media/response.html"))
|
|
||||||
var fetchIndexTmpl = template.Must(template.ParseFiles("templates/media/index.html"))
|
var fetchIndexTmpl = template.Must(template.ParseFiles("templates/media/index.html"))
|
||||||
|
|
||||||
// Where the media files are saved. Always has a trailing slash
|
// Where the media files are saved. Always has a trailing slash
|
||||||
|
|
@ -57,11 +57,11 @@ 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)
|
response, err := getMediaResults(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
_ = fetchIndexTmpl.Execute(w, response)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := fetchResponseTmpl.Execute(w, response); err != nil {
|
if err := fetchIndexTmpl.Execute(w, response); err != nil {
|
||||||
log.Error().Msgf("Error rendering template: %v", err)
|
log.Error().Msgf("Error rendering template: %v", err)
|
||||||
http.Error(w, "Internal error", http.StatusInternalServerError)
|
http.Error(w, "Internal error", http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|
@ -85,7 +85,7 @@ func FetchMediaApi(w http.ResponseWriter, r *http.Request) {
|
||||||
func getMediaResults(r *http.Request) (Results, error) {
|
func getMediaResults(r *http.Request) (Results, error) {
|
||||||
url := r.URL.Query().Get("url")
|
url := r.URL.Query().Get("url")
|
||||||
if url == "" {
|
if url == "" {
|
||||||
return Results{}, errors.New("Missing URL")
|
return Results{ErrorMessage: "Missing URL"}, errors.New("missing URL")
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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.
|
||||||
|
|
@ -95,25 +95,28 @@ func getMediaResults(r *http.Request) (Results, error) {
|
||||||
id := GetMD5Hash(url)
|
id := GetMD5Hash(url)
|
||||||
// Look to see if we already have the media on disk
|
// Look to see if we already have the media on disk
|
||||||
medias, err := getAllFilesForId(id)
|
medias, err := getAllFilesForId(id)
|
||||||
|
result := Results{Url: url}
|
||||||
if len(medias) == 0 {
|
if len(medias) == 0 {
|
||||||
// We don't, so go fetch it
|
// We don't, so go fetch it
|
||||||
id, err = downloadMedia(url)
|
errMessage := ""
|
||||||
|
id, errMessage, err = downloadMedia(url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Results{}, err
|
result.ErrorMessage = errMessage
|
||||||
|
return result, err
|
||||||
}
|
}
|
||||||
medias, err = getAllFilesForId(id)
|
medias, err = getAllFilesForId(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Results{}, err
|
result.ErrorMessage = err.Error()
|
||||||
|
return result, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Results{
|
result.Medias = medias
|
||||||
Medias: medias,
|
return result, nil
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns the ID of the file
|
// returns the ID of the file, and error message, and an error
|
||||||
func downloadMedia(url string) (string, error) {
|
func downloadMedia(url string) (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) + "%(id)s.%(ext)s"
|
name := getMediaDirectory(id) + "%(id)s.%(ext)s"
|
||||||
|
|
@ -140,7 +143,7 @@ func downloadMedia(url string) (string, error) {
|
||||||
err := cmd.Start()
|
err := cmd.Start()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Msgf("Error starting command: %v", err)
|
log.Error().Msgf("Error starting command: %v", err)
|
||||||
return "", err
|
return "", err.Error(), err
|
||||||
}
|
}
|
||||||
|
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
|
|
@ -157,15 +160,15 @@ func downloadMedia(url string) (string, error) {
|
||||||
|
|
||||||
err = cmd.Wait()
|
err = cmd.Wait()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Msgf("cmd.Run() failed with %s", err)
|
log.Error().Err(err).Msgf("cmd.Run() failed with %s", err)
|
||||||
return "", err
|
return "", strings.TrimSpace(stderrBuf.String()), err
|
||||||
} else if errStdout != nil {
|
} else if errStdout != nil {
|
||||||
log.Error().Msgf("failed to capture stdout: %v", errStdout)
|
log.Error().Msgf("failed to capture stdout: %v", errStdout)
|
||||||
} else if errStderr != nil {
|
} else if errStderr != nil {
|
||||||
log.Error().Msgf("failed to capture stderr: %v", errStderr)
|
log.Error().Msgf("failed to capture stderr: %v", errStderr)
|
||||||
}
|
}
|
||||||
|
|
||||||
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.
|
||||||
|
|
|
||||||
7
static/css/bootstrap.min.css
vendored
Normal file
7
static/css/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -3,8 +3,7 @@
|
||||||
<head>
|
<head>
|
||||||
<title>media-roller</title>
|
<title>media-roller</title>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet"
|
<link rel="stylesheet" type="text/css" href="/static/css//bootstrap.min.css">
|
||||||
integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
|
|
||||||
<link rel="stylesheet" type="text/css" href="/static/css/style.css">
|
<link rel="stylesheet" type="text/css" href="/static/css/style.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
@ -19,12 +18,24 @@
|
||||||
<form action="/fetch" method="GET">
|
<form action="/fetch" method="GET">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input name="url" type="url" class="form-control" placeholder="URL" aria-label="URL"
|
<input name="url" type="url" class="form-control" placeholder="URL" aria-label="URL"
|
||||||
aria-describedby="button-submit" autofocus>
|
aria-describedby="button-submit" value="{{.Url}}" autofocus>
|
||||||
<div class="input-group-append">
|
<div class="input-group-append">
|
||||||
<button class="btn btn-primary" type="submit" id="button-submit">Submit</button>
|
<button class="btn btn-primary" type="submit" id="button-submit">Submit</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
{{ if .Medias }}
|
||||||
|
<div style="margin-top:20px;">
|
||||||
|
<h2>Done!</h2>
|
||||||
|
{{range .Medias}}
|
||||||
|
<a style="color: dodgerblue" href="/download?id={{.Id}}">{{.Name}}</a> <small>{{.HumanSize}}</small>
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
{{ if .ErrorMessage }}
|
||||||
|
<h4 style="margin-top:20px;">Error</h4>
|
||||||
|
<pre style="background-color:white;text-align:left;white-space: pre-wrap;">{{ .ErrorMessage }}</pre>
|
||||||
|
{{ end }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<footer>
|
<footer>
|
||||||
|
|
|
||||||
|
|
@ -1,33 +0,0 @@
|
||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<title>media-roller</title>
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
|
||||||
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet"
|
|
||||||
integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
|
|
||||||
<link rel="stylesheet" type="text/css" href="/static/css/style.css">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="container d-flex flex-column text-light text-center">
|
|
||||||
<div class="flex-grow-1"></div>
|
|
||||||
<div class="jumbotron bg-transparent flex-grow-1">
|
|
||||||
<h1 class="display-4"><a class="text-light" href="/">media roller</a></h1>
|
|
||||||
<p>
|
|
||||||
Mobile friendly tool for downloading videos from social media
|
|
||||||
</p>
|
|
||||||
<div>
|
|
||||||
<h2>Done!</h2>
|
|
||||||
{{range .Medias}}
|
|
||||||
<a style="color: dodgerblue" href="/download?id={{.Id}}">{{.Name}}</a> <small>{{.HumanSize}}</small>
|
|
||||||
{{ end }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<footer>
|
|
||||||
<div>
|
|
||||||
<p class="text-muted">Source at <a class="text-light" href="https://github.com/rroller/media-roller">https://github.com/rroller/media-roller</a>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</footer>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
Loading…
Reference in a new issue