Full Mattermost server source with integrated Community Enterprise features. Includes vendor directory for offline/air-gapped builds. Structure: - enterprise-impl/: Enterprise feature implementations - enterprise-community/: Init files that register implementations - enterprise/: Bridge imports (community_imports.go) - vendor/: All dependencies for offline builds Build (online): go build ./cmd/mattermost Build (offline/air-gapped): go build -mod=vendor ./cmd/mattermost 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
145 lines
3.5 KiB
Go
145 lines
3.5 KiB
Go
package docconv // import "code.sajari.com/docconv/v2"
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"path"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
// Response payload sent back to the requestor
|
|
type Response struct {
|
|
Body string `json:"body"`
|
|
Meta map[string]string `json:"meta"`
|
|
MSecs uint32 `json:"msecs"`
|
|
Error string `json:"error"`
|
|
}
|
|
|
|
// MimeTypeByExtension returns a mimetype for the given extension, or
|
|
// application/octet-stream if none can be determined.
|
|
func MimeTypeByExtension(filename string) string {
|
|
switch strings.ToLower(path.Ext(filename)) {
|
|
case ".doc":
|
|
return "application/msword"
|
|
case ".docx":
|
|
return "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
|
|
case ".odt":
|
|
return "application/vnd.oasis.opendocument.text"
|
|
case ".pages":
|
|
return "application/vnd.apple.pages"
|
|
case ".pdf":
|
|
return "application/pdf"
|
|
case ".pptx":
|
|
return "application/vnd.openxmlformats-officedocument.presentationml.presentation"
|
|
case ".rtf":
|
|
return "application/rtf"
|
|
case ".xml":
|
|
return "text/xml"
|
|
case ".xhtml", ".html", ".htm":
|
|
return "text/html"
|
|
case ".jpg", ".jpeg", ".jpe", ".jfif", ".jfif-tbnl":
|
|
return "image/jpeg"
|
|
case ".png":
|
|
return "image/png"
|
|
case ".tif":
|
|
return "image/tif"
|
|
case ".tiff":
|
|
return "image/tiff"
|
|
case ".txt":
|
|
return "text/plain"
|
|
}
|
|
return "application/octet-stream"
|
|
}
|
|
|
|
// Convert a file to plain text.
|
|
func Convert(r io.Reader, mimeType string, readability bool) (*Response, error) {
|
|
start := time.Now()
|
|
|
|
var body string
|
|
var meta map[string]string
|
|
var err error
|
|
switch mimeType {
|
|
case "application/msword", "application/vnd.ms-word":
|
|
body, meta, err = ConvertDoc(r)
|
|
|
|
case "application/vnd.openxmlformats-officedocument.wordprocessingml.document":
|
|
body, meta, err = ConvertDocx(r)
|
|
|
|
case "application/vnd.openxmlformats-officedocument.presentationml.presentation":
|
|
body, meta, err = ConvertPptx(r)
|
|
|
|
case "application/vnd.oasis.opendocument.text":
|
|
body, meta, err = ConvertODT(r)
|
|
|
|
case "application/vnd.apple.pages", "application/x-iwork-pages-sffpages":
|
|
body, meta, err = ConvertPages(r)
|
|
|
|
case "application/pdf":
|
|
body, meta, err = ConvertPDF(r)
|
|
|
|
case "application/rtf", "application/x-rtf", "text/rtf", "text/richtext":
|
|
body, meta, err = ConvertRTF(r)
|
|
|
|
case "text/html":
|
|
body, meta, err = ConvertHTML(r, readability)
|
|
|
|
case "text/url":
|
|
body, meta, err = ConvertURL(r, readability)
|
|
|
|
case "text/xml", "application/xml":
|
|
body, meta, err = ConvertXML(r)
|
|
|
|
case "image/jpeg", "image/png", "image/tif", "image/tiff":
|
|
body, meta, err = ConvertImage(r)
|
|
|
|
case "text/plain":
|
|
var b []byte
|
|
b, err = io.ReadAll(r)
|
|
body = string(b)
|
|
}
|
|
|
|
if err != nil {
|
|
return nil, fmt.Errorf("error converting data: %v", err)
|
|
}
|
|
|
|
return &Response{
|
|
Body: strings.TrimSpace(body),
|
|
Meta: meta,
|
|
MSecs: uint32(time.Since(start) / time.Millisecond),
|
|
}, nil
|
|
}
|
|
|
|
// ConvertPath converts a local path to text.
|
|
func ConvertPath(path string) (*Response, error) {
|
|
mimeType := MimeTypeByExtension(path)
|
|
|
|
f, err := os.Open(path)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer f.Close()
|
|
|
|
return Convert(f, mimeType, true)
|
|
}
|
|
|
|
// ConvertPathReadability converts a local path to text, with the given readability
|
|
// option.
|
|
func ConvertPathReadability(path string, readability bool) ([]byte, error) {
|
|
mimeType := MimeTypeByExtension(path)
|
|
|
|
f, err := os.Open(path)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer f.Close()
|
|
|
|
data, err := Convert(f, mimeType, readability)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return json.Marshal(data)
|
|
}
|