Files
qhmes/XSLPrintDot/backend_unix.go

158 lines
4.1 KiB
Go
Raw Normal View History

//go:build !windows
package main
import (
"fmt"
"os/exec"
"strings"
)
func (b *Bridge) getPrintersPlatform() ([]PrinterInfo, error) {
defaultName := ""
if out, err := exec.Command("lpstat", "-d").Output(); err == nil {
line := strings.TrimSpace(string(out))
if idx := strings.LastIndex(line, ":"); idx >= 0 {
defaultName = strings.TrimSpace(line[idx+1:])
}
}
cmd := exec.Command("sh", "-c", "lpstat -a | cut -d ' ' -f 1")
output, err := cmd.Output()
if err != nil {
return nil, err
}
lines := strings.Split(string(output), "\n")
var printers []PrinterInfo
for _, line := range lines {
trimmed := strings.TrimSpace(line)
if trimmed != "" {
printers = append(printers, PrinterInfo{Name: trimmed, IsDefault: trimmed == defaultName})
}
}
return printers, nil
}
func (b *Bridge) getPrinterCapabilitiesPlatform(printerName string) (map[string]interface{}, error) {
printerName = strings.TrimSpace(printerName)
if printerName == "" {
return nil, fmt.Errorf("printer name is empty")
}
cmd := exec.Command("lpoptions", "-p", printerName, "-l")
output, err := cmd.CombinedOutput()
if err != nil {
return nil, fmt.Errorf("lpoptions error: %v, output: %s", err, string(output))
}
options := map[string]map[string]interface{}{}
lines := strings.Split(string(output), "\n")
for _, line := range lines {
line = strings.TrimSpace(line)
if line == "" {
continue
}
parts := strings.SplitN(line, ":", 2)
if len(parts) != 2 {
continue
}
left := strings.TrimSpace(parts[0])
right := strings.TrimSpace(parts[1])
optName := left
if idx := strings.Index(left, "/"); idx >= 0 {
optName = strings.TrimSpace(left[:idx])
}
values := []string{}
defaultValue := ""
for _, token := range strings.Fields(right) {
if strings.HasPrefix(token, "*") {
clean := strings.TrimPrefix(token, "*")
defaultValue = clean
values = append(values, clean)
continue
}
values = append(values, token)
}
options[optName] = map[string]interface{}{
"values": values,
"default": defaultValue,
"raw": right,
}
}
return map[string]interface{}{
"printer": printerName,
"options": options,
}, nil
}
func (b *Bridge) printPDFPlatform(printerName, filePath string, options PrintOptions) error {
args := []string{"-d", printerName}
if options.Copies > 1 {
args = append(args, "-n", fmt.Sprintf("%d", options.Copies))
}
if options.PageRange != "" {
args = append(args, "-P", options.PageRange)
}
switch strings.ToLower(strings.TrimSpace(options.PageSet)) {
case "even":
args = append(args, "-o", "page-set=even")
case "odd":
args = append(args, "-o", "page-set=odd")
}
switch strings.ToLower(strings.TrimSpace(options.Duplex)) {
case "long-edge", "long", "duplex", "duplexlong":
args = append(args, "-o", "sides=two-sided-long-edge")
case "short-edge", "short", "duplexshort":
args = append(args, "-o", "sides=two-sided-short-edge")
case "simplex", "one-sided":
args = append(args, "-o", "sides=one-sided")
}
switch strings.ToLower(strings.TrimSpace(options.ColorMode)) {
case "color":
args = append(args, "-o", "ColorModel=RGB")
case "mono", "monochrome", "grayscale", "gray":
args = append(args, "-o", "ColorModel=Gray")
}
if options.Paper != "" {
args = append(args, "-o", fmt.Sprintf("media=%s", options.Paper))
}
switch strings.ToLower(strings.TrimSpace(options.Scale)) {
case "noscale", "none", "actual":
args = append(args, "-o", "scaling=100")
case "shrink":
// Default CUPS behavior already shrinks to fit if needed
case "fit":
args = append(args, "-o", "fit-to-page")
}
switch strings.ToLower(strings.TrimSpace(options.Orientation)) {
case "portrait":
args = append(args, "-o", "orientation-requested=3")
case "landscape":
args = append(args, "-o", "orientation-requested=4")
}
if options.TrayBin != "" {
args = append(args, "-o", fmt.Sprintf("InputSlot=%s", options.TrayBin))
}
args = append(args, filePath)
cmd := exec.Command("lp", args...)
if out, err := cmd.CombinedOutput(); err != nil {
return fmt.Errorf("lp error: %v, output: %s", err, string(out))
}
return nil
}