fix(display): custom program file handling

This commit is contained in:
2025-12-03 17:29:45 +01:00
parent df1ea7b163
commit cfb26a0b47
4 changed files with 67 additions and 50 deletions
+63
View File
@@ -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
}
-44
View File
@@ -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
View File
@@ -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
View File
@@ -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)