1
0
mirror of https://github.com/Luzifer/tex-api.git synced 2024-09-16 16:18:24 +00:00

Allow to request log instead of PDF on error

Signed-off-by: Knut Ahlers <knut@ahlers.me>
This commit is contained in:
Knut Ahlers 2023-09-06 19:54:02 +02:00
parent 3364efc57b
commit 9c91061cf1
Signed by: luzifer
GPG Key ID: D91C3E91E4CAD6F5
4 changed files with 31 additions and 10 deletions

View File

@ -48,7 +48,7 @@ main.log
main.pdf
# Using the default-env and exchanging a TeX file for a PDF
# curl -sSL -H 'Accept: application/pdf' --data-binary @main.tex -o main.pdf localhost:3000/job
# curl -L -H 'Accept: application/pdf' --data-binary @main.tex -OJ localhost:3000/job
```
What happened here is we packed all assets required for generating the letter into the ZIP archive, pushed it to the API, waited for it to build a TAR and extracted the resulting files from it.
@ -69,3 +69,5 @@ GET /job/{uuid}/download Download the resulting archive (You may specify an
Accept header to select whether to receive a ZIP, a
TAR archive or just the raw PDF.)
```
All routes accept the `log-on-error` parameter: If set a PDF download (`Accept` header set to `application/pdf`) will return the log instead of the PDF if no PDF is found.

View File

@ -5,6 +5,7 @@ import (
"archive/zip"
"bytes"
"io"
"io/fs"
"os"
"path"
"path/filepath"
@ -109,7 +110,7 @@ func buildAssetsZIP(uid uuid.UUID) (io.Reader, error) {
return buf, errors.Wrap(w.Close(), "closing zip file")
}
func getAssetsPDF(uid uuid.UUID) (io.Reader, error) {
func getAssetsFile(uid uuid.UUID, ext string) (io.Reader, error) {
var (
buf = new(bytes.Buffer)
found bool
@ -121,7 +122,7 @@ func getAssetsPDF(uid uuid.UUID) (io.Reader, error) {
return err
}
if path.Ext(info.Name()) != ".pdf" {
if path.Ext(info.Name()) != ext {
return nil
}
@ -131,7 +132,7 @@ func getAssetsPDF(uid uuid.UUID) (io.Reader, error) {
}
defer func() {
if err := osFile.Close(); err != nil {
logrus.WithError(err).Error("closing output pdf file (leaked fd)")
logrus.WithError(err).Error("closing output file (leaked fd)")
}
}()
@ -145,7 +146,7 @@ func getAssetsPDF(uid uuid.UUID) (io.Reader, error) {
if !found {
// We found no file
return nil, errors.New("no pdf found")
return nil, fs.ErrNotExist
}
return buf, errors.Wrap(err, "walking source dir")

View File

@ -3,6 +3,7 @@ package main
import (
"fmt"
"io"
"io/fs"
"net/http"
"os"
"time"
@ -109,8 +110,14 @@ func downloadAssets(res http.ResponseWriter, r *http.Request) {
case "application/pdf":
contentType = "application/pdf"
content, err = getAssetsPDF(uid)
filename = uid.String() + ".pdf"
content, err = getAssetsFile(uid, ".pdf")
if errors.Is(err, fs.ErrNotExist) && r.URL.Query().Has("log-on-error") {
contentType = "application/octet-stream"
filename = uid.String() + ".log"
content, err = getAssetsFile(uid, ".log")
}
default:
content, err = buildAssetsZIP(uid)

View File

@ -6,7 +6,6 @@ import (
"io"
"math"
"net/http"
"net/url"
"os"
"os/exec"
"path"
@ -133,6 +132,7 @@ func startNewJob(res http.ResponseWriter, r *http.Request) {
go jobProcessor(jobUUID)
u := urlMust(router.Get("waitForJob").URL("uid", jobUUID.String()))
u.RawQuery = r.URL.Query().Encode()
http.Redirect(res, r, u.String(), http.StatusFound)
}
@ -163,19 +163,30 @@ func waitForJob(res http.ResponseWriter, r *http.Request) {
fallthrough
case statusStarted:
u := urlMust(router.Get("waitForJob").URL("uid", uid.String()))
u.RawQuery = url.Values{"loop": []string{strconv.Itoa(loop)}}.Encode()
<-time.After(time.Duration(math.Pow(sleepBase, float64(loop))) * time.Second)
params := r.URL.Query()
params.Set("loop", strconv.Itoa(loop))
u := urlMust(router.Get("waitForJob").URL("uid", uid.String()))
u.RawQuery = params.Encode()
http.Redirect(res, r, u.String(), http.StatusFound)
return
case statusError:
if r.URL.Query().Has("log-on-error") {
u := urlMust(router.Get("downloadAssets").URL("uid", uid.String()))
u.RawQuery = r.URL.Query().Encode()
http.Redirect(res, r, u.String(), http.StatusFound)
return
}
http.Error(res, "Processing ran into an error.", http.StatusInternalServerError)
case statusFinished:
u := urlMust(router.Get("downloadAssets").URL("uid", uid.String()))
u.RawQuery = r.URL.Query().Encode()
http.Redirect(res, r, u.String(), http.StatusFound)
}
}