diff --git a/plugin-libreoffice/plugin.go b/plugin-libreoffice/plugin.go deleted file mode 100644 index 583292f1..00000000 --- a/plugin-libreoffice/plugin.go +++ /dev/null @@ -1,288 +0,0 @@ -// Copyright 2016 Documize Inc. . All rights reserved. -// -// This software (Documize Community Edition) is licensed under -// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html -// -// You can operate outside the AGPL restrictions by purchasing -// Documize Enterprise Edition and obtaining a commercial license -// by contacting . -// -// https://documize.com - -// Package main provides a simple Documize plugin for document conversions using libreoffice. -package main - -import ( - "bytes" - "encoding/base64" - "errors" - "flag" - "fmt" - "io/ioutil" - "net" - "net/rpc" - "net/rpc/jsonrpc" - "os" - "os/exec" - "path/filepath" - "runtime" - "strings" - "sync" - "time" - "unicode" - "unicode/utf8" - - api "github.com/documize/community/core/convapi" -) - -var cmdmtx sync.Mutex // enforce only one conversion at a time - -// LibreOffice provides a peg on which to hang the Convert method. -type LibreOffice struct{} - -var dir *os.File -var outputDir string - -func init() { - tempDir := os.TempDir() - if !strings.HasSuffix(tempDir, string(os.PathSeparator)) { - tempDir += string(os.PathSeparator) - } - outputDir = tempDir + "documize-plugin-libreoffice" - err := os.MkdirAll(outputDir, os.ModePerm) - if err != nil { - panic(err) - } -} - -func createTempDir() *os.File { - fmt.Println("create temp dir") - err := os.Mkdir(outputDir, 0777) // make the dir if non-existent, TODO filemode - if err != nil { - //fmt.Println("unable to create temp dir") - panic(err) - } - dir, err = os.Open(outputDir) - if err != nil { - //fmt.Println("unable to open created temp dir") - panic(err) - } - return dir -} - -func removePrevTempFiles(dir *os.File) error { - fin, err := dir.Readdirnames(-1) - if err != nil { - return err - } - for _, nam := range fin { // remove any previous temporary files - target := outputDir + string(os.PathSeparator) + nam - //fmt.Println("delete temp file: " + target) - err = os.Remove(target) - if err != nil { - return err - } - } - return nil -} - -func runLibreOffice(inPath string) error { - var err error - var cmd = "soffice" - switch runtime.GOOS { - case "darwin": // may not be in the path - cmd = "/Applications/LibreOffice.app/Contents/MacOS/soffice" - case "windows": // TODO - } - cmd, err = exec.LookPath(cmd) - if err != nil { - return err - } - - args := []string{"--headless", - "--convert-to", "html", // "html:XHTML Writer File:UTF8", - "--outdir", outputDir, inPath} - - fmt.Println("libreoffice args:", args) - - ecmd := exec.Command(cmd, args...) - var outBuf, errBuf bytes.Buffer - ecmd.Stdout, ecmd.Stderr = &outBuf, &errBuf - over := make(chan error, 1) - go func() { - if e := ecmd.Start(); e != nil { - over <- e - } else { - over <- ecmd.Wait() - } - }() - select { - case err = <-over: - if err != nil { - return errors.New(string(outBuf.Bytes()) + string(errBuf.Bytes()) + err.Error()) - } - case <-time.After(2 * time.Minute): - ke := "" - if runtime.GOOS != "windows" { // Process is not available on windows - err = ecmd.Process.Kill() - if err != nil { - ke = ", kill error: " + err.Error() - } - } - return errors.New("libreoffice.Convert() cancelled via timeout" + ke) - } - return nil -} - -// Convert converts a file into the Countersoft Documize format. -func (file *LibreOffice) Convert(r api.DocumentConversionRequest, reply *api.DocumentConversionResponse) error { - var err error - - cmdmtx.Lock() // enforce only one conversion at a time - defer cmdmtx.Unlock() - - dir, err = os.Open(outputDir) - if err != nil { - dir = createTempDir() - } - defer func() { - if e := dir.Close(); e != nil { - fmt.Fprintln(os.Stderr, "Error closing temp dir: "+e.Error()) - } - }() - - err = removePrevTempFiles(dir) - if err != nil { - return err - } - - _, inFileX := filepath.Split(r.Filename) - inFile := fixName(inFileX) - if inFile == "" { - return errors.New("no filename") - } - - xtn := filepath.Ext(inFile) - if xtn == "" { - return errors.New("invalid filename: " + inFile) - } - - inPath := outputDir + string(os.PathSeparator) + inFile - fmt.Println("writing data to: " + inPath) - if err = ioutil.WriteFile(inPath, r.Filedata, 0777); err != nil { - return err - } - - err = runLibreOffice(inPath) - if err != nil { - return err - } - - outPath := strings.TrimSuffix(inPath, xtn) + ".html" - fmt.Println("output file: " + outPath) - reply.PagesHTML, err = ioutil.ReadFile(outPath) - if err != nil { - return err - } - fmt.Printf("%d bytes read from: %s\n", len(reply.PagesHTML), outPath) - - incorporateImages(reply) - - return ioutil.WriteFile(outputDir+string(os.PathSeparator)+"debug.html", reply.PagesHTML, 0666) -} - -func incorporateImages(reply *api.DocumentConversionResponse) { - dir, err := os.Open(outputDir) - if err == nil { - names, err := dir.Readdirnames(-1) - if err == nil { - for _, nam := range names { - //fmt.Println("Found file " + nam) - switch pic := strings.ToLower(filepath.Ext(nam)[1:]); pic { - case "jpg", "gif", "png", "webp": // TODO others? - //fmt.Println("Found picture file " + nam) - enam := fixName(nam) - buf, err := ioutil.ReadFile(outputDir + string(os.PathSeparator) + nam) - if err == nil { - enc := base64.StdEncoding.EncodeToString(buf) - benam := []byte(` 1000000 { - fmt.Println("Too large a file increase to replace (>1Mb)") - } else { - reply.PagesHTML = bytes.Join(split, rep) - } - } - } - } - } - } -} - -var port string - -func init() { - flag.StringVar(&port, "port", "", "the port to listen on") -} - -func main() { - var err error - - fmt.Println("Documize plugin-libreoffice starting up") - - fmt.Println("outputDir:" + outputDir) - - // register all the services that we accept - fileConverter := new(LibreOffice) - err = rpc.Register(fileConverter) - if err != nil { - panic(err) - } - - flag.Parse() - if port == "" { - fmt.Fprintln(os.Stderr, "no port specified, please use the '-port' flag") - return - } - - // set up the server - listener, err := net.Listen("tcp", ":"+port) - if err != nil { - panic(err) - } - - // start server - fmt.Println("Documize plugin-libreoffice server up on", listener.Addr()) - - for { - conn, err := listener.Accept() - if err != nil { - panic(err) - } - - go jsonrpc.ServeConn(conn) // using JSON encoding - } -} - -func fixName(s string) string { - ret := "" - for _, r := range s { - if utf8.RuneLen(r) > 1 || - unicode.IsSpace(r) || - unicode.IsSymbol(r) || - r == '%' { - ret += fmt.Sprintf("%%%x", r) - } else { - ret += string(r) - } - } - return ret -}