mirror of
https://codeberg.org/PLG-Development/PLG-MuDiCS
synced 2026-07-05 16:37:09 +00:00
fix(display): custom program file handling
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
package pkg
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"plg-mudics/shared"
|
||||
"syscall"
|
||||
|
||||
"github.com/gabriel-vasile/mimetype"
|
||||
)
|
||||
|
||||
var FileHandler fileHandler = fileHandler{}
|
||||
|
||||
type fileHandler struct {
|
||||
runningProgram *exec.Cmd
|
||||
}
|
||||
|
||||
func (fh *fileHandler) OpenFile(path string) error {
|
||||
var err error
|
||||
|
||||
mType, err := mimetype.DetectFile(path)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to detect mime type: %w", err)
|
||||
}
|
||||
|
||||
tempDirPath, err := os.MkdirTemp("", "plg-mudics-program-profile-")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create temporary profile directory: %w", err)
|
||||
}
|
||||
|
||||
err = fh.CloseRunningProgram()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch mType.String() {
|
||||
case "application/vnd.openxmlformats-officedocument.presentationml.presentation", "application/vnd.oasis.opendocument.presentation":
|
||||
fh.runningProgram = exec.Command("soffice", "--show", path, "--nologo", "--view", "--norestore", fmt.Sprintf("-env:UserInstallation=file://%s", tempDirPath))
|
||||
case "application/pdf":
|
||||
fh.runningProgram = exec.Command("xreader", path, "--presentation")
|
||||
default:
|
||||
return fmt.Errorf("unsupported file type: %s", mType.String())
|
||||
}
|
||||
|
||||
fh.runningProgram.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
|
||||
|
||||
result := shared.RunShellCommandNonBlocking(fh.runningProgram)
|
||||
if result.ExitCode != 0 {
|
||||
return fmt.Errorf("could not open pdf: %s (%d)", result.Stderr, result.ExitCode)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (fh *fileHandler) CloseRunningProgram() error {
|
||||
if fh.runningProgram == nil {
|
||||
return nil
|
||||
}
|
||||
err := syscall.Kill(-fh.runningProgram.Process.Pid, syscall.SIGTERM)
|
||||
fh.runningProgram = nil
|
||||
return err
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
package pkg
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"plg-mudics/shared"
|
||||
)
|
||||
|
||||
var runningHelpProgram *exec.Cmd = nil
|
||||
|
||||
func OpenPresentation(path string) error {
|
||||
tempDirPath, err := os.MkdirTemp("", "plg-mudics-libreoffice-profile-")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create temporary profile directory: %w", err)
|
||||
}
|
||||
|
||||
result := shared.RunShellCommand(runningHelpProgram)
|
||||
runningHelpProgram = exec.Command("soffice", "--show", path, "--nologo", "--view", "--norestore", fmt.Sprintf("-env:UserInstallation=file:///%s", tempDirPath))
|
||||
killedByParent := -1
|
||||
if result.ExitCode != 0 && result.ExitCode != killedByParent {
|
||||
return errors.New(result.Stderr)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func OpenPDF(path string) error {
|
||||
runningHelpProgram = exec.Command("xreader", path, "--presentation")
|
||||
result := shared.RunShellCommandNonBlocking(runningHelpProgram)
|
||||
killedByParent := -1
|
||||
if result.ExitCode != 0 && result.ExitCode != killedByParent {
|
||||
return fmt.Errorf("could not open pdf: %s (%d)", result.Stderr, result.ExitCode)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func CloseRunningProgram() error {
|
||||
if runningHelpProgram == nil {
|
||||
return nil
|
||||
}
|
||||
err := runningHelpProgram.Process.Kill()
|
||||
return err
|
||||
}
|
||||
+3
-5
@@ -322,10 +322,8 @@ func openFileRoute(ctx echo.Context) error {
|
||||
var templateBuffer bytes.Buffer
|
||||
imageTemplate(pathParam).Render(context.Background(), &templateBuffer)
|
||||
sseConnection <- templateBuffer.String()
|
||||
case "application/vnd.openxmlformats-officedocument.presentationml.presentation", "application/vnd.oasis.opendocument.presentation":
|
||||
err = pkg.OpenPresentation(fullPath)
|
||||
case "application/pdf":
|
||||
err = pkg.OpenPDF(fullPath)
|
||||
case "application/pdf", "application/vnd.openxmlformats-officedocument.presentationml.presentation", "application/vnd.oasis.opendocument.presentation":
|
||||
err = pkg.FileHandler.OpenFile(fullPath)
|
||||
default:
|
||||
slog.Info("Unsupported file type", "type", mType)
|
||||
return ctx.JSON(http.StatusUnsupportedMediaType, shared.ErrorResponse{Description: "Unsupported file type: " + mType.String()})
|
||||
@@ -409,7 +407,7 @@ func previewRoute(ctx echo.Context) error {
|
||||
|
||||
// Reset previous file views so they dont collide with the new one
|
||||
func resetView() error {
|
||||
err := pkg.CloseRunningProgram()
|
||||
err := pkg.FileHandler.CloseRunningProgram()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to close running program: %w", err)
|
||||
}
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@ func RunShellCommandNonBlocking(cmd *exec.Cmd) CommandResponse {
|
||||
cmd.Stderr = &stderr
|
||||
cmd.Start()
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 200*time.Millisecond)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
|
||||
defer cancel()
|
||||
|
||||
done := make(chan error, 1)
|
||||
|
||||
Reference in New Issue
Block a user