Files
filestash/server/ctrl/export.go
2019-01-28 01:09:45 +11:00

150 lines
4.1 KiB
Go

package ctrl
import (
"fmt"
. "github.com/mickael-kerjean/filestash/server/common"
"github.com/mickael-kerjean/filestash/server/model"
"github.com/gorilla/mux"
"io"
"net/http"
"os"
"os/exec"
"runtime"
"strings"
)
var EXPORT_PATH string
func init() {
EXPORT_PATH = GetAbsolutePath(TMP_PATH)
os.RemoveAll(EXPORT_PATH)
os.MkdirAll(EXPORT_PATH, os.ModePerm)
}
func FileExport(ctx App, res http.ResponseWriter, req *http.Request) {
query := req.URL.Query()
p := mux.Vars(req)
mimeType := fmt.Sprintf("%s/%s", p["mtype0"], p["mtype1"])
path, err := pathBuilder(ctx, strings.Replace(req.URL.Path, fmt.Sprintf("/api/export/%s/%s/%s", p["share"], p["mtype0"], p["mtype1"]), "", 1))
if err != nil {
SendErrorResult(res, err)
return
} else if model.CanRead(&ctx) == false {
SendErrorResult(res, ErrPermissionDenied)
return
}
http.SetCookie(res, &http.Cookie{
Name: "download",
Value: "",
MaxAge: -1,
Path: "/",
})
var tmpPath string = EXPORT_PATH + "/export_" + QuickString(10)
var cmd *exec.Cmd
var emacsPath string
var outPath string
if GetMimeType(path) == "text/org" {
if emacsPath, err = exec.LookPath("emacs"); err != nil {
SendErrorResult(res, ErrMissingDependency)
return
}
if runtime.GOOS == "darwin" {
// on OSX, the default emacs isn't usable so we default to the one provided by `brew`
if f, err := os.OpenFile("/usr/local/Cellar/emacs/", os.O_RDONLY, os.ModePerm); err == nil {
if dirs, err := f.Readdirnames(0); err == nil {
if len(dirs) > 0 {
emacsPath = "/usr/local/Cellar/emacs/" + dirs[0] + "/bin/emacs"
}
}
}
}
if mimeType == "text/html" {
cmd = exec.Command(
emacsPath, "--no-init-file", "--batch",
"--load", GetAbsolutePath(CONFIG_PATH + "emacs.el"),
"--eval", "(setq org-html-extension \"org\")",
tmpPath + "/index.org", "-f", "org-html-export-to-html",
)
outPath = "index.org.org"
} else if mimeType == "application/pdf" {
cmd = exec.Command(
emacsPath, "--no-init-file", "--batch",
tmpPath + "/index.org", "-f", "org-latex-export-to-pdf",
)
if query.Get("mode") == "beamer" {
cmd = exec.Command(
emacsPath, "--no-init-file", "--batch",
tmpPath + "/index.org", "-f", "org-beamer-export-to-pdf",
)
}
outPath = "index.pdf"
} else if mimeType == "text/calendar" {
cmd = exec.Command(
emacsPath, "--no-init-file", "--batch",
tmpPath + "/index.org", "-f", "org-icalendar-export-to-ics",
)
outPath = "index.ics"
} else if mimeType == "text/plain" {
cmd = exec.Command(
emacsPath, "--no-init-file", "--batch",
tmpPath + "/index.org", "-f", "org-ascii-export-to-ascii",
)
outPath = "index.txt"
} else if mimeType == "text/x-latex" {
cmd = exec.Command(
emacsPath, "--no-init-file", "--batch",
tmpPath + "/index.org", "-f", "org-latex-export-to-latex",
)
outPath = "index.tex"
} else if mimeType == "text/markdown" {
cmd = exec.Command(
emacsPath, "--no-init-file", "--batch",
tmpPath + "/index.org", "-f", "org-md-export-to-markdown",
)
outPath = "index.md"
} else if mimeType == "application/vnd.oasis.opendocument.text" {
cmd = exec.Command(
emacsPath, "--no-init-file", "--batch",
tmpPath + "/index.org", "-f", "org-odt-export-to-odt",
)
outPath = "index.odt"
}else {
SendErrorResult(res, ErrNotImplemented)
return
}
os.MkdirAll(tmpPath, os.ModePerm)
defer os.RemoveAll(tmpPath)
f, err := os.OpenFile(tmpPath + "/index.org", os.O_WRONLY|os.O_CREATE, os.ModePerm)
if err != nil {
SendErrorResult(res, ErrFilesystemError)
return
}
file, err := ctx.Backend.Cat(path)
if err != nil {
SendErrorResult(res, err)
return
}
io.Copy(f, file)
// TODO: insert related resources: eg: images
if err = cmd.Run(); err != nil {
SendErrorResult(res, NewError("emacs has quit with error: '%s'" + err.Error(), 400))
return
}
f, err = os.OpenFile(tmpPath + "/"+outPath, os.O_RDONLY, os.ModePerm)
if err != nil {
SendErrorResult(res, ErrFilesystemError)
return
}
res.Header().Set("Content-Type", mimeType)
io.Copy(res, f)
return
}
SendErrorResult(res, ErrNotImplemented)
return
}