go-ipp/cups-client.go

340 lines
12 KiB
Go
Raw Permalink Normal View History

2022-11-17 11:02:26 +00:00
/*
2022-11-18 09:02:04 +00:00
** Copyright 2022 Dolysis Consulting Limited
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
**
** For changes see the git log
*/
2019-03-10 17:43:47 +00:00
package ipp
2019-03-15 15:20:02 +00:00
import (
"bytes"
"strings"
)
2019-03-15 15:20:02 +00:00
// CUPSClient implements a ipp client with specific cups operations
2019-03-15 15:20:02 +00:00
type CUPSClient struct {
*IPPClient
}
// NewCUPSClient creates a new cups ipp client (used HttpAdapter internally)
2019-03-15 15:20:02 +00:00
func NewCUPSClient(host string, port int, username, password string, useTLS bool) *CUPSClient {
ippClient := NewIPPClient(host, port, username, password, useTLS)
return &CUPSClient{ippClient}
}
// NewCUPSClient creates a new cups ipp client with given Adapter
func NewCUPSClientWithAdapter(username string, adapter Adapter) *CUPSClient {
ippClient := NewIPPClientWithAdapter(username, adapter)
return &CUPSClient{ippClient}
}
2020-03-27 23:47:47 +00:00
// GetDevices returns a map of device uris and printer attributes
2019-03-15 15:20:02 +00:00
func (c *CUPSClient) GetDevices() (map[string]Attributes, error) {
req := NewRequest(OperationCupsGetDevices, 1)
2021-02-26 10:24:22 +00:00
resp, err := c.SendRequest(c.adapter.GetHttpUri("", nil), req, nil)
2019-03-15 15:20:02 +00:00
if err != nil {
return nil, err
}
printerNameMap := make(map[string]Attributes)
2020-03-05 15:30:33 +00:00
for _, printerAttributes := range resp.PrinterAttributes {
printerNameMap[printerAttributes[AttributeDeviceURI][0].Value.(string)] = printerAttributes
2019-03-15 15:20:02 +00:00
}
return printerNameMap, nil
}
2020-03-27 23:47:47 +00:00
// MoveJob moves a job to a other printer
2019-03-15 15:20:02 +00:00
func (c *CUPSClient) MoveJob(jobID int, destPrinter string) error {
req := NewRequest(OperationCupsMoveJob, 1)
req.OperationAttributes[AttributeJobURI] = c.getJobUri(jobID)
req.PrinterAttributes[AttributeJobPrinterURI] = c.getPrinterUri(destPrinter)
2019-03-15 15:20:02 +00:00
2021-02-26 10:24:22 +00:00
_, err := c.SendRequest(c.adapter.GetHttpUri("jobs", ""), req, nil)
2019-03-15 15:20:02 +00:00
return err
}
2020-03-27 23:47:47 +00:00
// MoveAllJob moves all job from a printer to a other printer
2019-03-15 15:20:02 +00:00
func (c *CUPSClient) MoveAllJob(srcPrinter, destPrinter string) error {
req := NewRequest(OperationCupsMoveJob, 1)
req.OperationAttributes[AttributePrinterURI] = c.getPrinterUri(srcPrinter)
req.PrinterAttributes[AttributeJobPrinterURI] = c.getPrinterUri(destPrinter)
2019-03-15 15:20:02 +00:00
2021-02-26 10:24:22 +00:00
_, err := c.SendRequest(c.adapter.GetHttpUri("jobs", ""), req, nil)
2019-03-15 15:20:02 +00:00
return err
}
2020-03-27 23:47:47 +00:00
// GetPPDs returns a map of ppd names and attributes
2019-03-15 15:20:02 +00:00
func (c *CUPSClient) GetPPDs() (map[string]Attributes, error) {
2020-03-09 11:21:57 +00:00
req := NewRequest(OperationCupsGetPPDs, 1)
2019-03-15 15:20:02 +00:00
2021-02-26 10:24:22 +00:00
resp, err := c.SendRequest(c.adapter.GetHttpUri("", nil), req, nil)
2019-03-15 15:20:02 +00:00
if err != nil {
return nil, err
}
ppdNameMap := make(map[string]Attributes)
2020-03-05 15:30:33 +00:00
for _, printerAttributes := range resp.PrinterAttributes {
ppdNameMap[printerAttributes[AttributePPDName][0].Value.(string)] = printerAttributes
2019-03-15 15:20:02 +00:00
}
return ppdNameMap, nil
}
2020-03-27 23:47:47 +00:00
// AcceptJobs lets a printer accept jobs again
func (c *CUPSClient) AcceptJobs(printer string) error {
2019-03-15 15:20:02 +00:00
req := NewRequest(OperationCupsAcceptJobs, 1)
req.OperationAttributes[AttributePrinterURI] = c.getPrinterUri(printer)
2019-03-15 15:20:02 +00:00
2021-02-26 10:24:22 +00:00
_, err := c.SendRequest(c.adapter.GetHttpUri("admin", ""), req, nil)
2019-03-15 15:20:02 +00:00
return err
}
2020-03-27 23:47:47 +00:00
// RejectJobs does not let a printer accept jobs
func (c *CUPSClient) RejectJobs(printer string) error {
2019-03-15 15:20:02 +00:00
req := NewRequest(OperationCupsRejectJobs, 1)
req.OperationAttributes[AttributePrinterURI] = c.getPrinterUri(printer)
2019-03-15 15:20:02 +00:00
2021-02-26 10:24:22 +00:00
_, err := c.SendRequest(c.adapter.GetHttpUri("admin", ""), req, nil)
2019-03-15 15:20:02 +00:00
return err
}
2020-03-27 23:47:47 +00:00
// AddPrinterToClass adds a printer to a class, if the class does not exists it will be crated
2019-03-15 15:20:02 +00:00
func (c *CUPSClient) AddPrinterToClass(class, printer string) error {
attributes, err := c.GetPrinterAttributes(class, []string{AttributeMemberURIs})
if err != nil && !IsNotExistsError(err) {
2019-03-15 15:20:02 +00:00
return err
}
memberURIList := make([]string, 0)
if !IsNotExistsError(err) {
for _, member := range attributes[AttributeMemberURIs] {
memberString := strings.Split(member.Value.(string), "/")
printerName := memberString[len(memberString)-1]
2019-03-15 15:20:02 +00:00
if printerName == printer {
return nil
}
2019-03-15 15:20:02 +00:00
memberURIList = append(memberURIList, member.Value.(string))
}
2019-03-15 15:20:02 +00:00
}
memberURIList = append(memberURIList, c.getPrinterUri(printer))
req := NewRequest(OperationCupsAddModifyClass, 1)
req.OperationAttributes[AttributePrinterURI] = c.getClassUri(class)
req.PrinterAttributes[AttributeMemberURIs] = memberURIList
2019-03-15 15:20:02 +00:00
2021-02-26 10:24:22 +00:00
_, err = c.SendRequest(c.adapter.GetHttpUri("admin", ""), req, nil)
2019-03-15 15:20:02 +00:00
return err
}
2020-03-27 23:47:47 +00:00
// DeletePrinterFromClass removes a printer from a class, if a class has no more printer it will be deleted
2019-03-15 15:20:02 +00:00
func (c *CUPSClient) DeletePrinterFromClass(class, printer string) error {
attributes, err := c.GetPrinterAttributes(class, []string{AttributeMemberURIs})
2019-03-15 15:20:02 +00:00
if err != nil {
return err
}
memberURIList := make([]string, 0)
for _, member := range attributes[AttributeMemberURIs] {
2019-03-15 15:20:02 +00:00
memberString := strings.Split(member.Value.(string), "/")
printerName := memberString[len(memberString)-1]
if printerName != printer {
memberURIList = append(memberURIList, member.Value.(string))
}
}
if len(memberURIList) == 0 {
return c.DeleteClass(class)
}
req := NewRequest(OperationCupsAddModifyClass, 1)
req.OperationAttributes[AttributePrinterURI] = c.getClassUri(class)
req.PrinterAttributes[AttributeMemberURIs] = memberURIList
2019-03-15 15:20:02 +00:00
2021-02-26 10:24:22 +00:00
_, err = c.SendRequest(c.adapter.GetHttpUri("admin", ""), req, nil)
2019-03-15 15:20:02 +00:00
return err
}
2020-03-27 23:47:47 +00:00
// DeleteClass deletes a class
2019-03-15 15:20:02 +00:00
func (c *CUPSClient) DeleteClass(class string) error {
req := NewRequest(OperationCupsDeleteClass, 1)
req.OperationAttributes[AttributePrinterURI] = c.getClassUri(class)
2019-03-15 15:20:02 +00:00
2021-02-26 10:24:22 +00:00
_, err := c.SendRequest(c.adapter.GetHttpUri("admin", ""), req, nil)
2019-03-15 15:20:02 +00:00
return err
}
2020-03-27 23:47:47 +00:00
// CreatePrinter creates a new printer
2020-03-09 11:47:23 +00:00
func (c *CUPSClient) CreatePrinter(name, deviceURI, ppd string, shared bool, errorPolicy string, information, location string) error {
2019-03-15 15:20:02 +00:00
req := NewRequest(OperationCupsAddModifyPrinter, 1)
req.OperationAttributes[AttributePrinterURI] = c.getPrinterUri(name)
req.OperationAttributes[AttributePPDName] = ppd
req.OperationAttributes[AttributePrinterIsShared] = shared
2020-08-07 13:22:02 +00:00
req.PrinterAttributes[AttributePrinterStateReasons] = "none"
req.PrinterAttributes[AttributeDeviceURI] = deviceURI
req.PrinterAttributes[AttributePrinterInfo] = information
req.PrinterAttributes[AttributePrinterLocation] = location
req.PrinterAttributes[AttributePrinterErrorPolicy] = string(errorPolicy)
2019-03-15 15:20:02 +00:00
2021-02-26 10:24:22 +00:00
_, err := c.SendRequest(c.adapter.GetHttpUri("admin", ""), req, nil)
2019-03-15 15:20:02 +00:00
return err
}
2020-03-27 23:47:47 +00:00
// SetPrinterPPD sets the ppd for a printer
2019-03-15 15:20:02 +00:00
func (c *CUPSClient) SetPrinterPPD(printer, ppd string) error {
req := NewRequest(OperationCupsAddModifyPrinter, 1)
req.OperationAttributes[AttributePrinterURI] = c.getPrinterUri(printer)
req.OperationAttributes[AttributePPDName] = ppd
2019-03-15 15:20:02 +00:00
2021-02-26 10:24:22 +00:00
_, err := c.SendRequest(c.adapter.GetHttpUri("admin", ""), req, nil)
2019-03-15 15:20:02 +00:00
return err
}
2020-03-27 23:47:47 +00:00
// SetPrinterDeviceURI sets the device uri for a printer
2019-03-15 15:20:02 +00:00
func (c *CUPSClient) SetPrinterDeviceURI(printer, deviceURI string) error {
req := NewRequest(OperationCupsAddModifyPrinter, 1)
req.OperationAttributes[AttributePrinterURI] = c.getPrinterUri(printer)
req.PrinterAttributes[AttributeDeviceURI] = deviceURI
2019-03-15 15:20:02 +00:00
2021-02-26 10:24:22 +00:00
_, err := c.SendRequest(c.adapter.GetHttpUri("admin", ""), req, nil)
2019-03-15 15:20:02 +00:00
return err
}
2020-03-27 23:47:47 +00:00
// SetPrinterIsShared shares or unshares a printer in the network
2019-03-15 15:20:02 +00:00
func (c *CUPSClient) SetPrinterIsShared(printer string, shared bool) error {
req := NewRequest(OperationCupsAddModifyPrinter, 1)
req.OperationAttributes[AttributePrinterURI] = c.getPrinterUri(printer)
req.OperationAttributes[AttributePrinterIsShared] = shared
2019-03-15 15:20:02 +00:00
2021-02-26 10:24:22 +00:00
_, err := c.SendRequest(c.adapter.GetHttpUri("admin", ""), req, nil)
2019-03-15 15:20:02 +00:00
return err
}
2020-03-27 23:47:47 +00:00
// SetPrinterErrorPolicy sets the error policy for a printer
2020-03-09 11:47:23 +00:00
func (c *CUPSClient) SetPrinterErrorPolicy(printer string, errorPolicy string) error {
2019-03-15 15:20:02 +00:00
req := NewRequest(OperationCupsAddModifyPrinter, 1)
req.OperationAttributes[AttributePrinterURI] = c.getPrinterUri(printer)
req.PrinterAttributes[AttributePrinterErrorPolicy] = string(errorPolicy)
2019-03-15 15:20:02 +00:00
2021-02-26 10:24:22 +00:00
_, err := c.SendRequest(c.adapter.GetHttpUri("admin", ""), req, nil)
2019-03-15 15:20:02 +00:00
return err
}
2020-03-27 23:47:47 +00:00
// SetPrinterInformation sets general printer information
2019-03-15 15:20:02 +00:00
func (c *CUPSClient) SetPrinterInformation(printer, information string) error {
req := NewRequest(OperationCupsAddModifyPrinter, 1)
req.OperationAttributes[AttributePrinterURI] = c.getPrinterUri(printer)
req.PrinterAttributes[AttributePrinterInfo] = information
2019-03-15 15:20:02 +00:00
2021-02-26 10:24:22 +00:00
_, err := c.SendRequest(c.adapter.GetHttpUri("admin", ""), req, nil)
2019-03-15 15:20:02 +00:00
return err
}
2020-03-27 23:47:47 +00:00
// SetPrinterLocation sets the printer location
2019-03-15 15:20:02 +00:00
func (c *CUPSClient) SetPrinterLocation(printer, location string) error {
req := NewRequest(OperationCupsAddModifyPrinter, 1)
req.OperationAttributes[AttributePrinterURI] = c.getPrinterUri(printer)
req.PrinterAttributes[AttributePrinterLocation] = location
2019-03-15 15:20:02 +00:00
2021-02-26 10:24:22 +00:00
_, err := c.SendRequest(c.adapter.GetHttpUri("admin", ""), req, nil)
2019-03-15 15:20:02 +00:00
return err
}
2020-03-27 23:47:47 +00:00
// DeletePrinter deletes a printer
2019-03-15 15:20:02 +00:00
func (c *CUPSClient) DeletePrinter(printer string) error {
req := NewRequest(OperationCupsDeletePrinter, 1)
req.OperationAttributes[AttributePrinterURI] = c.getPrinterUri(printer)
2019-03-15 15:20:02 +00:00
2021-02-26 10:24:22 +00:00
_, err := c.SendRequest(c.adapter.GetHttpUri("admin", ""), req, nil)
2019-03-15 15:20:02 +00:00
return err
}
2020-03-27 23:47:47 +00:00
// GetPrinters returns a map of printer names and attributes
2019-03-15 15:20:02 +00:00
func (c *CUPSClient) GetPrinters(attributes []string) (map[string]Attributes, error) {
req := NewRequest(OperationCupsGetPrinters, 1)
if attributes == nil {
req.OperationAttributes[AttributeRequestedAttributes] = DefaultPrinterAttributes
2019-03-15 15:20:02 +00:00
} else {
req.OperationAttributes[AttributeRequestedAttributes] = append(attributes, AttributePrinterName)
2019-03-15 15:20:02 +00:00
}
2021-02-26 10:24:22 +00:00
resp, err := c.SendRequest(c.adapter.GetHttpUri("", nil), req, nil)
2019-03-15 15:20:02 +00:00
if err != nil {
return nil, err
}
printerNameMap := make(map[string]Attributes)
2020-03-05 15:30:33 +00:00
for _, printerAttributes := range resp.PrinterAttributes {
printerNameMap[printerAttributes[AttributePrinterName][0].Value.(string)] = printerAttributes
2019-03-15 15:20:02 +00:00
}
return printerNameMap, nil
}
2020-03-27 23:47:47 +00:00
// GetClasses returns a map of class names and attributes
2019-03-15 15:20:02 +00:00
func (c *CUPSClient) GetClasses(attributes []string) (map[string]Attributes, error) {
req := NewRequest(OperationCupsGetClasses, 1)
if attributes == nil {
req.OperationAttributes[AttributeRequestedAttributes] = DefaultClassAttributes
2019-03-15 15:20:02 +00:00
} else {
req.OperationAttributes[AttributeRequestedAttributes] = append(attributes, AttributePrinterName)
2019-03-15 15:20:02 +00:00
}
2021-02-26 10:24:22 +00:00
resp, err := c.SendRequest(c.adapter.GetHttpUri("", nil), req, nil)
2019-03-15 15:20:02 +00:00
if err != nil {
return nil, err
}
printerNameMap := make(map[string]Attributes)
2020-03-05 15:30:33 +00:00
for _, printerAttributes := range resp.PrinterAttributes {
printerNameMap[printerAttributes[AttributePrinterName][0].Value.(string)] = printerAttributes
2019-03-15 15:20:02 +00:00
}
return printerNameMap, nil
}
// PrintTestPage prints a test page of type application/vnd.cups-pdf-banner
func (c *CUPSClient) PrintTestPage(printer string) (int, error) {
testPage := new(bytes.Buffer)
testPage.WriteString("#PDF-BANNER\n")
testPage.WriteString("Template default-testpage.pdf\n")
testPage.WriteString("Show printer-name printer-info printer-location printer-make-and-model printer-driver-name")
testPage.WriteString("printer-driver-version paper-size imageable-area job-id options time-at-creation")
testPage.WriteString("time-at-processing\n\n")
return c.PrintDocuments([]Document{
{
Document: testPage,
Name: "Test Page",
Size: testPage.Len(),
MimeType: MimeTypePostscript,
},
}, printer, map[string]interface{}{
AttributeJobName: "Test Page",
})
}