mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2025-12-05 21:15:38 -05:00
cups: add comprehensive CUPs setting page
- Add printers - Delete printers - Use polkit APIs as fallback on auth errors - Fix ref system to conditionally subscribe to cups when wanted
This commit is contained in:
@@ -34,12 +34,16 @@ packages:
|
|||||||
outpkg: mocks_network
|
outpkg: mocks_network
|
||||||
interfaces:
|
interfaces:
|
||||||
Backend:
|
Backend:
|
||||||
github.com/AvengeMedia/danklinux/internal/server/cups:
|
github.com/AvengeMedia/DankMaterialShell/core/internal/server/cups:
|
||||||
config:
|
config:
|
||||||
dir: "internal/mocks/cups"
|
dir: "internal/mocks/cups"
|
||||||
outpkg: mocks_cups
|
outpkg: mocks_cups
|
||||||
interfaces:
|
interfaces:
|
||||||
CUPSClientInterface:
|
CUPSClientInterface:
|
||||||
|
PkHelper:
|
||||||
|
config:
|
||||||
|
dir: "internal/mocks/cups_pkhelper"
|
||||||
|
outpkg: mocks_cups_pkhelper
|
||||||
github.com/AvengeMedia/DankMaterialShell/core/internal/server/evdev:
|
github.com/AvengeMedia/DankMaterialShell/core/internal/server/evdev:
|
||||||
config:
|
config:
|
||||||
dir: "internal/mocks/evdev"
|
dir: "internal/mocks/evdev"
|
||||||
|
|||||||
@@ -140,6 +140,7 @@ func runVersion(cmd *cobra.Command, args []string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func startDebugServer() error {
|
func startDebugServer() error {
|
||||||
|
server.CLIVersion = Version
|
||||||
return server.Start(true)
|
return server.Start(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -298,7 +298,8 @@ func ensureGreetdEnabled() error {
|
|||||||
fmt.Println(" ✓ Unmasked greetd")
|
fmt.Println(" ✓ Unmasked greetd")
|
||||||
}
|
}
|
||||||
|
|
||||||
if state.EnabledState == "disabled" || state.EnabledState == "masked" || state.EnabledState == "masked-runtime" {
|
switch state.EnabledState {
|
||||||
|
case "disabled", "masked", "masked-runtime":
|
||||||
fmt.Println(" Enabling greetd service...")
|
fmt.Println(" Enabling greetd service...")
|
||||||
enableCmd := exec.Command("sudo", "systemctl", "enable", "greetd")
|
enableCmd := exec.Command("sudo", "systemctl", "enable", "greetd")
|
||||||
enableCmd.Stdout = os.Stdout
|
enableCmd.Stdout = os.Stdout
|
||||||
@@ -307,9 +308,9 @@ func ensureGreetdEnabled() error {
|
|||||||
return fmt.Errorf("failed to enable greetd: %w", err)
|
return fmt.Errorf("failed to enable greetd: %w", err)
|
||||||
}
|
}
|
||||||
fmt.Println(" ✓ Enabled greetd service")
|
fmt.Println(" ✓ Enabled greetd service")
|
||||||
} else if state.EnabledState == "enabled" || state.EnabledState == "enabled-runtime" {
|
case "enabled", "enabled-runtime":
|
||||||
fmt.Println(" ✓ greetd is already enabled")
|
fmt.Println(" ✓ greetd is already enabled")
|
||||||
} else {
|
default:
|
||||||
fmt.Printf(" ℹ greetd is in state '%s' (should work, no action needed)\n", state.EnabledState)
|
fmt.Printf(" ℹ greetd is in state '%s' (should work, no action needed)\n", state.EnabledState)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -383,6 +383,7 @@ func runShellDaemon(session bool) {
|
|||||||
errChan <- fmt.Errorf("server panic: %v", r)
|
errChan <- fmt.Errorf("server panic: %v", r)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
server.CLIVersion = Version
|
||||||
if err := server.Start(false); err != nil {
|
if err := server.Start(false); err != nil {
|
||||||
errChan <- fmt.Errorf("server error: %w", err)
|
errChan <- fmt.Errorf("server error: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
core/internal/config/embedded/testpage.pdf
Normal file
BIN
core/internal/config/embedded/testpage.pdf
Normal file
Binary file not shown.
6
core/internal/config/testpage.go
Normal file
6
core/internal/config/testpage.go
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import _ "embed"
|
||||||
|
|
||||||
|
//go:embed embedded/testpage.pdf
|
||||||
|
var TestPage string
|
||||||
@@ -22,6 +22,99 @@ func (_m *MockCUPSClientInterface) EXPECT() *MockCUPSClientInterface_Expecter {
|
|||||||
return &MockCUPSClientInterface_Expecter{mock: &_m.Mock}
|
return &MockCUPSClientInterface_Expecter{mock: &_m.Mock}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AcceptJobs provides a mock function with given fields: printer
|
||||||
|
func (_m *MockCUPSClientInterface) AcceptJobs(printer string) error {
|
||||||
|
ret := _m.Called(printer)
|
||||||
|
|
||||||
|
if len(ret) == 0 {
|
||||||
|
panic("no return value specified for AcceptJobs")
|
||||||
|
}
|
||||||
|
|
||||||
|
var r0 error
|
||||||
|
if rf, ok := ret.Get(0).(func(string) error); ok {
|
||||||
|
r0 = rf(printer)
|
||||||
|
} else {
|
||||||
|
r0 = ret.Error(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
||||||
|
|
||||||
|
// MockCUPSClientInterface_AcceptJobs_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AcceptJobs'
|
||||||
|
type MockCUPSClientInterface_AcceptJobs_Call struct {
|
||||||
|
*mock.Call
|
||||||
|
}
|
||||||
|
|
||||||
|
// AcceptJobs is a helper method to define mock.On call
|
||||||
|
// - printer string
|
||||||
|
func (_e *MockCUPSClientInterface_Expecter) AcceptJobs(printer interface{}) *MockCUPSClientInterface_AcceptJobs_Call {
|
||||||
|
return &MockCUPSClientInterface_AcceptJobs_Call{Call: _e.mock.On("AcceptJobs", printer)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockCUPSClientInterface_AcceptJobs_Call) Run(run func(printer string)) *MockCUPSClientInterface_AcceptJobs_Call {
|
||||||
|
_c.Call.Run(func(args mock.Arguments) {
|
||||||
|
run(args[0].(string))
|
||||||
|
})
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockCUPSClientInterface_AcceptJobs_Call) Return(_a0 error) *MockCUPSClientInterface_AcceptJobs_Call {
|
||||||
|
_c.Call.Return(_a0)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockCUPSClientInterface_AcceptJobs_Call) RunAndReturn(run func(string) error) *MockCUPSClientInterface_AcceptJobs_Call {
|
||||||
|
_c.Call.Return(run)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddPrinterToClass provides a mock function with given fields: class, printer
|
||||||
|
func (_m *MockCUPSClientInterface) AddPrinterToClass(class string, printer string) error {
|
||||||
|
ret := _m.Called(class, printer)
|
||||||
|
|
||||||
|
if len(ret) == 0 {
|
||||||
|
panic("no return value specified for AddPrinterToClass")
|
||||||
|
}
|
||||||
|
|
||||||
|
var r0 error
|
||||||
|
if rf, ok := ret.Get(0).(func(string, string) error); ok {
|
||||||
|
r0 = rf(class, printer)
|
||||||
|
} else {
|
||||||
|
r0 = ret.Error(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
||||||
|
|
||||||
|
// MockCUPSClientInterface_AddPrinterToClass_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AddPrinterToClass'
|
||||||
|
type MockCUPSClientInterface_AddPrinterToClass_Call struct {
|
||||||
|
*mock.Call
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddPrinterToClass is a helper method to define mock.On call
|
||||||
|
// - class string
|
||||||
|
// - printer string
|
||||||
|
func (_e *MockCUPSClientInterface_Expecter) AddPrinterToClass(class interface{}, printer interface{}) *MockCUPSClientInterface_AddPrinterToClass_Call {
|
||||||
|
return &MockCUPSClientInterface_AddPrinterToClass_Call{Call: _e.mock.On("AddPrinterToClass", class, printer)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockCUPSClientInterface_AddPrinterToClass_Call) Run(run func(class string, printer string)) *MockCUPSClientInterface_AddPrinterToClass_Call {
|
||||||
|
_c.Call.Run(func(args mock.Arguments) {
|
||||||
|
run(args[0].(string), args[1].(string))
|
||||||
|
})
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockCUPSClientInterface_AddPrinterToClass_Call) Return(_a0 error) *MockCUPSClientInterface_AddPrinterToClass_Call {
|
||||||
|
_c.Call.Return(_a0)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockCUPSClientInterface_AddPrinterToClass_Call) RunAndReturn(run func(string, string) error) *MockCUPSClientInterface_AddPrinterToClass_Call {
|
||||||
|
_c.Call.Return(run)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
// CancelAllJob provides a mock function with given fields: printer, purge
|
// CancelAllJob provides a mock function with given fields: printer, purge
|
||||||
func (_m *MockCUPSClientInterface) CancelAllJob(printer string, purge bool) error {
|
func (_m *MockCUPSClientInterface) CancelAllJob(printer string, purge bool) error {
|
||||||
ret := _m.Called(printer, purge)
|
ret := _m.Called(printer, purge)
|
||||||
@@ -116,6 +209,312 @@ func (_c *MockCUPSClientInterface_CancelJob_Call) RunAndReturn(run func(int, boo
|
|||||||
return _c
|
return _c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreatePrinter provides a mock function with given fields: name, deviceURI, ppd, shared, errorPolicy, information, location
|
||||||
|
func (_m *MockCUPSClientInterface) CreatePrinter(name string, deviceURI string, ppd string, shared bool, errorPolicy string, information string, location string) error {
|
||||||
|
ret := _m.Called(name, deviceURI, ppd, shared, errorPolicy, information, location)
|
||||||
|
|
||||||
|
if len(ret) == 0 {
|
||||||
|
panic("no return value specified for CreatePrinter")
|
||||||
|
}
|
||||||
|
|
||||||
|
var r0 error
|
||||||
|
if rf, ok := ret.Get(0).(func(string, string, string, bool, string, string, string) error); ok {
|
||||||
|
r0 = rf(name, deviceURI, ppd, shared, errorPolicy, information, location)
|
||||||
|
} else {
|
||||||
|
r0 = ret.Error(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
||||||
|
|
||||||
|
// MockCUPSClientInterface_CreatePrinter_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreatePrinter'
|
||||||
|
type MockCUPSClientInterface_CreatePrinter_Call struct {
|
||||||
|
*mock.Call
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreatePrinter is a helper method to define mock.On call
|
||||||
|
// - name string
|
||||||
|
// - deviceURI string
|
||||||
|
// - ppd string
|
||||||
|
// - shared bool
|
||||||
|
// - errorPolicy string
|
||||||
|
// - information string
|
||||||
|
// - location string
|
||||||
|
func (_e *MockCUPSClientInterface_Expecter) CreatePrinter(name interface{}, deviceURI interface{}, ppd interface{}, shared interface{}, errorPolicy interface{}, information interface{}, location interface{}) *MockCUPSClientInterface_CreatePrinter_Call {
|
||||||
|
return &MockCUPSClientInterface_CreatePrinter_Call{Call: _e.mock.On("CreatePrinter", name, deviceURI, ppd, shared, errorPolicy, information, location)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockCUPSClientInterface_CreatePrinter_Call) Run(run func(name string, deviceURI string, ppd string, shared bool, errorPolicy string, information string, location string)) *MockCUPSClientInterface_CreatePrinter_Call {
|
||||||
|
_c.Call.Run(func(args mock.Arguments) {
|
||||||
|
run(args[0].(string), args[1].(string), args[2].(string), args[3].(bool), args[4].(string), args[5].(string), args[6].(string))
|
||||||
|
})
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockCUPSClientInterface_CreatePrinter_Call) Return(_a0 error) *MockCUPSClientInterface_CreatePrinter_Call {
|
||||||
|
_c.Call.Return(_a0)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockCUPSClientInterface_CreatePrinter_Call) RunAndReturn(run func(string, string, string, bool, string, string, string) error) *MockCUPSClientInterface_CreatePrinter_Call {
|
||||||
|
_c.Call.Return(run)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteClass provides a mock function with given fields: class
|
||||||
|
func (_m *MockCUPSClientInterface) DeleteClass(class string) error {
|
||||||
|
ret := _m.Called(class)
|
||||||
|
|
||||||
|
if len(ret) == 0 {
|
||||||
|
panic("no return value specified for DeleteClass")
|
||||||
|
}
|
||||||
|
|
||||||
|
var r0 error
|
||||||
|
if rf, ok := ret.Get(0).(func(string) error); ok {
|
||||||
|
r0 = rf(class)
|
||||||
|
} else {
|
||||||
|
r0 = ret.Error(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
||||||
|
|
||||||
|
// MockCUPSClientInterface_DeleteClass_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeleteClass'
|
||||||
|
type MockCUPSClientInterface_DeleteClass_Call struct {
|
||||||
|
*mock.Call
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteClass is a helper method to define mock.On call
|
||||||
|
// - class string
|
||||||
|
func (_e *MockCUPSClientInterface_Expecter) DeleteClass(class interface{}) *MockCUPSClientInterface_DeleteClass_Call {
|
||||||
|
return &MockCUPSClientInterface_DeleteClass_Call{Call: _e.mock.On("DeleteClass", class)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockCUPSClientInterface_DeleteClass_Call) Run(run func(class string)) *MockCUPSClientInterface_DeleteClass_Call {
|
||||||
|
_c.Call.Run(func(args mock.Arguments) {
|
||||||
|
run(args[0].(string))
|
||||||
|
})
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockCUPSClientInterface_DeleteClass_Call) Return(_a0 error) *MockCUPSClientInterface_DeleteClass_Call {
|
||||||
|
_c.Call.Return(_a0)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockCUPSClientInterface_DeleteClass_Call) RunAndReturn(run func(string) error) *MockCUPSClientInterface_DeleteClass_Call {
|
||||||
|
_c.Call.Return(run)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeletePrinter provides a mock function with given fields: printer
|
||||||
|
func (_m *MockCUPSClientInterface) DeletePrinter(printer string) error {
|
||||||
|
ret := _m.Called(printer)
|
||||||
|
|
||||||
|
if len(ret) == 0 {
|
||||||
|
panic("no return value specified for DeletePrinter")
|
||||||
|
}
|
||||||
|
|
||||||
|
var r0 error
|
||||||
|
if rf, ok := ret.Get(0).(func(string) error); ok {
|
||||||
|
r0 = rf(printer)
|
||||||
|
} else {
|
||||||
|
r0 = ret.Error(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
||||||
|
|
||||||
|
// MockCUPSClientInterface_DeletePrinter_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeletePrinter'
|
||||||
|
type MockCUPSClientInterface_DeletePrinter_Call struct {
|
||||||
|
*mock.Call
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeletePrinter is a helper method to define mock.On call
|
||||||
|
// - printer string
|
||||||
|
func (_e *MockCUPSClientInterface_Expecter) DeletePrinter(printer interface{}) *MockCUPSClientInterface_DeletePrinter_Call {
|
||||||
|
return &MockCUPSClientInterface_DeletePrinter_Call{Call: _e.mock.On("DeletePrinter", printer)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockCUPSClientInterface_DeletePrinter_Call) Run(run func(printer string)) *MockCUPSClientInterface_DeletePrinter_Call {
|
||||||
|
_c.Call.Run(func(args mock.Arguments) {
|
||||||
|
run(args[0].(string))
|
||||||
|
})
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockCUPSClientInterface_DeletePrinter_Call) Return(_a0 error) *MockCUPSClientInterface_DeletePrinter_Call {
|
||||||
|
_c.Call.Return(_a0)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockCUPSClientInterface_DeletePrinter_Call) RunAndReturn(run func(string) error) *MockCUPSClientInterface_DeletePrinter_Call {
|
||||||
|
_c.Call.Return(run)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeletePrinterFromClass provides a mock function with given fields: class, printer
|
||||||
|
func (_m *MockCUPSClientInterface) DeletePrinterFromClass(class string, printer string) error {
|
||||||
|
ret := _m.Called(class, printer)
|
||||||
|
|
||||||
|
if len(ret) == 0 {
|
||||||
|
panic("no return value specified for DeletePrinterFromClass")
|
||||||
|
}
|
||||||
|
|
||||||
|
var r0 error
|
||||||
|
if rf, ok := ret.Get(0).(func(string, string) error); ok {
|
||||||
|
r0 = rf(class, printer)
|
||||||
|
} else {
|
||||||
|
r0 = ret.Error(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
||||||
|
|
||||||
|
// MockCUPSClientInterface_DeletePrinterFromClass_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeletePrinterFromClass'
|
||||||
|
type MockCUPSClientInterface_DeletePrinterFromClass_Call struct {
|
||||||
|
*mock.Call
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeletePrinterFromClass is a helper method to define mock.On call
|
||||||
|
// - class string
|
||||||
|
// - printer string
|
||||||
|
func (_e *MockCUPSClientInterface_Expecter) DeletePrinterFromClass(class interface{}, printer interface{}) *MockCUPSClientInterface_DeletePrinterFromClass_Call {
|
||||||
|
return &MockCUPSClientInterface_DeletePrinterFromClass_Call{Call: _e.mock.On("DeletePrinterFromClass", class, printer)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockCUPSClientInterface_DeletePrinterFromClass_Call) Run(run func(class string, printer string)) *MockCUPSClientInterface_DeletePrinterFromClass_Call {
|
||||||
|
_c.Call.Run(func(args mock.Arguments) {
|
||||||
|
run(args[0].(string), args[1].(string))
|
||||||
|
})
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockCUPSClientInterface_DeletePrinterFromClass_Call) Return(_a0 error) *MockCUPSClientInterface_DeletePrinterFromClass_Call {
|
||||||
|
_c.Call.Return(_a0)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockCUPSClientInterface_DeletePrinterFromClass_Call) RunAndReturn(run func(string, string) error) *MockCUPSClientInterface_DeletePrinterFromClass_Call {
|
||||||
|
_c.Call.Return(run)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetClasses provides a mock function with given fields: attributes
|
||||||
|
func (_m *MockCUPSClientInterface) GetClasses(attributes []string) (map[string]ipp.Attributes, error) {
|
||||||
|
ret := _m.Called(attributes)
|
||||||
|
|
||||||
|
if len(ret) == 0 {
|
||||||
|
panic("no return value specified for GetClasses")
|
||||||
|
}
|
||||||
|
|
||||||
|
var r0 map[string]ipp.Attributes
|
||||||
|
var r1 error
|
||||||
|
if rf, ok := ret.Get(0).(func([]string) (map[string]ipp.Attributes, error)); ok {
|
||||||
|
return rf(attributes)
|
||||||
|
}
|
||||||
|
if rf, ok := ret.Get(0).(func([]string) map[string]ipp.Attributes); ok {
|
||||||
|
r0 = rf(attributes)
|
||||||
|
} else {
|
||||||
|
if ret.Get(0) != nil {
|
||||||
|
r0 = ret.Get(0).(map[string]ipp.Attributes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if rf, ok := ret.Get(1).(func([]string) error); ok {
|
||||||
|
r1 = rf(attributes)
|
||||||
|
} else {
|
||||||
|
r1 = ret.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0, r1
|
||||||
|
}
|
||||||
|
|
||||||
|
// MockCUPSClientInterface_GetClasses_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetClasses'
|
||||||
|
type MockCUPSClientInterface_GetClasses_Call struct {
|
||||||
|
*mock.Call
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetClasses is a helper method to define mock.On call
|
||||||
|
// - attributes []string
|
||||||
|
func (_e *MockCUPSClientInterface_Expecter) GetClasses(attributes interface{}) *MockCUPSClientInterface_GetClasses_Call {
|
||||||
|
return &MockCUPSClientInterface_GetClasses_Call{Call: _e.mock.On("GetClasses", attributes)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockCUPSClientInterface_GetClasses_Call) Run(run func(attributes []string)) *MockCUPSClientInterface_GetClasses_Call {
|
||||||
|
_c.Call.Run(func(args mock.Arguments) {
|
||||||
|
run(args[0].([]string))
|
||||||
|
})
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockCUPSClientInterface_GetClasses_Call) Return(_a0 map[string]ipp.Attributes, _a1 error) *MockCUPSClientInterface_GetClasses_Call {
|
||||||
|
_c.Call.Return(_a0, _a1)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockCUPSClientInterface_GetClasses_Call) RunAndReturn(run func([]string) (map[string]ipp.Attributes, error)) *MockCUPSClientInterface_GetClasses_Call {
|
||||||
|
_c.Call.Return(run)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDevices provides a mock function with no fields
|
||||||
|
func (_m *MockCUPSClientInterface) GetDevices() (map[string]ipp.Attributes, error) {
|
||||||
|
ret := _m.Called()
|
||||||
|
|
||||||
|
if len(ret) == 0 {
|
||||||
|
panic("no return value specified for GetDevices")
|
||||||
|
}
|
||||||
|
|
||||||
|
var r0 map[string]ipp.Attributes
|
||||||
|
var r1 error
|
||||||
|
if rf, ok := ret.Get(0).(func() (map[string]ipp.Attributes, error)); ok {
|
||||||
|
return rf()
|
||||||
|
}
|
||||||
|
if rf, ok := ret.Get(0).(func() map[string]ipp.Attributes); ok {
|
||||||
|
r0 = rf()
|
||||||
|
} else {
|
||||||
|
if ret.Get(0) != nil {
|
||||||
|
r0 = ret.Get(0).(map[string]ipp.Attributes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if rf, ok := ret.Get(1).(func() error); ok {
|
||||||
|
r1 = rf()
|
||||||
|
} else {
|
||||||
|
r1 = ret.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0, r1
|
||||||
|
}
|
||||||
|
|
||||||
|
// MockCUPSClientInterface_GetDevices_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetDevices'
|
||||||
|
type MockCUPSClientInterface_GetDevices_Call struct {
|
||||||
|
*mock.Call
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDevices is a helper method to define mock.On call
|
||||||
|
func (_e *MockCUPSClientInterface_Expecter) GetDevices() *MockCUPSClientInterface_GetDevices_Call {
|
||||||
|
return &MockCUPSClientInterface_GetDevices_Call{Call: _e.mock.On("GetDevices")}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockCUPSClientInterface_GetDevices_Call) Run(run func()) *MockCUPSClientInterface_GetDevices_Call {
|
||||||
|
_c.Call.Run(func(args mock.Arguments) {
|
||||||
|
run()
|
||||||
|
})
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockCUPSClientInterface_GetDevices_Call) Return(_a0 map[string]ipp.Attributes, _a1 error) *MockCUPSClientInterface_GetDevices_Call {
|
||||||
|
_c.Call.Return(_a0, _a1)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockCUPSClientInterface_GetDevices_Call) RunAndReturn(run func() (map[string]ipp.Attributes, error)) *MockCUPSClientInterface_GetDevices_Call {
|
||||||
|
_c.Call.Return(run)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
// GetJobs provides a mock function with given fields: printer, class, whichJobs, myJobs, firstJobId, limit, attributes
|
// GetJobs provides a mock function with given fields: printer, class, whichJobs, myJobs, firstJobId, limit, attributes
|
||||||
func (_m *MockCUPSClientInterface) GetJobs(printer string, class string, whichJobs string, myJobs bool, firstJobId int, limit int, attributes []string) (map[int]ipp.Attributes, error) {
|
func (_m *MockCUPSClientInterface) GetJobs(printer string, class string, whichJobs string, myJobs bool, firstJobId int, limit int, attributes []string) (map[int]ipp.Attributes, error) {
|
||||||
ret := _m.Called(printer, class, whichJobs, myJobs, firstJobId, limit, attributes)
|
ret := _m.Called(printer, class, whichJobs, myJobs, firstJobId, limit, attributes)
|
||||||
@@ -180,6 +579,63 @@ func (_c *MockCUPSClientInterface_GetJobs_Call) RunAndReturn(run func(string, st
|
|||||||
return _c
|
return _c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetPPDs provides a mock function with no fields
|
||||||
|
func (_m *MockCUPSClientInterface) GetPPDs() (map[string]ipp.Attributes, error) {
|
||||||
|
ret := _m.Called()
|
||||||
|
|
||||||
|
if len(ret) == 0 {
|
||||||
|
panic("no return value specified for GetPPDs")
|
||||||
|
}
|
||||||
|
|
||||||
|
var r0 map[string]ipp.Attributes
|
||||||
|
var r1 error
|
||||||
|
if rf, ok := ret.Get(0).(func() (map[string]ipp.Attributes, error)); ok {
|
||||||
|
return rf()
|
||||||
|
}
|
||||||
|
if rf, ok := ret.Get(0).(func() map[string]ipp.Attributes); ok {
|
||||||
|
r0 = rf()
|
||||||
|
} else {
|
||||||
|
if ret.Get(0) != nil {
|
||||||
|
r0 = ret.Get(0).(map[string]ipp.Attributes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if rf, ok := ret.Get(1).(func() error); ok {
|
||||||
|
r1 = rf()
|
||||||
|
} else {
|
||||||
|
r1 = ret.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0, r1
|
||||||
|
}
|
||||||
|
|
||||||
|
// MockCUPSClientInterface_GetPPDs_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetPPDs'
|
||||||
|
type MockCUPSClientInterface_GetPPDs_Call struct {
|
||||||
|
*mock.Call
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPPDs is a helper method to define mock.On call
|
||||||
|
func (_e *MockCUPSClientInterface_Expecter) GetPPDs() *MockCUPSClientInterface_GetPPDs_Call {
|
||||||
|
return &MockCUPSClientInterface_GetPPDs_Call{Call: _e.mock.On("GetPPDs")}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockCUPSClientInterface_GetPPDs_Call) Run(run func()) *MockCUPSClientInterface_GetPPDs_Call {
|
||||||
|
_c.Call.Run(func(args mock.Arguments) {
|
||||||
|
run()
|
||||||
|
})
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockCUPSClientInterface_GetPPDs_Call) Return(_a0 map[string]ipp.Attributes, _a1 error) *MockCUPSClientInterface_GetPPDs_Call {
|
||||||
|
_c.Call.Return(_a0, _a1)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockCUPSClientInterface_GetPPDs_Call) RunAndReturn(run func() (map[string]ipp.Attributes, error)) *MockCUPSClientInterface_GetPPDs_Call {
|
||||||
|
_c.Call.Return(run)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
// GetPrinters provides a mock function with given fields: attributes
|
// GetPrinters provides a mock function with given fields: attributes
|
||||||
func (_m *MockCUPSClientInterface) GetPrinters(attributes []string) (map[string]ipp.Attributes, error) {
|
func (_m *MockCUPSClientInterface) GetPrinters(attributes []string) (map[string]ipp.Attributes, error) {
|
||||||
ret := _m.Called(attributes)
|
ret := _m.Called(attributes)
|
||||||
@@ -238,6 +694,100 @@ func (_c *MockCUPSClientInterface_GetPrinters_Call) RunAndReturn(run func([]stri
|
|||||||
return _c
|
return _c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HoldJobUntil provides a mock function with given fields: jobID, holdUntil
|
||||||
|
func (_m *MockCUPSClientInterface) HoldJobUntil(jobID int, holdUntil string) error {
|
||||||
|
ret := _m.Called(jobID, holdUntil)
|
||||||
|
|
||||||
|
if len(ret) == 0 {
|
||||||
|
panic("no return value specified for HoldJobUntil")
|
||||||
|
}
|
||||||
|
|
||||||
|
var r0 error
|
||||||
|
if rf, ok := ret.Get(0).(func(int, string) error); ok {
|
||||||
|
r0 = rf(jobID, holdUntil)
|
||||||
|
} else {
|
||||||
|
r0 = ret.Error(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
||||||
|
|
||||||
|
// MockCUPSClientInterface_HoldJobUntil_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'HoldJobUntil'
|
||||||
|
type MockCUPSClientInterface_HoldJobUntil_Call struct {
|
||||||
|
*mock.Call
|
||||||
|
}
|
||||||
|
|
||||||
|
// HoldJobUntil is a helper method to define mock.On call
|
||||||
|
// - jobID int
|
||||||
|
// - holdUntil string
|
||||||
|
func (_e *MockCUPSClientInterface_Expecter) HoldJobUntil(jobID interface{}, holdUntil interface{}) *MockCUPSClientInterface_HoldJobUntil_Call {
|
||||||
|
return &MockCUPSClientInterface_HoldJobUntil_Call{Call: _e.mock.On("HoldJobUntil", jobID, holdUntil)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockCUPSClientInterface_HoldJobUntil_Call) Run(run func(jobID int, holdUntil string)) *MockCUPSClientInterface_HoldJobUntil_Call {
|
||||||
|
_c.Call.Run(func(args mock.Arguments) {
|
||||||
|
run(args[0].(int), args[1].(string))
|
||||||
|
})
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockCUPSClientInterface_HoldJobUntil_Call) Return(_a0 error) *MockCUPSClientInterface_HoldJobUntil_Call {
|
||||||
|
_c.Call.Return(_a0)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockCUPSClientInterface_HoldJobUntil_Call) RunAndReturn(run func(int, string) error) *MockCUPSClientInterface_HoldJobUntil_Call {
|
||||||
|
_c.Call.Return(run)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
// MoveJob provides a mock function with given fields: jobID, destPrinter
|
||||||
|
func (_m *MockCUPSClientInterface) MoveJob(jobID int, destPrinter string) error {
|
||||||
|
ret := _m.Called(jobID, destPrinter)
|
||||||
|
|
||||||
|
if len(ret) == 0 {
|
||||||
|
panic("no return value specified for MoveJob")
|
||||||
|
}
|
||||||
|
|
||||||
|
var r0 error
|
||||||
|
if rf, ok := ret.Get(0).(func(int, string) error); ok {
|
||||||
|
r0 = rf(jobID, destPrinter)
|
||||||
|
} else {
|
||||||
|
r0 = ret.Error(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
||||||
|
|
||||||
|
// MockCUPSClientInterface_MoveJob_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'MoveJob'
|
||||||
|
type MockCUPSClientInterface_MoveJob_Call struct {
|
||||||
|
*mock.Call
|
||||||
|
}
|
||||||
|
|
||||||
|
// MoveJob is a helper method to define mock.On call
|
||||||
|
// - jobID int
|
||||||
|
// - destPrinter string
|
||||||
|
func (_e *MockCUPSClientInterface_Expecter) MoveJob(jobID interface{}, destPrinter interface{}) *MockCUPSClientInterface_MoveJob_Call {
|
||||||
|
return &MockCUPSClientInterface_MoveJob_Call{Call: _e.mock.On("MoveJob", jobID, destPrinter)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockCUPSClientInterface_MoveJob_Call) Run(run func(jobID int, destPrinter string)) *MockCUPSClientInterface_MoveJob_Call {
|
||||||
|
_c.Call.Run(func(args mock.Arguments) {
|
||||||
|
run(args[0].(int), args[1].(string))
|
||||||
|
})
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockCUPSClientInterface_MoveJob_Call) Return(_a0 error) *MockCUPSClientInterface_MoveJob_Call {
|
||||||
|
_c.Call.Return(_a0)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockCUPSClientInterface_MoveJob_Call) RunAndReturn(run func(int, string) error) *MockCUPSClientInterface_MoveJob_Call {
|
||||||
|
_c.Call.Return(run)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
// PausePrinter provides a mock function with given fields: printer
|
// PausePrinter provides a mock function with given fields: printer
|
||||||
func (_m *MockCUPSClientInterface) PausePrinter(printer string) error {
|
func (_m *MockCUPSClientInterface) PausePrinter(printer string) error {
|
||||||
ret := _m.Called(printer)
|
ret := _m.Called(printer)
|
||||||
@@ -284,6 +834,156 @@ func (_c *MockCUPSClientInterface_PausePrinter_Call) RunAndReturn(run func(strin
|
|||||||
return _c
|
return _c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PrintTestPage provides a mock function with given fields: printer, testPageData, size
|
||||||
|
func (_m *MockCUPSClientInterface) PrintTestPage(printer string, testPageData io.Reader, size int) (int, error) {
|
||||||
|
ret := _m.Called(printer, testPageData, size)
|
||||||
|
|
||||||
|
if len(ret) == 0 {
|
||||||
|
panic("no return value specified for PrintTestPage")
|
||||||
|
}
|
||||||
|
|
||||||
|
var r0 int
|
||||||
|
var r1 error
|
||||||
|
if rf, ok := ret.Get(0).(func(string, io.Reader, int) (int, error)); ok {
|
||||||
|
return rf(printer, testPageData, size)
|
||||||
|
}
|
||||||
|
if rf, ok := ret.Get(0).(func(string, io.Reader, int) int); ok {
|
||||||
|
r0 = rf(printer, testPageData, size)
|
||||||
|
} else {
|
||||||
|
r0 = ret.Get(0).(int)
|
||||||
|
}
|
||||||
|
|
||||||
|
if rf, ok := ret.Get(1).(func(string, io.Reader, int) error); ok {
|
||||||
|
r1 = rf(printer, testPageData, size)
|
||||||
|
} else {
|
||||||
|
r1 = ret.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0, r1
|
||||||
|
}
|
||||||
|
|
||||||
|
// MockCUPSClientInterface_PrintTestPage_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PrintTestPage'
|
||||||
|
type MockCUPSClientInterface_PrintTestPage_Call struct {
|
||||||
|
*mock.Call
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrintTestPage is a helper method to define mock.On call
|
||||||
|
// - printer string
|
||||||
|
// - testPageData io.Reader
|
||||||
|
// - size int
|
||||||
|
func (_e *MockCUPSClientInterface_Expecter) PrintTestPage(printer interface{}, testPageData interface{}, size interface{}) *MockCUPSClientInterface_PrintTestPage_Call {
|
||||||
|
return &MockCUPSClientInterface_PrintTestPage_Call{Call: _e.mock.On("PrintTestPage", printer, testPageData, size)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockCUPSClientInterface_PrintTestPage_Call) Run(run func(printer string, testPageData io.Reader, size int)) *MockCUPSClientInterface_PrintTestPage_Call {
|
||||||
|
_c.Call.Run(func(args mock.Arguments) {
|
||||||
|
run(args[0].(string), args[1].(io.Reader), args[2].(int))
|
||||||
|
})
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockCUPSClientInterface_PrintTestPage_Call) Return(_a0 int, _a1 error) *MockCUPSClientInterface_PrintTestPage_Call {
|
||||||
|
_c.Call.Return(_a0, _a1)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockCUPSClientInterface_PrintTestPage_Call) RunAndReturn(run func(string, io.Reader, int) (int, error)) *MockCUPSClientInterface_PrintTestPage_Call {
|
||||||
|
_c.Call.Return(run)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
// RejectJobs provides a mock function with given fields: printer
|
||||||
|
func (_m *MockCUPSClientInterface) RejectJobs(printer string) error {
|
||||||
|
ret := _m.Called(printer)
|
||||||
|
|
||||||
|
if len(ret) == 0 {
|
||||||
|
panic("no return value specified for RejectJobs")
|
||||||
|
}
|
||||||
|
|
||||||
|
var r0 error
|
||||||
|
if rf, ok := ret.Get(0).(func(string) error); ok {
|
||||||
|
r0 = rf(printer)
|
||||||
|
} else {
|
||||||
|
r0 = ret.Error(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
||||||
|
|
||||||
|
// MockCUPSClientInterface_RejectJobs_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RejectJobs'
|
||||||
|
type MockCUPSClientInterface_RejectJobs_Call struct {
|
||||||
|
*mock.Call
|
||||||
|
}
|
||||||
|
|
||||||
|
// RejectJobs is a helper method to define mock.On call
|
||||||
|
// - printer string
|
||||||
|
func (_e *MockCUPSClientInterface_Expecter) RejectJobs(printer interface{}) *MockCUPSClientInterface_RejectJobs_Call {
|
||||||
|
return &MockCUPSClientInterface_RejectJobs_Call{Call: _e.mock.On("RejectJobs", printer)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockCUPSClientInterface_RejectJobs_Call) Run(run func(printer string)) *MockCUPSClientInterface_RejectJobs_Call {
|
||||||
|
_c.Call.Run(func(args mock.Arguments) {
|
||||||
|
run(args[0].(string))
|
||||||
|
})
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockCUPSClientInterface_RejectJobs_Call) Return(_a0 error) *MockCUPSClientInterface_RejectJobs_Call {
|
||||||
|
_c.Call.Return(_a0)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockCUPSClientInterface_RejectJobs_Call) RunAndReturn(run func(string) error) *MockCUPSClientInterface_RejectJobs_Call {
|
||||||
|
_c.Call.Return(run)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
// RestartJob provides a mock function with given fields: jobID
|
||||||
|
func (_m *MockCUPSClientInterface) RestartJob(jobID int) error {
|
||||||
|
ret := _m.Called(jobID)
|
||||||
|
|
||||||
|
if len(ret) == 0 {
|
||||||
|
panic("no return value specified for RestartJob")
|
||||||
|
}
|
||||||
|
|
||||||
|
var r0 error
|
||||||
|
if rf, ok := ret.Get(0).(func(int) error); ok {
|
||||||
|
r0 = rf(jobID)
|
||||||
|
} else {
|
||||||
|
r0 = ret.Error(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
||||||
|
|
||||||
|
// MockCUPSClientInterface_RestartJob_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RestartJob'
|
||||||
|
type MockCUPSClientInterface_RestartJob_Call struct {
|
||||||
|
*mock.Call
|
||||||
|
}
|
||||||
|
|
||||||
|
// RestartJob is a helper method to define mock.On call
|
||||||
|
// - jobID int
|
||||||
|
func (_e *MockCUPSClientInterface_Expecter) RestartJob(jobID interface{}) *MockCUPSClientInterface_RestartJob_Call {
|
||||||
|
return &MockCUPSClientInterface_RestartJob_Call{Call: _e.mock.On("RestartJob", jobID)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockCUPSClientInterface_RestartJob_Call) Run(run func(jobID int)) *MockCUPSClientInterface_RestartJob_Call {
|
||||||
|
_c.Call.Run(func(args mock.Arguments) {
|
||||||
|
run(args[0].(int))
|
||||||
|
})
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockCUPSClientInterface_RestartJob_Call) Return(_a0 error) *MockCUPSClientInterface_RestartJob_Call {
|
||||||
|
_c.Call.Return(_a0)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockCUPSClientInterface_RestartJob_Call) RunAndReturn(run func(int) error) *MockCUPSClientInterface_RestartJob_Call {
|
||||||
|
_c.Call.Return(run)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
// ResumePrinter provides a mock function with given fields: printer
|
// ResumePrinter provides a mock function with given fields: printer
|
||||||
func (_m *MockCUPSClientInterface) ResumePrinter(printer string) error {
|
func (_m *MockCUPSClientInterface) ResumePrinter(printer string) error {
|
||||||
ret := _m.Called(printer)
|
ret := _m.Called(printer)
|
||||||
@@ -390,6 +1090,147 @@ func (_c *MockCUPSClientInterface_SendRequest_Call) RunAndReturn(run func(string
|
|||||||
return _c
|
return _c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetPrinterInformation provides a mock function with given fields: printer, information
|
||||||
|
func (_m *MockCUPSClientInterface) SetPrinterInformation(printer string, information string) error {
|
||||||
|
ret := _m.Called(printer, information)
|
||||||
|
|
||||||
|
if len(ret) == 0 {
|
||||||
|
panic("no return value specified for SetPrinterInformation")
|
||||||
|
}
|
||||||
|
|
||||||
|
var r0 error
|
||||||
|
if rf, ok := ret.Get(0).(func(string, string) error); ok {
|
||||||
|
r0 = rf(printer, information)
|
||||||
|
} else {
|
||||||
|
r0 = ret.Error(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
||||||
|
|
||||||
|
// MockCUPSClientInterface_SetPrinterInformation_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetPrinterInformation'
|
||||||
|
type MockCUPSClientInterface_SetPrinterInformation_Call struct {
|
||||||
|
*mock.Call
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetPrinterInformation is a helper method to define mock.On call
|
||||||
|
// - printer string
|
||||||
|
// - information string
|
||||||
|
func (_e *MockCUPSClientInterface_Expecter) SetPrinterInformation(printer interface{}, information interface{}) *MockCUPSClientInterface_SetPrinterInformation_Call {
|
||||||
|
return &MockCUPSClientInterface_SetPrinterInformation_Call{Call: _e.mock.On("SetPrinterInformation", printer, information)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockCUPSClientInterface_SetPrinterInformation_Call) Run(run func(printer string, information string)) *MockCUPSClientInterface_SetPrinterInformation_Call {
|
||||||
|
_c.Call.Run(func(args mock.Arguments) {
|
||||||
|
run(args[0].(string), args[1].(string))
|
||||||
|
})
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockCUPSClientInterface_SetPrinterInformation_Call) Return(_a0 error) *MockCUPSClientInterface_SetPrinterInformation_Call {
|
||||||
|
_c.Call.Return(_a0)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockCUPSClientInterface_SetPrinterInformation_Call) RunAndReturn(run func(string, string) error) *MockCUPSClientInterface_SetPrinterInformation_Call {
|
||||||
|
_c.Call.Return(run)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetPrinterIsShared provides a mock function with given fields: printer, shared
|
||||||
|
func (_m *MockCUPSClientInterface) SetPrinterIsShared(printer string, shared bool) error {
|
||||||
|
ret := _m.Called(printer, shared)
|
||||||
|
|
||||||
|
if len(ret) == 0 {
|
||||||
|
panic("no return value specified for SetPrinterIsShared")
|
||||||
|
}
|
||||||
|
|
||||||
|
var r0 error
|
||||||
|
if rf, ok := ret.Get(0).(func(string, bool) error); ok {
|
||||||
|
r0 = rf(printer, shared)
|
||||||
|
} else {
|
||||||
|
r0 = ret.Error(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
||||||
|
|
||||||
|
// MockCUPSClientInterface_SetPrinterIsShared_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetPrinterIsShared'
|
||||||
|
type MockCUPSClientInterface_SetPrinterIsShared_Call struct {
|
||||||
|
*mock.Call
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetPrinterIsShared is a helper method to define mock.On call
|
||||||
|
// - printer string
|
||||||
|
// - shared bool
|
||||||
|
func (_e *MockCUPSClientInterface_Expecter) SetPrinterIsShared(printer interface{}, shared interface{}) *MockCUPSClientInterface_SetPrinterIsShared_Call {
|
||||||
|
return &MockCUPSClientInterface_SetPrinterIsShared_Call{Call: _e.mock.On("SetPrinterIsShared", printer, shared)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockCUPSClientInterface_SetPrinterIsShared_Call) Run(run func(printer string, shared bool)) *MockCUPSClientInterface_SetPrinterIsShared_Call {
|
||||||
|
_c.Call.Run(func(args mock.Arguments) {
|
||||||
|
run(args[0].(string), args[1].(bool))
|
||||||
|
})
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockCUPSClientInterface_SetPrinterIsShared_Call) Return(_a0 error) *MockCUPSClientInterface_SetPrinterIsShared_Call {
|
||||||
|
_c.Call.Return(_a0)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockCUPSClientInterface_SetPrinterIsShared_Call) RunAndReturn(run func(string, bool) error) *MockCUPSClientInterface_SetPrinterIsShared_Call {
|
||||||
|
_c.Call.Return(run)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetPrinterLocation provides a mock function with given fields: printer, location
|
||||||
|
func (_m *MockCUPSClientInterface) SetPrinterLocation(printer string, location string) error {
|
||||||
|
ret := _m.Called(printer, location)
|
||||||
|
|
||||||
|
if len(ret) == 0 {
|
||||||
|
panic("no return value specified for SetPrinterLocation")
|
||||||
|
}
|
||||||
|
|
||||||
|
var r0 error
|
||||||
|
if rf, ok := ret.Get(0).(func(string, string) error); ok {
|
||||||
|
r0 = rf(printer, location)
|
||||||
|
} else {
|
||||||
|
r0 = ret.Error(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
||||||
|
|
||||||
|
// MockCUPSClientInterface_SetPrinterLocation_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetPrinterLocation'
|
||||||
|
type MockCUPSClientInterface_SetPrinterLocation_Call struct {
|
||||||
|
*mock.Call
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetPrinterLocation is a helper method to define mock.On call
|
||||||
|
// - printer string
|
||||||
|
// - location string
|
||||||
|
func (_e *MockCUPSClientInterface_Expecter) SetPrinterLocation(printer interface{}, location interface{}) *MockCUPSClientInterface_SetPrinterLocation_Call {
|
||||||
|
return &MockCUPSClientInterface_SetPrinterLocation_Call{Call: _e.mock.On("SetPrinterLocation", printer, location)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockCUPSClientInterface_SetPrinterLocation_Call) Run(run func(printer string, location string)) *MockCUPSClientInterface_SetPrinterLocation_Call {
|
||||||
|
_c.Call.Run(func(args mock.Arguments) {
|
||||||
|
run(args[0].(string), args[1].(string))
|
||||||
|
})
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockCUPSClientInterface_SetPrinterLocation_Call) Return(_a0 error) *MockCUPSClientInterface_SetPrinterLocation_Call {
|
||||||
|
_c.Call.Return(_a0)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockCUPSClientInterface_SetPrinterLocation_Call) RunAndReturn(run func(string, string) error) *MockCUPSClientInterface_SetPrinterLocation_Call {
|
||||||
|
_c.Call.Return(run)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
// NewMockCUPSClientInterface creates a new instance of MockCUPSClientInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
|
// NewMockCUPSClientInterface creates a new instance of MockCUPSClientInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
|
||||||
// The first argument is typically a *testing.T value.
|
// The first argument is typically a *testing.T value.
|
||||||
func NewMockCUPSClientInterface(t interface {
|
func NewMockCUPSClientInterface(t interface {
|
||||||
|
|||||||
708
core/internal/mocks/cups_pkhelper/mock_PkHelper.go
Normal file
708
core/internal/mocks/cups_pkhelper/mock_PkHelper.go
Normal file
@@ -0,0 +1,708 @@
|
|||||||
|
// Code generated by mockery v2.53.5. DO NOT EDIT.
|
||||||
|
|
||||||
|
package mocks_cups_pkhelper
|
||||||
|
|
||||||
|
import (
|
||||||
|
cups "github.com/AvengeMedia/DankMaterialShell/core/internal/server/cups"
|
||||||
|
mock "github.com/stretchr/testify/mock"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MockPkHelper is an autogenerated mock type for the PkHelper type
|
||||||
|
type MockPkHelper struct {
|
||||||
|
mock.Mock
|
||||||
|
}
|
||||||
|
|
||||||
|
type MockPkHelper_Expecter struct {
|
||||||
|
mock *mock.Mock
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_m *MockPkHelper) EXPECT() *MockPkHelper_Expecter {
|
||||||
|
return &MockPkHelper_Expecter{mock: &_m.Mock}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClassAddPrinter provides a mock function with given fields: className, printerName
|
||||||
|
func (_m *MockPkHelper) ClassAddPrinter(className string, printerName string) error {
|
||||||
|
ret := _m.Called(className, printerName)
|
||||||
|
|
||||||
|
if len(ret) == 0 {
|
||||||
|
panic("no return value specified for ClassAddPrinter")
|
||||||
|
}
|
||||||
|
|
||||||
|
var r0 error
|
||||||
|
if rf, ok := ret.Get(0).(func(string, string) error); ok {
|
||||||
|
r0 = rf(className, printerName)
|
||||||
|
} else {
|
||||||
|
r0 = ret.Error(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
||||||
|
|
||||||
|
// MockPkHelper_ClassAddPrinter_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ClassAddPrinter'
|
||||||
|
type MockPkHelper_ClassAddPrinter_Call struct {
|
||||||
|
*mock.Call
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClassAddPrinter is a helper method to define mock.On call
|
||||||
|
// - className string
|
||||||
|
// - printerName string
|
||||||
|
func (_e *MockPkHelper_Expecter) ClassAddPrinter(className interface{}, printerName interface{}) *MockPkHelper_ClassAddPrinter_Call {
|
||||||
|
return &MockPkHelper_ClassAddPrinter_Call{Call: _e.mock.On("ClassAddPrinter", className, printerName)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockPkHelper_ClassAddPrinter_Call) Run(run func(className string, printerName string)) *MockPkHelper_ClassAddPrinter_Call {
|
||||||
|
_c.Call.Run(func(args mock.Arguments) {
|
||||||
|
run(args[0].(string), args[1].(string))
|
||||||
|
})
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockPkHelper_ClassAddPrinter_Call) Return(_a0 error) *MockPkHelper_ClassAddPrinter_Call {
|
||||||
|
_c.Call.Return(_a0)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockPkHelper_ClassAddPrinter_Call) RunAndReturn(run func(string, string) error) *MockPkHelper_ClassAddPrinter_Call {
|
||||||
|
_c.Call.Return(run)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClassDelete provides a mock function with given fields: className
|
||||||
|
func (_m *MockPkHelper) ClassDelete(className string) error {
|
||||||
|
ret := _m.Called(className)
|
||||||
|
|
||||||
|
if len(ret) == 0 {
|
||||||
|
panic("no return value specified for ClassDelete")
|
||||||
|
}
|
||||||
|
|
||||||
|
var r0 error
|
||||||
|
if rf, ok := ret.Get(0).(func(string) error); ok {
|
||||||
|
r0 = rf(className)
|
||||||
|
} else {
|
||||||
|
r0 = ret.Error(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
||||||
|
|
||||||
|
// MockPkHelper_ClassDelete_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ClassDelete'
|
||||||
|
type MockPkHelper_ClassDelete_Call struct {
|
||||||
|
*mock.Call
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClassDelete is a helper method to define mock.On call
|
||||||
|
// - className string
|
||||||
|
func (_e *MockPkHelper_Expecter) ClassDelete(className interface{}) *MockPkHelper_ClassDelete_Call {
|
||||||
|
return &MockPkHelper_ClassDelete_Call{Call: _e.mock.On("ClassDelete", className)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockPkHelper_ClassDelete_Call) Run(run func(className string)) *MockPkHelper_ClassDelete_Call {
|
||||||
|
_c.Call.Run(func(args mock.Arguments) {
|
||||||
|
run(args[0].(string))
|
||||||
|
})
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockPkHelper_ClassDelete_Call) Return(_a0 error) *MockPkHelper_ClassDelete_Call {
|
||||||
|
_c.Call.Return(_a0)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockPkHelper_ClassDelete_Call) RunAndReturn(run func(string) error) *MockPkHelper_ClassDelete_Call {
|
||||||
|
_c.Call.Return(run)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClassDeletePrinter provides a mock function with given fields: className, printerName
|
||||||
|
func (_m *MockPkHelper) ClassDeletePrinter(className string, printerName string) error {
|
||||||
|
ret := _m.Called(className, printerName)
|
||||||
|
|
||||||
|
if len(ret) == 0 {
|
||||||
|
panic("no return value specified for ClassDeletePrinter")
|
||||||
|
}
|
||||||
|
|
||||||
|
var r0 error
|
||||||
|
if rf, ok := ret.Get(0).(func(string, string) error); ok {
|
||||||
|
r0 = rf(className, printerName)
|
||||||
|
} else {
|
||||||
|
r0 = ret.Error(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
||||||
|
|
||||||
|
// MockPkHelper_ClassDeletePrinter_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ClassDeletePrinter'
|
||||||
|
type MockPkHelper_ClassDeletePrinter_Call struct {
|
||||||
|
*mock.Call
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClassDeletePrinter is a helper method to define mock.On call
|
||||||
|
// - className string
|
||||||
|
// - printerName string
|
||||||
|
func (_e *MockPkHelper_Expecter) ClassDeletePrinter(className interface{}, printerName interface{}) *MockPkHelper_ClassDeletePrinter_Call {
|
||||||
|
return &MockPkHelper_ClassDeletePrinter_Call{Call: _e.mock.On("ClassDeletePrinter", className, printerName)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockPkHelper_ClassDeletePrinter_Call) Run(run func(className string, printerName string)) *MockPkHelper_ClassDeletePrinter_Call {
|
||||||
|
_c.Call.Run(func(args mock.Arguments) {
|
||||||
|
run(args[0].(string), args[1].(string))
|
||||||
|
})
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockPkHelper_ClassDeletePrinter_Call) Return(_a0 error) *MockPkHelper_ClassDeletePrinter_Call {
|
||||||
|
_c.Call.Return(_a0)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockPkHelper_ClassDeletePrinter_Call) RunAndReturn(run func(string, string) error) *MockPkHelper_ClassDeletePrinter_Call {
|
||||||
|
_c.Call.Return(run)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
// DevicesGet provides a mock function with given fields: timeout, limit, includeSchemes, excludeSchemes
|
||||||
|
func (_m *MockPkHelper) DevicesGet(timeout int, limit int, includeSchemes []string, excludeSchemes []string) ([]cups.Device, error) {
|
||||||
|
ret := _m.Called(timeout, limit, includeSchemes, excludeSchemes)
|
||||||
|
|
||||||
|
if len(ret) == 0 {
|
||||||
|
panic("no return value specified for DevicesGet")
|
||||||
|
}
|
||||||
|
|
||||||
|
var r0 []cups.Device
|
||||||
|
var r1 error
|
||||||
|
if rf, ok := ret.Get(0).(func(int, int, []string, []string) ([]cups.Device, error)); ok {
|
||||||
|
return rf(timeout, limit, includeSchemes, excludeSchemes)
|
||||||
|
}
|
||||||
|
if rf, ok := ret.Get(0).(func(int, int, []string, []string) []cups.Device); ok {
|
||||||
|
r0 = rf(timeout, limit, includeSchemes, excludeSchemes)
|
||||||
|
} else {
|
||||||
|
if ret.Get(0) != nil {
|
||||||
|
r0 = ret.Get(0).([]cups.Device)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if rf, ok := ret.Get(1).(func(int, int, []string, []string) error); ok {
|
||||||
|
r1 = rf(timeout, limit, includeSchemes, excludeSchemes)
|
||||||
|
} else {
|
||||||
|
r1 = ret.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0, r1
|
||||||
|
}
|
||||||
|
|
||||||
|
// MockPkHelper_DevicesGet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DevicesGet'
|
||||||
|
type MockPkHelper_DevicesGet_Call struct {
|
||||||
|
*mock.Call
|
||||||
|
}
|
||||||
|
|
||||||
|
// DevicesGet is a helper method to define mock.On call
|
||||||
|
// - timeout int
|
||||||
|
// - limit int
|
||||||
|
// - includeSchemes []string
|
||||||
|
// - excludeSchemes []string
|
||||||
|
func (_e *MockPkHelper_Expecter) DevicesGet(timeout interface{}, limit interface{}, includeSchemes interface{}, excludeSchemes interface{}) *MockPkHelper_DevicesGet_Call {
|
||||||
|
return &MockPkHelper_DevicesGet_Call{Call: _e.mock.On("DevicesGet", timeout, limit, includeSchemes, excludeSchemes)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockPkHelper_DevicesGet_Call) Run(run func(timeout int, limit int, includeSchemes []string, excludeSchemes []string)) *MockPkHelper_DevicesGet_Call {
|
||||||
|
_c.Call.Run(func(args mock.Arguments) {
|
||||||
|
run(args[0].(int), args[1].(int), args[2].([]string), args[3].([]string))
|
||||||
|
})
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockPkHelper_DevicesGet_Call) Return(_a0 []cups.Device, _a1 error) *MockPkHelper_DevicesGet_Call {
|
||||||
|
_c.Call.Return(_a0, _a1)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockPkHelper_DevicesGet_Call) RunAndReturn(run func(int, int, []string, []string) ([]cups.Device, error)) *MockPkHelper_DevicesGet_Call {
|
||||||
|
_c.Call.Return(run)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
// JobCancelPurge provides a mock function with given fields: jobID, purge
|
||||||
|
func (_m *MockPkHelper) JobCancelPurge(jobID int, purge bool) error {
|
||||||
|
ret := _m.Called(jobID, purge)
|
||||||
|
|
||||||
|
if len(ret) == 0 {
|
||||||
|
panic("no return value specified for JobCancelPurge")
|
||||||
|
}
|
||||||
|
|
||||||
|
var r0 error
|
||||||
|
if rf, ok := ret.Get(0).(func(int, bool) error); ok {
|
||||||
|
r0 = rf(jobID, purge)
|
||||||
|
} else {
|
||||||
|
r0 = ret.Error(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
||||||
|
|
||||||
|
// MockPkHelper_JobCancelPurge_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'JobCancelPurge'
|
||||||
|
type MockPkHelper_JobCancelPurge_Call struct {
|
||||||
|
*mock.Call
|
||||||
|
}
|
||||||
|
|
||||||
|
// JobCancelPurge is a helper method to define mock.On call
|
||||||
|
// - jobID int
|
||||||
|
// - purge bool
|
||||||
|
func (_e *MockPkHelper_Expecter) JobCancelPurge(jobID interface{}, purge interface{}) *MockPkHelper_JobCancelPurge_Call {
|
||||||
|
return &MockPkHelper_JobCancelPurge_Call{Call: _e.mock.On("JobCancelPurge", jobID, purge)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockPkHelper_JobCancelPurge_Call) Run(run func(jobID int, purge bool)) *MockPkHelper_JobCancelPurge_Call {
|
||||||
|
_c.Call.Run(func(args mock.Arguments) {
|
||||||
|
run(args[0].(int), args[1].(bool))
|
||||||
|
})
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockPkHelper_JobCancelPurge_Call) Return(_a0 error) *MockPkHelper_JobCancelPurge_Call {
|
||||||
|
_c.Call.Return(_a0)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockPkHelper_JobCancelPurge_Call) RunAndReturn(run func(int, bool) error) *MockPkHelper_JobCancelPurge_Call {
|
||||||
|
_c.Call.Return(run)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
// JobRestart provides a mock function with given fields: jobID
|
||||||
|
func (_m *MockPkHelper) JobRestart(jobID int) error {
|
||||||
|
ret := _m.Called(jobID)
|
||||||
|
|
||||||
|
if len(ret) == 0 {
|
||||||
|
panic("no return value specified for JobRestart")
|
||||||
|
}
|
||||||
|
|
||||||
|
var r0 error
|
||||||
|
if rf, ok := ret.Get(0).(func(int) error); ok {
|
||||||
|
r0 = rf(jobID)
|
||||||
|
} else {
|
||||||
|
r0 = ret.Error(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
||||||
|
|
||||||
|
// MockPkHelper_JobRestart_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'JobRestart'
|
||||||
|
type MockPkHelper_JobRestart_Call struct {
|
||||||
|
*mock.Call
|
||||||
|
}
|
||||||
|
|
||||||
|
// JobRestart is a helper method to define mock.On call
|
||||||
|
// - jobID int
|
||||||
|
func (_e *MockPkHelper_Expecter) JobRestart(jobID interface{}) *MockPkHelper_JobRestart_Call {
|
||||||
|
return &MockPkHelper_JobRestart_Call{Call: _e.mock.On("JobRestart", jobID)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockPkHelper_JobRestart_Call) Run(run func(jobID int)) *MockPkHelper_JobRestart_Call {
|
||||||
|
_c.Call.Run(func(args mock.Arguments) {
|
||||||
|
run(args[0].(int))
|
||||||
|
})
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockPkHelper_JobRestart_Call) Return(_a0 error) *MockPkHelper_JobRestart_Call {
|
||||||
|
_c.Call.Return(_a0)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockPkHelper_JobRestart_Call) RunAndReturn(run func(int) error) *MockPkHelper_JobRestart_Call {
|
||||||
|
_c.Call.Return(run)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
// JobSetHoldUntil provides a mock function with given fields: jobID, holdUntil
|
||||||
|
func (_m *MockPkHelper) JobSetHoldUntil(jobID int, holdUntil string) error {
|
||||||
|
ret := _m.Called(jobID, holdUntil)
|
||||||
|
|
||||||
|
if len(ret) == 0 {
|
||||||
|
panic("no return value specified for JobSetHoldUntil")
|
||||||
|
}
|
||||||
|
|
||||||
|
var r0 error
|
||||||
|
if rf, ok := ret.Get(0).(func(int, string) error); ok {
|
||||||
|
r0 = rf(jobID, holdUntil)
|
||||||
|
} else {
|
||||||
|
r0 = ret.Error(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
||||||
|
|
||||||
|
// MockPkHelper_JobSetHoldUntil_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'JobSetHoldUntil'
|
||||||
|
type MockPkHelper_JobSetHoldUntil_Call struct {
|
||||||
|
*mock.Call
|
||||||
|
}
|
||||||
|
|
||||||
|
// JobSetHoldUntil is a helper method to define mock.On call
|
||||||
|
// - jobID int
|
||||||
|
// - holdUntil string
|
||||||
|
func (_e *MockPkHelper_Expecter) JobSetHoldUntil(jobID interface{}, holdUntil interface{}) *MockPkHelper_JobSetHoldUntil_Call {
|
||||||
|
return &MockPkHelper_JobSetHoldUntil_Call{Call: _e.mock.On("JobSetHoldUntil", jobID, holdUntil)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockPkHelper_JobSetHoldUntil_Call) Run(run func(jobID int, holdUntil string)) *MockPkHelper_JobSetHoldUntil_Call {
|
||||||
|
_c.Call.Run(func(args mock.Arguments) {
|
||||||
|
run(args[0].(int), args[1].(string))
|
||||||
|
})
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockPkHelper_JobSetHoldUntil_Call) Return(_a0 error) *MockPkHelper_JobSetHoldUntil_Call {
|
||||||
|
_c.Call.Return(_a0)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockPkHelper_JobSetHoldUntil_Call) RunAndReturn(run func(int, string) error) *MockPkHelper_JobSetHoldUntil_Call {
|
||||||
|
_c.Call.Return(run)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrinterAdd provides a mock function with given fields: name, uri, ppd, info, location
|
||||||
|
func (_m *MockPkHelper) PrinterAdd(name string, uri string, ppd string, info string, location string) error {
|
||||||
|
ret := _m.Called(name, uri, ppd, info, location)
|
||||||
|
|
||||||
|
if len(ret) == 0 {
|
||||||
|
panic("no return value specified for PrinterAdd")
|
||||||
|
}
|
||||||
|
|
||||||
|
var r0 error
|
||||||
|
if rf, ok := ret.Get(0).(func(string, string, string, string, string) error); ok {
|
||||||
|
r0 = rf(name, uri, ppd, info, location)
|
||||||
|
} else {
|
||||||
|
r0 = ret.Error(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
||||||
|
|
||||||
|
// MockPkHelper_PrinterAdd_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PrinterAdd'
|
||||||
|
type MockPkHelper_PrinterAdd_Call struct {
|
||||||
|
*mock.Call
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrinterAdd is a helper method to define mock.On call
|
||||||
|
// - name string
|
||||||
|
// - uri string
|
||||||
|
// - ppd string
|
||||||
|
// - info string
|
||||||
|
// - location string
|
||||||
|
func (_e *MockPkHelper_Expecter) PrinterAdd(name interface{}, uri interface{}, ppd interface{}, info interface{}, location interface{}) *MockPkHelper_PrinterAdd_Call {
|
||||||
|
return &MockPkHelper_PrinterAdd_Call{Call: _e.mock.On("PrinterAdd", name, uri, ppd, info, location)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockPkHelper_PrinterAdd_Call) Run(run func(name string, uri string, ppd string, info string, location string)) *MockPkHelper_PrinterAdd_Call {
|
||||||
|
_c.Call.Run(func(args mock.Arguments) {
|
||||||
|
run(args[0].(string), args[1].(string), args[2].(string), args[3].(string), args[4].(string))
|
||||||
|
})
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockPkHelper_PrinterAdd_Call) Return(_a0 error) *MockPkHelper_PrinterAdd_Call {
|
||||||
|
_c.Call.Return(_a0)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockPkHelper_PrinterAdd_Call) RunAndReturn(run func(string, string, string, string, string) error) *MockPkHelper_PrinterAdd_Call {
|
||||||
|
_c.Call.Return(run)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrinterDelete provides a mock function with given fields: name
|
||||||
|
func (_m *MockPkHelper) PrinterDelete(name string) error {
|
||||||
|
ret := _m.Called(name)
|
||||||
|
|
||||||
|
if len(ret) == 0 {
|
||||||
|
panic("no return value specified for PrinterDelete")
|
||||||
|
}
|
||||||
|
|
||||||
|
var r0 error
|
||||||
|
if rf, ok := ret.Get(0).(func(string) error); ok {
|
||||||
|
r0 = rf(name)
|
||||||
|
} else {
|
||||||
|
r0 = ret.Error(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
||||||
|
|
||||||
|
// MockPkHelper_PrinterDelete_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PrinterDelete'
|
||||||
|
type MockPkHelper_PrinterDelete_Call struct {
|
||||||
|
*mock.Call
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrinterDelete is a helper method to define mock.On call
|
||||||
|
// - name string
|
||||||
|
func (_e *MockPkHelper_Expecter) PrinterDelete(name interface{}) *MockPkHelper_PrinterDelete_Call {
|
||||||
|
return &MockPkHelper_PrinterDelete_Call{Call: _e.mock.On("PrinterDelete", name)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockPkHelper_PrinterDelete_Call) Run(run func(name string)) *MockPkHelper_PrinterDelete_Call {
|
||||||
|
_c.Call.Run(func(args mock.Arguments) {
|
||||||
|
run(args[0].(string))
|
||||||
|
})
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockPkHelper_PrinterDelete_Call) Return(_a0 error) *MockPkHelper_PrinterDelete_Call {
|
||||||
|
_c.Call.Return(_a0)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockPkHelper_PrinterDelete_Call) RunAndReturn(run func(string) error) *MockPkHelper_PrinterDelete_Call {
|
||||||
|
_c.Call.Return(run)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrinterSetAcceptJobs provides a mock function with given fields: name, enabled, reason
|
||||||
|
func (_m *MockPkHelper) PrinterSetAcceptJobs(name string, enabled bool, reason string) error {
|
||||||
|
ret := _m.Called(name, enabled, reason)
|
||||||
|
|
||||||
|
if len(ret) == 0 {
|
||||||
|
panic("no return value specified for PrinterSetAcceptJobs")
|
||||||
|
}
|
||||||
|
|
||||||
|
var r0 error
|
||||||
|
if rf, ok := ret.Get(0).(func(string, bool, string) error); ok {
|
||||||
|
r0 = rf(name, enabled, reason)
|
||||||
|
} else {
|
||||||
|
r0 = ret.Error(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
||||||
|
|
||||||
|
// MockPkHelper_PrinterSetAcceptJobs_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PrinterSetAcceptJobs'
|
||||||
|
type MockPkHelper_PrinterSetAcceptJobs_Call struct {
|
||||||
|
*mock.Call
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrinterSetAcceptJobs is a helper method to define mock.On call
|
||||||
|
// - name string
|
||||||
|
// - enabled bool
|
||||||
|
// - reason string
|
||||||
|
func (_e *MockPkHelper_Expecter) PrinterSetAcceptJobs(name interface{}, enabled interface{}, reason interface{}) *MockPkHelper_PrinterSetAcceptJobs_Call {
|
||||||
|
return &MockPkHelper_PrinterSetAcceptJobs_Call{Call: _e.mock.On("PrinterSetAcceptJobs", name, enabled, reason)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockPkHelper_PrinterSetAcceptJobs_Call) Run(run func(name string, enabled bool, reason string)) *MockPkHelper_PrinterSetAcceptJobs_Call {
|
||||||
|
_c.Call.Run(func(args mock.Arguments) {
|
||||||
|
run(args[0].(string), args[1].(bool), args[2].(string))
|
||||||
|
})
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockPkHelper_PrinterSetAcceptJobs_Call) Return(_a0 error) *MockPkHelper_PrinterSetAcceptJobs_Call {
|
||||||
|
_c.Call.Return(_a0)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockPkHelper_PrinterSetAcceptJobs_Call) RunAndReturn(run func(string, bool, string) error) *MockPkHelper_PrinterSetAcceptJobs_Call {
|
||||||
|
_c.Call.Return(run)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrinterSetEnabled provides a mock function with given fields: name, enabled
|
||||||
|
func (_m *MockPkHelper) PrinterSetEnabled(name string, enabled bool) error {
|
||||||
|
ret := _m.Called(name, enabled)
|
||||||
|
|
||||||
|
if len(ret) == 0 {
|
||||||
|
panic("no return value specified for PrinterSetEnabled")
|
||||||
|
}
|
||||||
|
|
||||||
|
var r0 error
|
||||||
|
if rf, ok := ret.Get(0).(func(string, bool) error); ok {
|
||||||
|
r0 = rf(name, enabled)
|
||||||
|
} else {
|
||||||
|
r0 = ret.Error(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
||||||
|
|
||||||
|
// MockPkHelper_PrinterSetEnabled_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PrinterSetEnabled'
|
||||||
|
type MockPkHelper_PrinterSetEnabled_Call struct {
|
||||||
|
*mock.Call
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrinterSetEnabled is a helper method to define mock.On call
|
||||||
|
// - name string
|
||||||
|
// - enabled bool
|
||||||
|
func (_e *MockPkHelper_Expecter) PrinterSetEnabled(name interface{}, enabled interface{}) *MockPkHelper_PrinterSetEnabled_Call {
|
||||||
|
return &MockPkHelper_PrinterSetEnabled_Call{Call: _e.mock.On("PrinterSetEnabled", name, enabled)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockPkHelper_PrinterSetEnabled_Call) Run(run func(name string, enabled bool)) *MockPkHelper_PrinterSetEnabled_Call {
|
||||||
|
_c.Call.Run(func(args mock.Arguments) {
|
||||||
|
run(args[0].(string), args[1].(bool))
|
||||||
|
})
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockPkHelper_PrinterSetEnabled_Call) Return(_a0 error) *MockPkHelper_PrinterSetEnabled_Call {
|
||||||
|
_c.Call.Return(_a0)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockPkHelper_PrinterSetEnabled_Call) RunAndReturn(run func(string, bool) error) *MockPkHelper_PrinterSetEnabled_Call {
|
||||||
|
_c.Call.Return(run)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrinterSetInfo provides a mock function with given fields: name, info
|
||||||
|
func (_m *MockPkHelper) PrinterSetInfo(name string, info string) error {
|
||||||
|
ret := _m.Called(name, info)
|
||||||
|
|
||||||
|
if len(ret) == 0 {
|
||||||
|
panic("no return value specified for PrinterSetInfo")
|
||||||
|
}
|
||||||
|
|
||||||
|
var r0 error
|
||||||
|
if rf, ok := ret.Get(0).(func(string, string) error); ok {
|
||||||
|
r0 = rf(name, info)
|
||||||
|
} else {
|
||||||
|
r0 = ret.Error(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
||||||
|
|
||||||
|
// MockPkHelper_PrinterSetInfo_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PrinterSetInfo'
|
||||||
|
type MockPkHelper_PrinterSetInfo_Call struct {
|
||||||
|
*mock.Call
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrinterSetInfo is a helper method to define mock.On call
|
||||||
|
// - name string
|
||||||
|
// - info string
|
||||||
|
func (_e *MockPkHelper_Expecter) PrinterSetInfo(name interface{}, info interface{}) *MockPkHelper_PrinterSetInfo_Call {
|
||||||
|
return &MockPkHelper_PrinterSetInfo_Call{Call: _e.mock.On("PrinterSetInfo", name, info)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockPkHelper_PrinterSetInfo_Call) Run(run func(name string, info string)) *MockPkHelper_PrinterSetInfo_Call {
|
||||||
|
_c.Call.Run(func(args mock.Arguments) {
|
||||||
|
run(args[0].(string), args[1].(string))
|
||||||
|
})
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockPkHelper_PrinterSetInfo_Call) Return(_a0 error) *MockPkHelper_PrinterSetInfo_Call {
|
||||||
|
_c.Call.Return(_a0)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockPkHelper_PrinterSetInfo_Call) RunAndReturn(run func(string, string) error) *MockPkHelper_PrinterSetInfo_Call {
|
||||||
|
_c.Call.Return(run)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrinterSetLocation provides a mock function with given fields: name, location
|
||||||
|
func (_m *MockPkHelper) PrinterSetLocation(name string, location string) error {
|
||||||
|
ret := _m.Called(name, location)
|
||||||
|
|
||||||
|
if len(ret) == 0 {
|
||||||
|
panic("no return value specified for PrinterSetLocation")
|
||||||
|
}
|
||||||
|
|
||||||
|
var r0 error
|
||||||
|
if rf, ok := ret.Get(0).(func(string, string) error); ok {
|
||||||
|
r0 = rf(name, location)
|
||||||
|
} else {
|
||||||
|
r0 = ret.Error(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
||||||
|
|
||||||
|
// MockPkHelper_PrinterSetLocation_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PrinterSetLocation'
|
||||||
|
type MockPkHelper_PrinterSetLocation_Call struct {
|
||||||
|
*mock.Call
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrinterSetLocation is a helper method to define mock.On call
|
||||||
|
// - name string
|
||||||
|
// - location string
|
||||||
|
func (_e *MockPkHelper_Expecter) PrinterSetLocation(name interface{}, location interface{}) *MockPkHelper_PrinterSetLocation_Call {
|
||||||
|
return &MockPkHelper_PrinterSetLocation_Call{Call: _e.mock.On("PrinterSetLocation", name, location)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockPkHelper_PrinterSetLocation_Call) Run(run func(name string, location string)) *MockPkHelper_PrinterSetLocation_Call {
|
||||||
|
_c.Call.Run(func(args mock.Arguments) {
|
||||||
|
run(args[0].(string), args[1].(string))
|
||||||
|
})
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockPkHelper_PrinterSetLocation_Call) Return(_a0 error) *MockPkHelper_PrinterSetLocation_Call {
|
||||||
|
_c.Call.Return(_a0)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockPkHelper_PrinterSetLocation_Call) RunAndReturn(run func(string, string) error) *MockPkHelper_PrinterSetLocation_Call {
|
||||||
|
_c.Call.Return(run)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrinterSetShared provides a mock function with given fields: name, shared
|
||||||
|
func (_m *MockPkHelper) PrinterSetShared(name string, shared bool) error {
|
||||||
|
ret := _m.Called(name, shared)
|
||||||
|
|
||||||
|
if len(ret) == 0 {
|
||||||
|
panic("no return value specified for PrinterSetShared")
|
||||||
|
}
|
||||||
|
|
||||||
|
var r0 error
|
||||||
|
if rf, ok := ret.Get(0).(func(string, bool) error); ok {
|
||||||
|
r0 = rf(name, shared)
|
||||||
|
} else {
|
||||||
|
r0 = ret.Error(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
||||||
|
|
||||||
|
// MockPkHelper_PrinterSetShared_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PrinterSetShared'
|
||||||
|
type MockPkHelper_PrinterSetShared_Call struct {
|
||||||
|
*mock.Call
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrinterSetShared is a helper method to define mock.On call
|
||||||
|
// - name string
|
||||||
|
// - shared bool
|
||||||
|
func (_e *MockPkHelper_Expecter) PrinterSetShared(name interface{}, shared interface{}) *MockPkHelper_PrinterSetShared_Call {
|
||||||
|
return &MockPkHelper_PrinterSetShared_Call{Call: _e.mock.On("PrinterSetShared", name, shared)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockPkHelper_PrinterSetShared_Call) Run(run func(name string, shared bool)) *MockPkHelper_PrinterSetShared_Call {
|
||||||
|
_c.Call.Run(func(args mock.Arguments) {
|
||||||
|
run(args[0].(string), args[1].(bool))
|
||||||
|
})
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockPkHelper_PrinterSetShared_Call) Return(_a0 error) *MockPkHelper_PrinterSetShared_Call {
|
||||||
|
_c.Call.Return(_a0)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockPkHelper_PrinterSetShared_Call) RunAndReturn(run func(string, bool) error) *MockPkHelper_PrinterSetShared_Call {
|
||||||
|
_c.Call.Return(run)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMockPkHelper creates a new instance of MockPkHelper. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
|
||||||
|
// The first argument is typically a *testing.T value.
|
||||||
|
func NewMockPkHelper(t interface {
|
||||||
|
mock.TestingT
|
||||||
|
Cleanup(func())
|
||||||
|
}) *MockPkHelper {
|
||||||
|
mock := &MockPkHelper{}
|
||||||
|
mock.Mock.Test(t)
|
||||||
|
|
||||||
|
t.Cleanup(func() { mock.AssertExpectations(t) })
|
||||||
|
|
||||||
|
return mock
|
||||||
|
}
|
||||||
@@ -1,12 +1,34 @@
|
|||||||
package cups
|
package cups
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/AvengeMedia/DankMaterialShell/core/internal/config"
|
||||||
"github.com/AvengeMedia/DankMaterialShell/core/pkg/ipp"
|
"github.com/AvengeMedia/DankMaterialShell/core/pkg/ipp"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func isAuthError(err error) bool {
|
||||||
|
if err == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
var httpErr ipp.HTTPError
|
||||||
|
if errors.As(err, &httpErr) {
|
||||||
|
return httpErr.Code == 401 || httpErr.Code == 403
|
||||||
|
}
|
||||||
|
|
||||||
|
var ippErr ipp.IPPError
|
||||||
|
if errors.As(err, &ippErr) {
|
||||||
|
return ippErr.Status == ipp.StatusErrorForbidden ||
|
||||||
|
ippErr.Status == ipp.StatusErrorNotAuthenticated ||
|
||||||
|
ippErr.Status == ipp.StatusErrorNotAuthorized
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func (m *Manager) GetPrinters() ([]Printer, error) {
|
func (m *Manager) GetPrinters() ([]Printer, error) {
|
||||||
attributes := []string{
|
attributes := []string{
|
||||||
ipp.AttributePrinterName,
|
ipp.AttributePrinterName,
|
||||||
@@ -21,6 +43,9 @@ func (m *Manager) GetPrinters() ([]Printer, error) {
|
|||||||
|
|
||||||
printerAttrs, err := m.client.GetPrinters(attributes)
|
printerAttrs, err := m.client.GetPrinters(attributes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if isNoPrintersError(err) {
|
||||||
|
return []Printer{}, nil
|
||||||
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,17 +116,289 @@ func (m *Manager) GetJobs(printerName string, whichJobs string) ([]Job, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *Manager) CancelJob(jobID int) error {
|
func (m *Manager) CancelJob(jobID int) error {
|
||||||
return m.client.CancelJob(jobID, false)
|
err := m.client.CancelJob(jobID, false)
|
||||||
|
if isAuthError(err) && m.pkHelper != nil {
|
||||||
|
err = m.pkHelper.JobCancelPurge(jobID, false)
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
m.RefreshState()
|
||||||
|
}
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Manager) PausePrinter(printerName string) error {
|
func (m *Manager) PausePrinter(printerName string) error {
|
||||||
return m.client.PausePrinter(printerName)
|
err := m.client.PausePrinter(printerName)
|
||||||
|
if isAuthError(err) && m.pkHelper != nil {
|
||||||
|
err = m.pkHelper.PrinterSetEnabled(printerName, false)
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
m.RefreshState()
|
||||||
|
}
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Manager) ResumePrinter(printerName string) error {
|
func (m *Manager) ResumePrinter(printerName string) error {
|
||||||
return m.client.ResumePrinter(printerName)
|
err := m.client.ResumePrinter(printerName)
|
||||||
|
if isAuthError(err) && m.pkHelper != nil {
|
||||||
|
err = m.pkHelper.PrinterSetEnabled(printerName, true)
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
m.RefreshState()
|
||||||
|
}
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Manager) PurgeJobs(printerName string) error {
|
func (m *Manager) PurgeJobs(printerName string) error {
|
||||||
return m.client.CancelAllJob(printerName, true)
|
err := m.client.CancelAllJob(printerName, true)
|
||||||
|
if err == nil {
|
||||||
|
m.RefreshState()
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Manager) GetDevices() ([]Device, error) {
|
||||||
|
if m.pkHelper != nil {
|
||||||
|
return m.pkHelper.DevicesGet(10, 0, nil, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
deviceAttrs, err := m.client.GetDevices()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
devices := make([]Device, 0, len(deviceAttrs))
|
||||||
|
for uri, attrs := range deviceAttrs {
|
||||||
|
device := Device{
|
||||||
|
URI: uri,
|
||||||
|
Class: getStringAttr(attrs, "device-class"),
|
||||||
|
Info: getStringAttr(attrs, "device-info"),
|
||||||
|
MakeModel: getStringAttr(attrs, "device-make-and-model"),
|
||||||
|
ID: getStringAttr(attrs, "device-id"),
|
||||||
|
Location: getStringAttr(attrs, "device-location"),
|
||||||
|
}
|
||||||
|
devices = append(devices, device)
|
||||||
|
}
|
||||||
|
|
||||||
|
return devices, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Manager) GetPPDs() ([]PPD, error) {
|
||||||
|
ppdAttrs, err := m.client.GetPPDs()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ppds := make([]PPD, 0, len(ppdAttrs))
|
||||||
|
for name, attrs := range ppdAttrs {
|
||||||
|
ppd := PPD{
|
||||||
|
Name: name,
|
||||||
|
NaturalLanguage: getStringAttr(attrs, "ppd-natural-language"),
|
||||||
|
MakeModel: getStringAttr(attrs, ipp.AttributePPDMakeAndModel),
|
||||||
|
DeviceID: getStringAttr(attrs, "ppd-device-id"),
|
||||||
|
Product: getStringAttr(attrs, "ppd-product"),
|
||||||
|
PSVersion: getStringAttr(attrs, "ppd-psversion"),
|
||||||
|
Type: getStringAttr(attrs, "ppd-type"),
|
||||||
|
}
|
||||||
|
ppds = append(ppds, ppd)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ppds, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Manager) GetClasses() ([]PrinterClass, error) {
|
||||||
|
attributes := []string{
|
||||||
|
ipp.AttributePrinterName,
|
||||||
|
ipp.AttributePrinterUriSupported,
|
||||||
|
ipp.AttributePrinterState,
|
||||||
|
ipp.AttributeMemberURIs,
|
||||||
|
ipp.AttributeMemberNames,
|
||||||
|
ipp.AttributePrinterLocation,
|
||||||
|
ipp.AttributePrinterInfo,
|
||||||
|
}
|
||||||
|
|
||||||
|
classAttrs, err := m.client.GetClasses(attributes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
classes := make([]PrinterClass, 0, len(classAttrs))
|
||||||
|
for _, attrs := range classAttrs {
|
||||||
|
class := PrinterClass{
|
||||||
|
Name: getStringAttr(attrs, ipp.AttributePrinterName),
|
||||||
|
URI: getStringAttr(attrs, ipp.AttributePrinterUriSupported),
|
||||||
|
State: parsePrinterState(attrs),
|
||||||
|
Location: getStringAttr(attrs, ipp.AttributePrinterLocation),
|
||||||
|
Info: getStringAttr(attrs, ipp.AttributePrinterInfo),
|
||||||
|
Members: getStringSliceAttr(attrs, ipp.AttributeMemberNames),
|
||||||
|
}
|
||||||
|
classes = append(classes, class)
|
||||||
|
}
|
||||||
|
|
||||||
|
return classes, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Manager) CreatePrinter(name, deviceURI, ppd string, shared bool, errorPolicy, information, location string) error {
|
||||||
|
usedPkHelper := false
|
||||||
|
|
||||||
|
err := m.client.CreatePrinter(name, deviceURI, ppd, shared, errorPolicy, information, location)
|
||||||
|
if isAuthError(err) && m.pkHelper != nil {
|
||||||
|
if err = m.pkHelper.PrinterAdd(name, deviceURI, ppd, information, location); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
usedPkHelper = true
|
||||||
|
} else if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if usedPkHelper {
|
||||||
|
m.pkHelper.PrinterSetEnabled(name, true)
|
||||||
|
m.pkHelper.PrinterSetAcceptJobs(name, true, "")
|
||||||
|
} else {
|
||||||
|
if err := m.client.ResumePrinter(name); isAuthError(err) && m.pkHelper != nil {
|
||||||
|
m.pkHelper.PrinterSetEnabled(name, true)
|
||||||
|
}
|
||||||
|
if err := m.client.AcceptJobs(name); isAuthError(err) && m.pkHelper != nil {
|
||||||
|
m.pkHelper.PrinterSetAcceptJobs(name, true, "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m.RefreshState()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Manager) DeletePrinter(printerName string) error {
|
||||||
|
err := m.client.DeletePrinter(printerName)
|
||||||
|
if isAuthError(err) && m.pkHelper != nil {
|
||||||
|
err = m.pkHelper.PrinterDelete(printerName)
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
m.RefreshState()
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Manager) AcceptJobs(printerName string) error {
|
||||||
|
err := m.client.AcceptJobs(printerName)
|
||||||
|
if isAuthError(err) && m.pkHelper != nil {
|
||||||
|
err = m.pkHelper.PrinterSetAcceptJobs(printerName, true, "")
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
m.RefreshState()
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Manager) RejectJobs(printerName string) error {
|
||||||
|
err := m.client.RejectJobs(printerName)
|
||||||
|
if isAuthError(err) && m.pkHelper != nil {
|
||||||
|
err = m.pkHelper.PrinterSetAcceptJobs(printerName, false, "")
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
m.RefreshState()
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Manager) SetPrinterShared(printerName string, shared bool) error {
|
||||||
|
err := m.client.SetPrinterIsShared(printerName, shared)
|
||||||
|
if isAuthError(err) && m.pkHelper != nil {
|
||||||
|
err = m.pkHelper.PrinterSetShared(printerName, shared)
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
m.RefreshState()
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Manager) SetPrinterLocation(printerName, location string) error {
|
||||||
|
err := m.client.SetPrinterLocation(printerName, location)
|
||||||
|
if isAuthError(err) && m.pkHelper != nil {
|
||||||
|
err = m.pkHelper.PrinterSetLocation(printerName, location)
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
m.RefreshState()
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Manager) SetPrinterInfo(printerName, info string) error {
|
||||||
|
err := m.client.SetPrinterInformation(printerName, info)
|
||||||
|
if isAuthError(err) && m.pkHelper != nil {
|
||||||
|
err = m.pkHelper.PrinterSetInfo(printerName, info)
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
m.RefreshState()
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Manager) MoveJob(jobID int, destPrinter string) error {
|
||||||
|
err := m.client.MoveJob(jobID, destPrinter)
|
||||||
|
if err == nil {
|
||||||
|
m.RefreshState()
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Manager) PrintTestPage(printerName string) (int, error) {
|
||||||
|
jobID, err := m.client.PrintTestPage(printerName, strings.NewReader(config.TestPage), len(config.TestPage))
|
||||||
|
if err == nil {
|
||||||
|
m.RefreshState()
|
||||||
|
}
|
||||||
|
return jobID, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Manager) AddPrinterToClass(className, printerName string) error {
|
||||||
|
err := m.client.AddPrinterToClass(className, printerName)
|
||||||
|
if isAuthError(err) && m.pkHelper != nil {
|
||||||
|
err = m.pkHelper.ClassAddPrinter(className, printerName)
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
m.RefreshState()
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Manager) RemovePrinterFromClass(className, printerName string) error {
|
||||||
|
err := m.client.DeletePrinterFromClass(className, printerName)
|
||||||
|
if isAuthError(err) && m.pkHelper != nil {
|
||||||
|
err = m.pkHelper.ClassDeletePrinter(className, printerName)
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
m.RefreshState()
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Manager) DeleteClass(className string) error {
|
||||||
|
err := m.client.DeleteClass(className)
|
||||||
|
if isAuthError(err) && m.pkHelper != nil {
|
||||||
|
err = m.pkHelper.ClassDelete(className)
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
m.RefreshState()
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Manager) RestartJob(jobID int) error {
|
||||||
|
err := m.client.RestartJob(jobID)
|
||||||
|
if isAuthError(err) && m.pkHelper != nil {
|
||||||
|
err = m.pkHelper.JobRestart(jobID)
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
m.RefreshState()
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Manager) HoldJob(jobID int, holdUntil string) error {
|
||||||
|
err := m.client.HoldJobUntil(jobID, holdUntil)
|
||||||
|
if isAuthError(err) && m.pkHelper != nil {
|
||||||
|
err = m.pkHelper.JobSetHoldUntil(jobID, holdUntil)
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
m.RefreshState()
|
||||||
|
}
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
235
core/internal/server/cups/actions_pkhelper_test.go
Normal file
235
core/internal/server/cups/actions_pkhelper_test.go
Normal file
@@ -0,0 +1,235 @@
|
|||||||
|
package cups_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
mocks_cups "github.com/AvengeMedia/DankMaterialShell/core/internal/mocks/cups"
|
||||||
|
mocks_pkhelper "github.com/AvengeMedia/DankMaterialShell/core/internal/mocks/cups_pkhelper"
|
||||||
|
"github.com/AvengeMedia/DankMaterialShell/core/internal/server/cups"
|
||||||
|
"github.com/AvengeMedia/DankMaterialShell/core/pkg/ipp"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/mock"
|
||||||
|
)
|
||||||
|
|
||||||
|
func authErr() error {
|
||||||
|
return ipp.IPPError{Status: ipp.StatusErrorForbidden}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestManager_CancelJob_WithPkHelper(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
mockClient.EXPECT().CancelJob(1, false).Return(authErr())
|
||||||
|
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||||
|
|
||||||
|
mockPk := mocks_pkhelper.NewMockPkHelper(t)
|
||||||
|
mockPk.EXPECT().JobCancelPurge(1, false).Return(nil)
|
||||||
|
|
||||||
|
m := cups.NewTestManager(mockClient, mockPk)
|
||||||
|
assert.NoError(t, m.CancelJob(1))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestManager_CancelJob_PkHelperError(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
mockClient.EXPECT().CancelJob(1, false).Return(authErr())
|
||||||
|
|
||||||
|
mockPk := mocks_pkhelper.NewMockPkHelper(t)
|
||||||
|
mockPk.EXPECT().JobCancelPurge(1, false).Return(assert.AnError)
|
||||||
|
|
||||||
|
m := cups.NewTestManager(mockClient, mockPk)
|
||||||
|
assert.Error(t, m.CancelJob(1))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestManager_PausePrinter_WithPkHelper(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
mockClient.EXPECT().PausePrinter("printer1").Return(authErr())
|
||||||
|
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||||
|
|
||||||
|
mockPk := mocks_pkhelper.NewMockPkHelper(t)
|
||||||
|
mockPk.EXPECT().PrinterSetEnabled("printer1", false).Return(nil)
|
||||||
|
|
||||||
|
m := cups.NewTestManager(mockClient, mockPk)
|
||||||
|
assert.NoError(t, m.PausePrinter("printer1"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestManager_ResumePrinter_WithPkHelper(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
mockClient.EXPECT().ResumePrinter("printer1").Return(authErr())
|
||||||
|
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||||
|
|
||||||
|
mockPk := mocks_pkhelper.NewMockPkHelper(t)
|
||||||
|
mockPk.EXPECT().PrinterSetEnabled("printer1", true).Return(nil)
|
||||||
|
|
||||||
|
m := cups.NewTestManager(mockClient, mockPk)
|
||||||
|
assert.NoError(t, m.ResumePrinter("printer1"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestManager_GetDevices_WithPkHelper(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
|
||||||
|
mockPk := mocks_pkhelper.NewMockPkHelper(t)
|
||||||
|
mockPk.EXPECT().DevicesGet(10, 0, []string(nil), []string(nil)).Return([]cups.Device{
|
||||||
|
{URI: "usb://HP/LaserJet", Class: "direct"},
|
||||||
|
}, nil)
|
||||||
|
|
||||||
|
m := cups.NewTestManager(mockClient, mockPk)
|
||||||
|
got, err := m.GetDevices()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Len(t, got, 1)
|
||||||
|
assert.Equal(t, "usb://HP/LaserJet", got[0].URI)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestManager_GetDevices_PkHelperError(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
|
||||||
|
mockPk := mocks_pkhelper.NewMockPkHelper(t)
|
||||||
|
mockPk.EXPECT().DevicesGet(10, 0, []string(nil), []string(nil)).Return(nil, assert.AnError)
|
||||||
|
|
||||||
|
m := cups.NewTestManager(mockClient, mockPk)
|
||||||
|
_, err := m.GetDevices()
|
||||||
|
assert.Error(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestManager_CreatePrinter_WithPkHelper(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
mockClient.EXPECT().CreatePrinter("newprinter", "usb://HP", "generic.ppd", true, "stop-printer", "info", "location").Return(authErr())
|
||||||
|
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||||
|
|
||||||
|
mockPk := mocks_pkhelper.NewMockPkHelper(t)
|
||||||
|
mockPk.EXPECT().PrinterAdd("newprinter", "usb://HP", "generic.ppd", "info", "location").Return(nil)
|
||||||
|
mockPk.EXPECT().PrinterSetEnabled("newprinter", true).Return(nil)
|
||||||
|
mockPk.EXPECT().PrinterSetAcceptJobs("newprinter", true, "").Return(nil)
|
||||||
|
|
||||||
|
m := cups.NewTestManager(mockClient, mockPk)
|
||||||
|
assert.NoError(t, m.CreatePrinter("newprinter", "usb://HP", "generic.ppd", true, "stop-printer", "info", "location"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestManager_DeletePrinter_WithPkHelper(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
mockClient.EXPECT().DeletePrinter("printer1").Return(authErr())
|
||||||
|
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||||
|
|
||||||
|
mockPk := mocks_pkhelper.NewMockPkHelper(t)
|
||||||
|
mockPk.EXPECT().PrinterDelete("printer1").Return(nil)
|
||||||
|
|
||||||
|
m := cups.NewTestManager(mockClient, mockPk)
|
||||||
|
assert.NoError(t, m.DeletePrinter("printer1"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestManager_AcceptJobs_WithPkHelper(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
mockClient.EXPECT().AcceptJobs("printer1").Return(authErr())
|
||||||
|
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||||
|
|
||||||
|
mockPk := mocks_pkhelper.NewMockPkHelper(t)
|
||||||
|
mockPk.EXPECT().PrinterSetAcceptJobs("printer1", true, "").Return(nil)
|
||||||
|
|
||||||
|
m := cups.NewTestManager(mockClient, mockPk)
|
||||||
|
assert.NoError(t, m.AcceptJobs("printer1"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestManager_RejectJobs_WithPkHelper(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
mockClient.EXPECT().RejectJobs("printer1").Return(authErr())
|
||||||
|
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||||
|
|
||||||
|
mockPk := mocks_pkhelper.NewMockPkHelper(t)
|
||||||
|
mockPk.EXPECT().PrinterSetAcceptJobs("printer1", false, "").Return(nil)
|
||||||
|
|
||||||
|
m := cups.NewTestManager(mockClient, mockPk)
|
||||||
|
assert.NoError(t, m.RejectJobs("printer1"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestManager_SetPrinterShared_WithPkHelper(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
mockClient.EXPECT().SetPrinterIsShared("printer1", true).Return(authErr())
|
||||||
|
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||||
|
|
||||||
|
mockPk := mocks_pkhelper.NewMockPkHelper(t)
|
||||||
|
mockPk.EXPECT().PrinterSetShared("printer1", true).Return(nil)
|
||||||
|
|
||||||
|
m := cups.NewTestManager(mockClient, mockPk)
|
||||||
|
assert.NoError(t, m.SetPrinterShared("printer1", true))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestManager_SetPrinterLocation_WithPkHelper(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
mockClient.EXPECT().SetPrinterLocation("printer1", "Office").Return(authErr())
|
||||||
|
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||||
|
|
||||||
|
mockPk := mocks_pkhelper.NewMockPkHelper(t)
|
||||||
|
mockPk.EXPECT().PrinterSetLocation("printer1", "Office").Return(nil)
|
||||||
|
|
||||||
|
m := cups.NewTestManager(mockClient, mockPk)
|
||||||
|
assert.NoError(t, m.SetPrinterLocation("printer1", "Office"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestManager_SetPrinterInfo_WithPkHelper(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
mockClient.EXPECT().SetPrinterInformation("printer1", "Main Printer").Return(authErr())
|
||||||
|
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||||
|
|
||||||
|
mockPk := mocks_pkhelper.NewMockPkHelper(t)
|
||||||
|
mockPk.EXPECT().PrinterSetInfo("printer1", "Main Printer").Return(nil)
|
||||||
|
|
||||||
|
m := cups.NewTestManager(mockClient, mockPk)
|
||||||
|
assert.NoError(t, m.SetPrinterInfo("printer1", "Main Printer"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestManager_AddPrinterToClass_WithPkHelper(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
mockClient.EXPECT().AddPrinterToClass("office", "printer1").Return(authErr())
|
||||||
|
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||||
|
|
||||||
|
mockPk := mocks_pkhelper.NewMockPkHelper(t)
|
||||||
|
mockPk.EXPECT().ClassAddPrinter("office", "printer1").Return(nil)
|
||||||
|
|
||||||
|
m := cups.NewTestManager(mockClient, mockPk)
|
||||||
|
assert.NoError(t, m.AddPrinterToClass("office", "printer1"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestManager_RemovePrinterFromClass_WithPkHelper(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
mockClient.EXPECT().DeletePrinterFromClass("office", "printer1").Return(authErr())
|
||||||
|
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||||
|
|
||||||
|
mockPk := mocks_pkhelper.NewMockPkHelper(t)
|
||||||
|
mockPk.EXPECT().ClassDeletePrinter("office", "printer1").Return(nil)
|
||||||
|
|
||||||
|
m := cups.NewTestManager(mockClient, mockPk)
|
||||||
|
assert.NoError(t, m.RemovePrinterFromClass("office", "printer1"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestManager_DeleteClass_WithPkHelper(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
mockClient.EXPECT().DeleteClass("office").Return(authErr())
|
||||||
|
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||||
|
|
||||||
|
mockPk := mocks_pkhelper.NewMockPkHelper(t)
|
||||||
|
mockPk.EXPECT().ClassDelete("office").Return(nil)
|
||||||
|
|
||||||
|
m := cups.NewTestManager(mockClient, mockPk)
|
||||||
|
assert.NoError(t, m.DeleteClass("office"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestManager_RestartJob_WithPkHelper(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
mockClient.EXPECT().RestartJob(1).Return(authErr())
|
||||||
|
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||||
|
|
||||||
|
mockPk := mocks_pkhelper.NewMockPkHelper(t)
|
||||||
|
mockPk.EXPECT().JobRestart(1).Return(nil)
|
||||||
|
|
||||||
|
m := cups.NewTestManager(mockClient, mockPk)
|
||||||
|
assert.NoError(t, m.RestartJob(1))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestManager_HoldJob_WithPkHelper(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
mockClient.EXPECT().HoldJobUntil(1, "indefinite").Return(authErr())
|
||||||
|
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||||
|
|
||||||
|
mockPk := mocks_pkhelper.NewMockPkHelper(t)
|
||||||
|
mockPk.EXPECT().JobSetHoldUntil(1, "indefinite").Return(nil)
|
||||||
|
|
||||||
|
m := cups.NewTestManager(mockClient, mockPk)
|
||||||
|
assert.NoError(t, m.HoldJob(1, "indefinite"))
|
||||||
|
}
|
||||||
@@ -137,114 +137,30 @@ func TestManager_GetJobs(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestManager_CancelJob(t *testing.T) {
|
func TestManager_CancelJob(t *testing.T) {
|
||||||
tests := []struct {
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
name string
|
mockClient.EXPECT().CancelJob(1, false).Return(nil)
|
||||||
mockErr error
|
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||||
wantErr bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "success",
|
|
||||||
mockErr: nil,
|
|
||||||
wantErr: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "error",
|
|
||||||
mockErr: errors.New("test error"),
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tt := range tests {
|
m := NewTestManager(mockClient, nil)
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
assert.NoError(t, m.CancelJob(1))
|
||||||
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
|
||||||
mockClient.EXPECT().CancelJob(1, false).Return(tt.mockErr)
|
|
||||||
|
|
||||||
m := &Manager{
|
|
||||||
client: mockClient,
|
|
||||||
}
|
|
||||||
|
|
||||||
err := m.CancelJob(1)
|
|
||||||
if tt.wantErr {
|
|
||||||
assert.Error(t, err)
|
|
||||||
} else {
|
|
||||||
assert.NoError(t, err)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestManager_PausePrinter(t *testing.T) {
|
func TestManager_PausePrinter(t *testing.T) {
|
||||||
tests := []struct {
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
name string
|
mockClient.EXPECT().PausePrinter("printer1").Return(nil)
|
||||||
mockErr error
|
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||||
wantErr bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "success",
|
|
||||||
mockErr: nil,
|
|
||||||
wantErr: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "error",
|
|
||||||
mockErr: errors.New("test error"),
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tt := range tests {
|
m := NewTestManager(mockClient, nil)
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
assert.NoError(t, m.PausePrinter("printer1"))
|
||||||
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
|
||||||
mockClient.EXPECT().PausePrinter("printer1").Return(tt.mockErr)
|
|
||||||
|
|
||||||
m := &Manager{
|
|
||||||
client: mockClient,
|
|
||||||
}
|
|
||||||
|
|
||||||
err := m.PausePrinter("printer1")
|
|
||||||
if tt.wantErr {
|
|
||||||
assert.Error(t, err)
|
|
||||||
} else {
|
|
||||||
assert.NoError(t, err)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestManager_ResumePrinter(t *testing.T) {
|
func TestManager_ResumePrinter(t *testing.T) {
|
||||||
tests := []struct {
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
name string
|
mockClient.EXPECT().ResumePrinter("printer1").Return(nil)
|
||||||
mockErr error
|
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||||
wantErr bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "success",
|
|
||||||
mockErr: nil,
|
|
||||||
wantErr: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "error",
|
|
||||||
mockErr: errors.New("test error"),
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tt := range tests {
|
m := NewTestManager(mockClient, nil)
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
assert.NoError(t, m.ResumePrinter("printer1"))
|
||||||
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
|
||||||
mockClient.EXPECT().ResumePrinter("printer1").Return(tt.mockErr)
|
|
||||||
|
|
||||||
m := &Manager{
|
|
||||||
client: mockClient,
|
|
||||||
}
|
|
||||||
|
|
||||||
err := m.ResumePrinter("printer1")
|
|
||||||
if tt.wantErr {
|
|
||||||
assert.Error(t, err)
|
|
||||||
} else {
|
|
||||||
assert.NoError(t, err)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestManager_PurgeJobs(t *testing.T) {
|
func TestManager_PurgeJobs(t *testing.T) {
|
||||||
@@ -269,11 +185,12 @@ func TestManager_PurgeJobs(t *testing.T) {
|
|||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
mockClient.EXPECT().CancelAllJob("printer1", true).Return(tt.mockErr)
|
mockClient.EXPECT().CancelAllJob("printer1", true).Return(tt.mockErr)
|
||||||
|
if !tt.wantErr {
|
||||||
m := &Manager{
|
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||||
client: mockClient,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m := NewTestManager(mockClient, nil)
|
||||||
|
|
||||||
err := m.PurgeJobs("printer1")
|
err := m.PurgeJobs("printer1")
|
||||||
if tt.wantErr {
|
if tt.wantErr {
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
@@ -283,3 +200,251 @@ func TestManager_PurgeJobs(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestManager_GetDevices(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
mockClient.EXPECT().GetDevices().Return(map[string]ipp.Attributes{
|
||||||
|
"usb://HP/LaserJet": {
|
||||||
|
"device-class": []ipp.Attribute{{Value: "direct"}},
|
||||||
|
"device-info": []ipp.Attribute{{Value: "HP LaserJet"}},
|
||||||
|
"device-make-and-model": []ipp.Attribute{{Value: "HP LaserJet 1020"}},
|
||||||
|
},
|
||||||
|
}, nil)
|
||||||
|
|
||||||
|
m := &Manager{client: mockClient}
|
||||||
|
got, err := m.GetDevices()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Len(t, got, 1)
|
||||||
|
assert.Equal(t, "usb://HP/LaserJet", got[0].URI)
|
||||||
|
assert.Equal(t, "direct", got[0].Class)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestManager_GetPPDs(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
mockRet map[string]ipp.Attributes
|
||||||
|
mockErr error
|
||||||
|
want int
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "success",
|
||||||
|
mockRet: map[string]ipp.Attributes{
|
||||||
|
"drv:///sample.drv/generic.ppd": {
|
||||||
|
"ppd-make-and-model": []ipp.Attribute{{Value: "Generic PostScript"}},
|
||||||
|
"ppd-type": []ipp.Attribute{{Value: "ppd"}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mockErr: nil,
|
||||||
|
want: 1,
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "error",
|
||||||
|
mockRet: nil,
|
||||||
|
mockErr: errors.New("test error"),
|
||||||
|
want: 0,
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
mockClient.EXPECT().GetPPDs().Return(tt.mockRet, tt.mockErr)
|
||||||
|
|
||||||
|
m := &Manager{client: mockClient}
|
||||||
|
|
||||||
|
got, err := m.GetPPDs()
|
||||||
|
if tt.wantErr {
|
||||||
|
assert.Error(t, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, tt.want, len(got))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestManager_GetClasses(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
mockRet map[string]ipp.Attributes
|
||||||
|
mockErr error
|
||||||
|
want int
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "success",
|
||||||
|
mockRet: map[string]ipp.Attributes{
|
||||||
|
"office": {
|
||||||
|
ipp.AttributePrinterName: []ipp.Attribute{{Value: "office"}},
|
||||||
|
ipp.AttributePrinterState: []ipp.Attribute{{Value: 3}},
|
||||||
|
ipp.AttributeMemberNames: []ipp.Attribute{{Value: "printer1"}, {Value: "printer2"}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mockErr: nil,
|
||||||
|
want: 1,
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "error",
|
||||||
|
mockRet: nil,
|
||||||
|
mockErr: errors.New("test error"),
|
||||||
|
want: 0,
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
mockClient.EXPECT().GetClasses(mock.Anything).Return(tt.mockRet, tt.mockErr)
|
||||||
|
|
||||||
|
m := &Manager{client: mockClient}
|
||||||
|
|
||||||
|
got, err := m.GetClasses()
|
||||||
|
if tt.wantErr {
|
||||||
|
assert.Error(t, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, tt.want, len(got))
|
||||||
|
if len(got) > 0 {
|
||||||
|
assert.Equal(t, "office", got[0].Name)
|
||||||
|
assert.Equal(t, 2, len(got[0].Members))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestManager_CreatePrinter(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
mockClient.EXPECT().CreatePrinter("newprinter", "usb://HP", "generic.ppd", true, "stop-printer", "info", "location").Return(nil)
|
||||||
|
mockClient.EXPECT().ResumePrinter("newprinter").Return(nil)
|
||||||
|
mockClient.EXPECT().AcceptJobs("newprinter").Return(nil)
|
||||||
|
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||||
|
|
||||||
|
m := NewTestManager(mockClient, nil)
|
||||||
|
assert.NoError(t, m.CreatePrinter("newprinter", "usb://HP", "generic.ppd", true, "stop-printer", "info", "location"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestManager_DeletePrinter(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
mockClient.EXPECT().DeletePrinter("printer1").Return(nil)
|
||||||
|
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||||
|
|
||||||
|
m := NewTestManager(mockClient, nil)
|
||||||
|
assert.NoError(t, m.DeletePrinter("printer1"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestManager_AcceptJobs(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
mockClient.EXPECT().AcceptJobs("printer1").Return(nil)
|
||||||
|
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||||
|
|
||||||
|
m := NewTestManager(mockClient, nil)
|
||||||
|
assert.NoError(t, m.AcceptJobs("printer1"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestManager_RejectJobs(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
mockClient.EXPECT().RejectJobs("printer1").Return(nil)
|
||||||
|
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||||
|
|
||||||
|
m := NewTestManager(mockClient, nil)
|
||||||
|
assert.NoError(t, m.RejectJobs("printer1"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestManager_SetPrinterShared(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
mockClient.EXPECT().SetPrinterIsShared("printer1", true).Return(nil)
|
||||||
|
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||||
|
|
||||||
|
m := NewTestManager(mockClient, nil)
|
||||||
|
assert.NoError(t, m.SetPrinterShared("printer1", true))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestManager_SetPrinterLocation(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
mockClient.EXPECT().SetPrinterLocation("printer1", "Office").Return(nil)
|
||||||
|
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||||
|
|
||||||
|
m := NewTestManager(mockClient, nil)
|
||||||
|
assert.NoError(t, m.SetPrinterLocation("printer1", "Office"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestManager_SetPrinterInfo(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
mockClient.EXPECT().SetPrinterInformation("printer1", "Main Printer").Return(nil)
|
||||||
|
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||||
|
|
||||||
|
m := NewTestManager(mockClient, nil)
|
||||||
|
assert.NoError(t, m.SetPrinterInfo("printer1", "Main Printer"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestManager_MoveJob(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
mockClient.EXPECT().MoveJob(1, "printer2").Return(nil)
|
||||||
|
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||||
|
|
||||||
|
m := NewTestManager(mockClient, nil)
|
||||||
|
err := m.MoveJob(1, "printer2")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestManager_PrintTestPage(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
mockClient.EXPECT().PrintTestPage("printer1", mock.Anything, mock.Anything).Return(42, nil)
|
||||||
|
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||||
|
|
||||||
|
m := NewTestManager(mockClient, nil)
|
||||||
|
jobID, err := m.PrintTestPage("printer1")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, 42, jobID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestManager_AddPrinterToClass(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
mockClient.EXPECT().AddPrinterToClass("office", "printer1").Return(nil)
|
||||||
|
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||||
|
|
||||||
|
m := NewTestManager(mockClient, nil)
|
||||||
|
assert.NoError(t, m.AddPrinterToClass("office", "printer1"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestManager_RemovePrinterFromClass(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
mockClient.EXPECT().DeletePrinterFromClass("office", "printer1").Return(nil)
|
||||||
|
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||||
|
|
||||||
|
m := NewTestManager(mockClient, nil)
|
||||||
|
assert.NoError(t, m.RemovePrinterFromClass("office", "printer1"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestManager_DeleteClass(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
mockClient.EXPECT().DeleteClass("office").Return(nil)
|
||||||
|
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||||
|
|
||||||
|
m := NewTestManager(mockClient, nil)
|
||||||
|
assert.NoError(t, m.DeleteClass("office"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestManager_RestartJob(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
mockClient.EXPECT().RestartJob(1).Return(nil)
|
||||||
|
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||||
|
|
||||||
|
m := NewTestManager(mockClient, nil)
|
||||||
|
assert.NoError(t, m.RestartJob(1))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestManager_HoldJob(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
mockClient.EXPECT().HoldJobUntil(1, "indefinite").Return(nil)
|
||||||
|
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||||
|
|
||||||
|
m := NewTestManager(mockClient, nil)
|
||||||
|
assert.NoError(t, m.HoldJob(1, "indefinite"))
|
||||||
|
}
|
||||||
|
|||||||
@@ -40,6 +40,40 @@ func HandleRequest(conn net.Conn, req Request, manager *Manager) {
|
|||||||
handleCancelJob(conn, req, manager)
|
handleCancelJob(conn, req, manager)
|
||||||
case "cups.purgeJobs":
|
case "cups.purgeJobs":
|
||||||
handlePurgeJobs(conn, req, manager)
|
handlePurgeJobs(conn, req, manager)
|
||||||
|
case "cups.getDevices":
|
||||||
|
handleGetDevices(conn, req, manager)
|
||||||
|
case "cups.getPPDs":
|
||||||
|
handleGetPPDs(conn, req, manager)
|
||||||
|
case "cups.getClasses":
|
||||||
|
handleGetClasses(conn, req, manager)
|
||||||
|
case "cups.createPrinter":
|
||||||
|
handleCreatePrinter(conn, req, manager)
|
||||||
|
case "cups.deletePrinter":
|
||||||
|
handleDeletePrinter(conn, req, manager)
|
||||||
|
case "cups.acceptJobs":
|
||||||
|
handleAcceptJobs(conn, req, manager)
|
||||||
|
case "cups.rejectJobs":
|
||||||
|
handleRejectJobs(conn, req, manager)
|
||||||
|
case "cups.setPrinterShared":
|
||||||
|
handleSetPrinterShared(conn, req, manager)
|
||||||
|
case "cups.setPrinterLocation":
|
||||||
|
handleSetPrinterLocation(conn, req, manager)
|
||||||
|
case "cups.setPrinterInfo":
|
||||||
|
handleSetPrinterInfo(conn, req, manager)
|
||||||
|
case "cups.moveJob":
|
||||||
|
handleMoveJob(conn, req, manager)
|
||||||
|
case "cups.printTestPage":
|
||||||
|
handlePrintTestPage(conn, req, manager)
|
||||||
|
case "cups.addPrinterToClass":
|
||||||
|
handleAddPrinterToClass(conn, req, manager)
|
||||||
|
case "cups.removePrinterFromClass":
|
||||||
|
handleRemovePrinterFromClass(conn, req, manager)
|
||||||
|
case "cups.deleteClass":
|
||||||
|
handleDeleteClass(conn, req, manager)
|
||||||
|
case "cups.restartJob":
|
||||||
|
handleRestartJob(conn, req, manager)
|
||||||
|
case "cups.holdJob":
|
||||||
|
handleHoldJob(conn, req, manager)
|
||||||
default:
|
default:
|
||||||
models.RespondError(conn, req.ID, fmt.Sprintf("unknown method: %s", req.Method))
|
models.RespondError(conn, req.ID, fmt.Sprintf("unknown method: %s", req.Method))
|
||||||
}
|
}
|
||||||
@@ -158,3 +192,291 @@ func handleSubscribe(conn net.Conn, req Request, manager *Manager) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func handleGetDevices(conn net.Conn, req Request, manager *Manager) {
|
||||||
|
devices, err := manager.GetDevices()
|
||||||
|
if err != nil {
|
||||||
|
models.RespondError(conn, req.ID, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
models.Respond(conn, req.ID, devices)
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleGetPPDs(conn net.Conn, req Request, manager *Manager) {
|
||||||
|
ppds, err := manager.GetPPDs()
|
||||||
|
if err != nil {
|
||||||
|
models.RespondError(conn, req.ID, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
models.Respond(conn, req.ID, ppds)
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleGetClasses(conn net.Conn, req Request, manager *Manager) {
|
||||||
|
classes, err := manager.GetClasses()
|
||||||
|
if err != nil {
|
||||||
|
models.RespondError(conn, req.ID, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
models.Respond(conn, req.ID, classes)
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleCreatePrinter(conn net.Conn, req Request, manager *Manager) {
|
||||||
|
name, ok := req.Params["name"].(string)
|
||||||
|
if !ok || name == "" {
|
||||||
|
models.RespondError(conn, req.ID, "missing or invalid 'name' parameter")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
deviceURI, ok := req.Params["deviceURI"].(string)
|
||||||
|
if !ok || deviceURI == "" {
|
||||||
|
models.RespondError(conn, req.ID, "missing or invalid 'deviceURI' parameter")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ppd, ok := req.Params["ppd"].(string)
|
||||||
|
if !ok || ppd == "" {
|
||||||
|
models.RespondError(conn, req.ID, "missing or invalid 'ppd' parameter")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
shared, _ := req.Params["shared"].(bool)
|
||||||
|
errorPolicy, _ := req.Params["errorPolicy"].(string)
|
||||||
|
information, _ := req.Params["information"].(string)
|
||||||
|
location, _ := req.Params["location"].(string)
|
||||||
|
|
||||||
|
if err := manager.CreatePrinter(name, deviceURI, ppd, shared, errorPolicy, information, location); err != nil {
|
||||||
|
models.RespondError(conn, req.ID, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
models.Respond(conn, req.ID, SuccessResult{Success: true, Message: "printer created"})
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleDeletePrinter(conn net.Conn, req Request, manager *Manager) {
|
||||||
|
printerName, ok := req.Params["printerName"].(string)
|
||||||
|
if !ok || printerName == "" {
|
||||||
|
models.RespondError(conn, req.ID, "missing or invalid 'printerName' parameter")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := manager.DeletePrinter(printerName); err != nil {
|
||||||
|
models.RespondError(conn, req.ID, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
models.Respond(conn, req.ID, SuccessResult{Success: true, Message: "printer deleted"})
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleAcceptJobs(conn net.Conn, req Request, manager *Manager) {
|
||||||
|
printerName, ok := req.Params["printerName"].(string)
|
||||||
|
if !ok || printerName == "" {
|
||||||
|
models.RespondError(conn, req.ID, "missing or invalid 'printerName' parameter")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := manager.AcceptJobs(printerName); err != nil {
|
||||||
|
models.RespondError(conn, req.ID, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
models.Respond(conn, req.ID, SuccessResult{Success: true, Message: "accepting jobs"})
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleRejectJobs(conn net.Conn, req Request, manager *Manager) {
|
||||||
|
printerName, ok := req.Params["printerName"].(string)
|
||||||
|
if !ok || printerName == "" {
|
||||||
|
models.RespondError(conn, req.ID, "missing or invalid 'printerName' parameter")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := manager.RejectJobs(printerName); err != nil {
|
||||||
|
models.RespondError(conn, req.ID, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
models.Respond(conn, req.ID, SuccessResult{Success: true, Message: "rejecting jobs"})
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleSetPrinterShared(conn net.Conn, req Request, manager *Manager) {
|
||||||
|
printerName, ok := req.Params["printerName"].(string)
|
||||||
|
if !ok || printerName == "" {
|
||||||
|
models.RespondError(conn, req.ID, "missing or invalid 'printerName' parameter")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
shared, ok := req.Params["shared"].(bool)
|
||||||
|
if !ok {
|
||||||
|
models.RespondError(conn, req.ID, "missing or invalid 'shared' parameter")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := manager.SetPrinterShared(printerName, shared); err != nil {
|
||||||
|
models.RespondError(conn, req.ID, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
models.Respond(conn, req.ID, SuccessResult{Success: true, Message: "sharing updated"})
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleSetPrinterLocation(conn net.Conn, req Request, manager *Manager) {
|
||||||
|
printerName, ok := req.Params["printerName"].(string)
|
||||||
|
if !ok || printerName == "" {
|
||||||
|
models.RespondError(conn, req.ID, "missing or invalid 'printerName' parameter")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
location, ok := req.Params["location"].(string)
|
||||||
|
if !ok {
|
||||||
|
models.RespondError(conn, req.ID, "missing or invalid 'location' parameter")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := manager.SetPrinterLocation(printerName, location); err != nil {
|
||||||
|
models.RespondError(conn, req.ID, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
models.Respond(conn, req.ID, SuccessResult{Success: true, Message: "location updated"})
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleSetPrinterInfo(conn net.Conn, req Request, manager *Manager) {
|
||||||
|
printerName, ok := req.Params["printerName"].(string)
|
||||||
|
if !ok || printerName == "" {
|
||||||
|
models.RespondError(conn, req.ID, "missing or invalid 'printerName' parameter")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
info, ok := req.Params["info"].(string)
|
||||||
|
if !ok {
|
||||||
|
models.RespondError(conn, req.ID, "missing or invalid 'info' parameter")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := manager.SetPrinterInfo(printerName, info); err != nil {
|
||||||
|
models.RespondError(conn, req.ID, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
models.Respond(conn, req.ID, SuccessResult{Success: true, Message: "info updated"})
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleMoveJob(conn net.Conn, req Request, manager *Manager) {
|
||||||
|
jobIDFloat, ok := req.Params["jobID"].(float64)
|
||||||
|
if !ok {
|
||||||
|
models.RespondError(conn, req.ID, "missing or invalid 'jobID' parameter")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
destPrinter, ok := req.Params["destPrinter"].(string)
|
||||||
|
if !ok || destPrinter == "" {
|
||||||
|
models.RespondError(conn, req.ID, "missing or invalid 'destPrinter' parameter")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := manager.MoveJob(int(jobIDFloat), destPrinter); err != nil {
|
||||||
|
models.RespondError(conn, req.ID, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
models.Respond(conn, req.ID, SuccessResult{Success: true, Message: "job moved"})
|
||||||
|
}
|
||||||
|
|
||||||
|
type TestPageResult struct {
|
||||||
|
Success bool `json:"success"`
|
||||||
|
JobID int `json:"jobId"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func handlePrintTestPage(conn net.Conn, req Request, manager *Manager) {
|
||||||
|
printerName, ok := req.Params["printerName"].(string)
|
||||||
|
if !ok || printerName == "" {
|
||||||
|
models.RespondError(conn, req.ID, "missing or invalid 'printerName' parameter")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
jobID, err := manager.PrintTestPage(printerName)
|
||||||
|
if err != nil {
|
||||||
|
models.RespondError(conn, req.ID, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
models.Respond(conn, req.ID, TestPageResult{Success: true, JobID: jobID, Message: "test page queued"})
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleAddPrinterToClass(conn net.Conn, req Request, manager *Manager) {
|
||||||
|
className, ok := req.Params["className"].(string)
|
||||||
|
if !ok || className == "" {
|
||||||
|
models.RespondError(conn, req.ID, "missing or invalid 'className' parameter")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
printerName, ok := req.Params["printerName"].(string)
|
||||||
|
if !ok || printerName == "" {
|
||||||
|
models.RespondError(conn, req.ID, "missing or invalid 'printerName' parameter")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := manager.AddPrinterToClass(className, printerName); err != nil {
|
||||||
|
models.RespondError(conn, req.ID, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
models.Respond(conn, req.ID, SuccessResult{Success: true, Message: "printer added to class"})
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleRemovePrinterFromClass(conn net.Conn, req Request, manager *Manager) {
|
||||||
|
className, ok := req.Params["className"].(string)
|
||||||
|
if !ok || className == "" {
|
||||||
|
models.RespondError(conn, req.ID, "missing or invalid 'className' parameter")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
printerName, ok := req.Params["printerName"].(string)
|
||||||
|
if !ok || printerName == "" {
|
||||||
|
models.RespondError(conn, req.ID, "missing or invalid 'printerName' parameter")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := manager.RemovePrinterFromClass(className, printerName); err != nil {
|
||||||
|
models.RespondError(conn, req.ID, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
models.Respond(conn, req.ID, SuccessResult{Success: true, Message: "printer removed from class"})
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleDeleteClass(conn net.Conn, req Request, manager *Manager) {
|
||||||
|
className, ok := req.Params["className"].(string)
|
||||||
|
if !ok || className == "" {
|
||||||
|
models.RespondError(conn, req.ID, "missing or invalid 'className' parameter")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := manager.DeleteClass(className); err != nil {
|
||||||
|
models.RespondError(conn, req.ID, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
models.Respond(conn, req.ID, SuccessResult{Success: true, Message: "class deleted"})
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleRestartJob(conn net.Conn, req Request, manager *Manager) {
|
||||||
|
jobIDFloat, ok := req.Params["jobID"].(float64)
|
||||||
|
if !ok {
|
||||||
|
models.RespondError(conn, req.ID, "missing or invalid 'jobID' parameter")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := manager.RestartJob(int(jobIDFloat)); err != nil {
|
||||||
|
models.RespondError(conn, req.ID, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
models.Respond(conn, req.ID, SuccessResult{Success: true, Message: "job restarted"})
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleHoldJob(conn net.Conn, req Request, manager *Manager) {
|
||||||
|
jobIDFloat, ok := req.Params["jobID"].(float64)
|
||||||
|
if !ok {
|
||||||
|
models.RespondError(conn, req.ID, "missing or invalid 'jobID' parameter")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
holdUntil, _ := req.Params["holdUntil"].(string)
|
||||||
|
if holdUntil == "" {
|
||||||
|
holdUntil = "indefinite"
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := manager.HoldJob(int(jobIDFloat), holdUntil); err != nil {
|
||||||
|
models.RespondError(conn, req.ID, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
models.Respond(conn, req.ID, SuccessResult{Success: true, Message: "job held"})
|
||||||
|
}
|
||||||
|
|||||||
@@ -145,10 +145,9 @@ func TestHandleGetJobs_MissingParam(t *testing.T) {
|
|||||||
func TestHandlePausePrinter(t *testing.T) {
|
func TestHandlePausePrinter(t *testing.T) {
|
||||||
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
mockClient.EXPECT().PausePrinter("printer1").Return(nil)
|
mockClient.EXPECT().PausePrinter("printer1").Return(nil)
|
||||||
|
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||||
|
|
||||||
m := &Manager{
|
m := NewTestManager(mockClient, nil)
|
||||||
client: mockClient,
|
|
||||||
}
|
|
||||||
|
|
||||||
buf := &bytes.Buffer{}
|
buf := &bytes.Buffer{}
|
||||||
conn := &mockConn{Buffer: buf}
|
conn := &mockConn{Buffer: buf}
|
||||||
@@ -173,10 +172,9 @@ func TestHandlePausePrinter(t *testing.T) {
|
|||||||
func TestHandleResumePrinter(t *testing.T) {
|
func TestHandleResumePrinter(t *testing.T) {
|
||||||
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
mockClient.EXPECT().ResumePrinter("printer1").Return(nil)
|
mockClient.EXPECT().ResumePrinter("printer1").Return(nil)
|
||||||
|
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||||
|
|
||||||
m := &Manager{
|
m := NewTestManager(mockClient, nil)
|
||||||
client: mockClient,
|
|
||||||
}
|
|
||||||
|
|
||||||
buf := &bytes.Buffer{}
|
buf := &bytes.Buffer{}
|
||||||
conn := &mockConn{Buffer: buf}
|
conn := &mockConn{Buffer: buf}
|
||||||
@@ -201,10 +199,9 @@ func TestHandleResumePrinter(t *testing.T) {
|
|||||||
func TestHandleCancelJob(t *testing.T) {
|
func TestHandleCancelJob(t *testing.T) {
|
||||||
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
mockClient.EXPECT().CancelJob(1, false).Return(nil)
|
mockClient.EXPECT().CancelJob(1, false).Return(nil)
|
||||||
|
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||||
|
|
||||||
m := &Manager{
|
m := NewTestManager(mockClient, nil)
|
||||||
client: mockClient,
|
|
||||||
}
|
|
||||||
|
|
||||||
buf := &bytes.Buffer{}
|
buf := &bytes.Buffer{}
|
||||||
conn := &mockConn{Buffer: buf}
|
conn := &mockConn{Buffer: buf}
|
||||||
@@ -229,10 +226,9 @@ func TestHandleCancelJob(t *testing.T) {
|
|||||||
func TestHandlePurgeJobs(t *testing.T) {
|
func TestHandlePurgeJobs(t *testing.T) {
|
||||||
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
mockClient.EXPECT().CancelAllJob("printer1", true).Return(nil)
|
mockClient.EXPECT().CancelAllJob("printer1", true).Return(nil)
|
||||||
|
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||||
|
|
||||||
m := &Manager{
|
m := NewTestManager(mockClient, nil)
|
||||||
client: mockClient,
|
|
||||||
}
|
|
||||||
|
|
||||||
buf := &bytes.Buffer{}
|
buf := &bytes.Buffer{}
|
||||||
conn := &mockConn{Buffer: buf}
|
conn := &mockConn{Buffer: buf}
|
||||||
@@ -277,3 +273,439 @@ func TestHandleRequest_UnknownMethod(t *testing.T) {
|
|||||||
assert.Nil(t, resp.Result)
|
assert.Nil(t, resp.Result)
|
||||||
assert.NotNil(t, resp.Error)
|
assert.NotNil(t, resp.Error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestHandleGetDevices(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
mockClient.EXPECT().GetDevices().Return(map[string]ipp.Attributes{
|
||||||
|
"usb://HP/LaserJet": {
|
||||||
|
"device-class": []ipp.Attribute{{Value: "direct"}},
|
||||||
|
"device-info": []ipp.Attribute{{Value: "HP LaserJet"}},
|
||||||
|
},
|
||||||
|
}, nil)
|
||||||
|
|
||||||
|
m := &Manager{client: mockClient}
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
conn := &mockConn{Buffer: buf}
|
||||||
|
|
||||||
|
req := Request{ID: 1, Method: "cups.getDevices"}
|
||||||
|
handleGetDevices(conn, req, m)
|
||||||
|
|
||||||
|
var resp models.Response[[]Device]
|
||||||
|
err := json.NewDecoder(buf).Decode(&resp)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, resp.Result)
|
||||||
|
assert.Equal(t, 1, len(*resp.Result))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHandleGetPPDs(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
mockClient.EXPECT().GetPPDs().Return(map[string]ipp.Attributes{
|
||||||
|
"generic.ppd": {
|
||||||
|
"ppd-make-and-model": []ipp.Attribute{{Value: "Generic"}},
|
||||||
|
},
|
||||||
|
}, nil)
|
||||||
|
|
||||||
|
m := &Manager{client: mockClient}
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
conn := &mockConn{Buffer: buf}
|
||||||
|
|
||||||
|
req := Request{ID: 1, Method: "cups.getPPDs"}
|
||||||
|
handleGetPPDs(conn, req, m)
|
||||||
|
|
||||||
|
var resp models.Response[[]PPD]
|
||||||
|
err := json.NewDecoder(buf).Decode(&resp)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, resp.Result)
|
||||||
|
assert.Equal(t, 1, len(*resp.Result))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHandleGetClasses(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
mockClient.EXPECT().GetClasses(mock.Anything).Return(map[string]ipp.Attributes{
|
||||||
|
"office": {
|
||||||
|
ipp.AttributePrinterName: []ipp.Attribute{{Value: "office"}},
|
||||||
|
ipp.AttributePrinterState: []ipp.Attribute{{Value: 3}},
|
||||||
|
},
|
||||||
|
}, nil)
|
||||||
|
|
||||||
|
m := &Manager{client: mockClient}
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
conn := &mockConn{Buffer: buf}
|
||||||
|
|
||||||
|
req := Request{ID: 1, Method: "cups.getClasses"}
|
||||||
|
handleGetClasses(conn, req, m)
|
||||||
|
|
||||||
|
var resp models.Response[[]PrinterClass]
|
||||||
|
err := json.NewDecoder(buf).Decode(&resp)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, resp.Result)
|
||||||
|
assert.Equal(t, 1, len(*resp.Result))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHandleCreatePrinter(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
mockClient.EXPECT().CreatePrinter("newprinter", "usb://HP", "generic.ppd", false, "", "", "").Return(nil)
|
||||||
|
mockClient.EXPECT().ResumePrinter("newprinter").Return(nil)
|
||||||
|
mockClient.EXPECT().AcceptJobs("newprinter").Return(nil)
|
||||||
|
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||||
|
|
||||||
|
m := NewTestManager(mockClient, nil)
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
conn := &mockConn{Buffer: buf}
|
||||||
|
|
||||||
|
req := Request{
|
||||||
|
ID: 1,
|
||||||
|
Method: "cups.createPrinter",
|
||||||
|
Params: map[string]interface{}{
|
||||||
|
"name": "newprinter",
|
||||||
|
"deviceURI": "usb://HP",
|
||||||
|
"ppd": "generic.ppd",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
handleCreatePrinter(conn, req, m)
|
||||||
|
|
||||||
|
var resp models.Response[SuccessResult]
|
||||||
|
err := json.NewDecoder(buf).Decode(&resp)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, resp.Result)
|
||||||
|
assert.True(t, resp.Result.Success)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHandleCreatePrinter_MissingParams(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
m := &Manager{client: mockClient}
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
conn := &mockConn{Buffer: buf}
|
||||||
|
|
||||||
|
req := Request{ID: 1, Method: "cups.createPrinter", Params: map[string]interface{}{}}
|
||||||
|
handleCreatePrinter(conn, req, m)
|
||||||
|
|
||||||
|
var resp models.Response[interface{}]
|
||||||
|
err := json.NewDecoder(buf).Decode(&resp)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Nil(t, resp.Result)
|
||||||
|
assert.NotNil(t, resp.Error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHandleDeletePrinter(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
mockClient.EXPECT().DeletePrinter("printer1").Return(nil)
|
||||||
|
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||||
|
|
||||||
|
m := NewTestManager(mockClient, nil)
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
conn := &mockConn{Buffer: buf}
|
||||||
|
|
||||||
|
req := Request{
|
||||||
|
ID: 1,
|
||||||
|
Method: "cups.deletePrinter",
|
||||||
|
Params: map[string]interface{}{"printerName": "printer1"},
|
||||||
|
}
|
||||||
|
handleDeletePrinter(conn, req, m)
|
||||||
|
|
||||||
|
var resp models.Response[SuccessResult]
|
||||||
|
err := json.NewDecoder(buf).Decode(&resp)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, resp.Result)
|
||||||
|
assert.True(t, resp.Result.Success)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHandleAcceptJobs(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
mockClient.EXPECT().AcceptJobs("printer1").Return(nil)
|
||||||
|
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||||
|
|
||||||
|
m := NewTestManager(mockClient, nil)
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
conn := &mockConn{Buffer: buf}
|
||||||
|
|
||||||
|
req := Request{
|
||||||
|
ID: 1,
|
||||||
|
Method: "cups.acceptJobs",
|
||||||
|
Params: map[string]interface{}{"printerName": "printer1"},
|
||||||
|
}
|
||||||
|
handleAcceptJobs(conn, req, m)
|
||||||
|
|
||||||
|
var resp models.Response[SuccessResult]
|
||||||
|
err := json.NewDecoder(buf).Decode(&resp)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, resp.Result)
|
||||||
|
assert.True(t, resp.Result.Success)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHandleRejectJobs(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
mockClient.EXPECT().RejectJobs("printer1").Return(nil)
|
||||||
|
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||||
|
|
||||||
|
m := NewTestManager(mockClient, nil)
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
conn := &mockConn{Buffer: buf}
|
||||||
|
|
||||||
|
req := Request{
|
||||||
|
ID: 1,
|
||||||
|
Method: "cups.rejectJobs",
|
||||||
|
Params: map[string]interface{}{"printerName": "printer1"},
|
||||||
|
}
|
||||||
|
handleRejectJobs(conn, req, m)
|
||||||
|
|
||||||
|
var resp models.Response[SuccessResult]
|
||||||
|
err := json.NewDecoder(buf).Decode(&resp)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, resp.Result)
|
||||||
|
assert.True(t, resp.Result.Success)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHandleSetPrinterShared(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
mockClient.EXPECT().SetPrinterIsShared("printer1", true).Return(nil)
|
||||||
|
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||||
|
|
||||||
|
m := NewTestManager(mockClient, nil)
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
conn := &mockConn{Buffer: buf}
|
||||||
|
|
||||||
|
req := Request{
|
||||||
|
ID: 1,
|
||||||
|
Method: "cups.setPrinterShared",
|
||||||
|
Params: map[string]interface{}{"printerName": "printer1", "shared": true},
|
||||||
|
}
|
||||||
|
handleSetPrinterShared(conn, req, m)
|
||||||
|
|
||||||
|
var resp models.Response[SuccessResult]
|
||||||
|
err := json.NewDecoder(buf).Decode(&resp)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, resp.Result)
|
||||||
|
assert.True(t, resp.Result.Success)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHandleSetPrinterLocation(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
mockClient.EXPECT().SetPrinterLocation("printer1", "Office").Return(nil)
|
||||||
|
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||||
|
|
||||||
|
m := NewTestManager(mockClient, nil)
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
conn := &mockConn{Buffer: buf}
|
||||||
|
|
||||||
|
req := Request{
|
||||||
|
ID: 1,
|
||||||
|
Method: "cups.setPrinterLocation",
|
||||||
|
Params: map[string]interface{}{"printerName": "printer1", "location": "Office"},
|
||||||
|
}
|
||||||
|
handleSetPrinterLocation(conn, req, m)
|
||||||
|
|
||||||
|
var resp models.Response[SuccessResult]
|
||||||
|
err := json.NewDecoder(buf).Decode(&resp)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, resp.Result)
|
||||||
|
assert.True(t, resp.Result.Success)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHandleSetPrinterInfo(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
mockClient.EXPECT().SetPrinterInformation("printer1", "Main Printer").Return(nil)
|
||||||
|
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||||
|
|
||||||
|
m := NewTestManager(mockClient, nil)
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
conn := &mockConn{Buffer: buf}
|
||||||
|
|
||||||
|
req := Request{
|
||||||
|
ID: 1,
|
||||||
|
Method: "cups.setPrinterInfo",
|
||||||
|
Params: map[string]interface{}{"printerName": "printer1", "info": "Main Printer"},
|
||||||
|
}
|
||||||
|
handleSetPrinterInfo(conn, req, m)
|
||||||
|
|
||||||
|
var resp models.Response[SuccessResult]
|
||||||
|
err := json.NewDecoder(buf).Decode(&resp)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, resp.Result)
|
||||||
|
assert.True(t, resp.Result.Success)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHandleMoveJob(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
mockClient.EXPECT().MoveJob(1, "printer2").Return(nil)
|
||||||
|
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||||
|
|
||||||
|
m := NewTestManager(mockClient, nil)
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
conn := &mockConn{Buffer: buf}
|
||||||
|
|
||||||
|
req := Request{
|
||||||
|
ID: 1,
|
||||||
|
Method: "cups.moveJob",
|
||||||
|
Params: map[string]interface{}{"jobID": float64(1), "destPrinter": "printer2"},
|
||||||
|
}
|
||||||
|
handleMoveJob(conn, req, m)
|
||||||
|
|
||||||
|
var resp models.Response[SuccessResult]
|
||||||
|
err := json.NewDecoder(buf).Decode(&resp)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, resp.Result)
|
||||||
|
assert.True(t, resp.Result.Success)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHandlePrintTestPage(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
mockClient.EXPECT().PrintTestPage("printer1", mock.Anything, mock.Anything).Return(42, nil)
|
||||||
|
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||||
|
|
||||||
|
m := NewTestManager(mockClient, nil)
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
conn := &mockConn{Buffer: buf}
|
||||||
|
|
||||||
|
req := Request{
|
||||||
|
ID: 1,
|
||||||
|
Method: "cups.printTestPage",
|
||||||
|
Params: map[string]interface{}{"printerName": "printer1"},
|
||||||
|
}
|
||||||
|
handlePrintTestPage(conn, req, m)
|
||||||
|
|
||||||
|
var resp models.Response[TestPageResult]
|
||||||
|
err := json.NewDecoder(buf).Decode(&resp)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, resp.Result)
|
||||||
|
assert.True(t, resp.Result.Success)
|
||||||
|
assert.Equal(t, 42, resp.Result.JobID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHandleAddPrinterToClass(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
mockClient.EXPECT().AddPrinterToClass("office", "printer1").Return(nil)
|
||||||
|
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||||
|
|
||||||
|
m := NewTestManager(mockClient, nil)
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
conn := &mockConn{Buffer: buf}
|
||||||
|
|
||||||
|
req := Request{
|
||||||
|
ID: 1,
|
||||||
|
Method: "cups.addPrinterToClass",
|
||||||
|
Params: map[string]interface{}{"className": "office", "printerName": "printer1"},
|
||||||
|
}
|
||||||
|
handleAddPrinterToClass(conn, req, m)
|
||||||
|
|
||||||
|
var resp models.Response[SuccessResult]
|
||||||
|
err := json.NewDecoder(buf).Decode(&resp)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, resp.Result)
|
||||||
|
assert.True(t, resp.Result.Success)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHandleRemovePrinterFromClass(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
mockClient.EXPECT().DeletePrinterFromClass("office", "printer1").Return(nil)
|
||||||
|
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||||
|
|
||||||
|
m := NewTestManager(mockClient, nil)
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
conn := &mockConn{Buffer: buf}
|
||||||
|
|
||||||
|
req := Request{
|
||||||
|
ID: 1,
|
||||||
|
Method: "cups.removePrinterFromClass",
|
||||||
|
Params: map[string]interface{}{"className": "office", "printerName": "printer1"},
|
||||||
|
}
|
||||||
|
handleRemovePrinterFromClass(conn, req, m)
|
||||||
|
|
||||||
|
var resp models.Response[SuccessResult]
|
||||||
|
err := json.NewDecoder(buf).Decode(&resp)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, resp.Result)
|
||||||
|
assert.True(t, resp.Result.Success)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHandleDeleteClass(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
mockClient.EXPECT().DeleteClass("office").Return(nil)
|
||||||
|
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||||
|
|
||||||
|
m := NewTestManager(mockClient, nil)
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
conn := &mockConn{Buffer: buf}
|
||||||
|
|
||||||
|
req := Request{
|
||||||
|
ID: 1,
|
||||||
|
Method: "cups.deleteClass",
|
||||||
|
Params: map[string]interface{}{"className": "office"},
|
||||||
|
}
|
||||||
|
handleDeleteClass(conn, req, m)
|
||||||
|
|
||||||
|
var resp models.Response[SuccessResult]
|
||||||
|
err := json.NewDecoder(buf).Decode(&resp)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, resp.Result)
|
||||||
|
assert.True(t, resp.Result.Success)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHandleRestartJob(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
mockClient.EXPECT().RestartJob(1).Return(nil)
|
||||||
|
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||||
|
|
||||||
|
m := NewTestManager(mockClient, nil)
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
conn := &mockConn{Buffer: buf}
|
||||||
|
|
||||||
|
req := Request{
|
||||||
|
ID: 1,
|
||||||
|
Method: "cups.restartJob",
|
||||||
|
Params: map[string]interface{}{"jobID": float64(1)},
|
||||||
|
}
|
||||||
|
handleRestartJob(conn, req, m)
|
||||||
|
|
||||||
|
var resp models.Response[SuccessResult]
|
||||||
|
err := json.NewDecoder(buf).Decode(&resp)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, resp.Result)
|
||||||
|
assert.True(t, resp.Result.Success)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHandleHoldJob(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
mockClient.EXPECT().HoldJobUntil(1, "indefinite").Return(nil)
|
||||||
|
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||||
|
|
||||||
|
m := NewTestManager(mockClient, nil)
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
conn := &mockConn{Buffer: buf}
|
||||||
|
|
||||||
|
req := Request{
|
||||||
|
ID: 1,
|
||||||
|
Method: "cups.holdJob",
|
||||||
|
Params: map[string]interface{}{"jobID": float64(1)},
|
||||||
|
}
|
||||||
|
handleHoldJob(conn, req, m)
|
||||||
|
|
||||||
|
var resp models.Response[SuccessResult]
|
||||||
|
err := json.NewDecoder(buf).Decode(&resp)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, resp.Result)
|
||||||
|
assert.True(t, resp.Result.Success)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHandleHoldJob_WithHoldUntil(t *testing.T) {
|
||||||
|
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||||
|
mockClient.EXPECT().HoldJobUntil(1, "no-hold").Return(nil)
|
||||||
|
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||||
|
|
||||||
|
m := NewTestManager(mockClient, nil)
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
conn := &mockConn{Buffer: buf}
|
||||||
|
|
||||||
|
req := Request{
|
||||||
|
ID: 1,
|
||||||
|
Method: "cups.holdJob",
|
||||||
|
Params: map[string]interface{}{"jobID": float64(1), "holdUntil": "no-hold"},
|
||||||
|
}
|
||||||
|
handleHoldJob(conn, req, m)
|
||||||
|
|
||||||
|
var resp models.Response[SuccessResult]
|
||||||
|
err := json.NewDecoder(buf).Decode(&resp)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, resp.Result)
|
||||||
|
assert.True(t, resp.Result.Success)
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package cups
|
package cups
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -31,11 +32,21 @@ func NewManager() (*Manager, error) {
|
|||||||
client := ipp.NewCUPSClient(host, port, username, password, false)
|
client := ipp.NewCUPSClient(host, port, username, password, false)
|
||||||
baseURL := fmt.Sprintf("http://%s:%d", host, port)
|
baseURL := fmt.Sprintf("http://%s:%d", host, port)
|
||||||
|
|
||||||
|
var pkHelper PkHelper
|
||||||
|
if isLocalCUPS(host) {
|
||||||
|
var err error
|
||||||
|
pkHelper, err = NewPkHelper()
|
||||||
|
if err != nil {
|
||||||
|
log.Warnf("[CUPS] Failed to initialize pkhelper: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m := &Manager{
|
m := &Manager{
|
||||||
state: &CUPSState{
|
state: &CUPSState{
|
||||||
Printers: make(map[string]*Printer),
|
Printers: make(map[string]*Printer),
|
||||||
},
|
},
|
||||||
client: client,
|
client: client,
|
||||||
|
pkHelper: pkHelper,
|
||||||
baseURL: baseURL,
|
baseURL: baseURL,
|
||||||
stateMutex: sync.RWMutex{},
|
stateMutex: sync.RWMutex{},
|
||||||
stopChan: make(chan struct{}),
|
stopChan: make(chan struct{}),
|
||||||
@@ -98,6 +109,12 @@ func (m *Manager) eventHandler() {
|
|||||||
func (m *Manager) updateState() error {
|
func (m *Manager) updateState() error {
|
||||||
printers, err := m.GetPrinters()
|
printers, err := m.GetPrinters()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if isNoPrintersError(err) {
|
||||||
|
m.stateMutex.Lock()
|
||||||
|
m.state.Printers = make(map[string]*Printer)
|
||||||
|
m.stateMutex.Unlock()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,6 +136,19 @@ func (m *Manager) updateState() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isNoPrintersError(err error) bool {
|
||||||
|
if err == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
var ippErr ipp.IPPError
|
||||||
|
if errors.As(err, &ippErr) {
|
||||||
|
return ippErr.Status == 1030
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func (m *Manager) notifier() {
|
func (m *Manager) notifier() {
|
||||||
defer m.notifierWg.Done()
|
defer m.notifierWg.Done()
|
||||||
const minGap = 100 * time.Millisecond
|
const minGap = 100 * time.Millisecond
|
||||||
@@ -170,6 +200,14 @@ func (m *Manager) notifySubscribers() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *Manager) RefreshState() {
|
||||||
|
if err := m.updateState(); err != nil {
|
||||||
|
log.Warnf("[CUPS] Failed to refresh state: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
m.notifySubscribers()
|
||||||
|
}
|
||||||
|
|
||||||
func (m *Manager) GetState() CUPSState {
|
func (m *Manager) GetState() CUPSState {
|
||||||
return m.snapshotState()
|
return m.snapshotState()
|
||||||
}
|
}
|
||||||
@@ -256,6 +294,7 @@ func stateChanged(old, new *CUPSState) bool {
|
|||||||
}
|
}
|
||||||
if oldPrinter.State != newPrinter.State ||
|
if oldPrinter.State != newPrinter.State ||
|
||||||
oldPrinter.StateReason != newPrinter.StateReason ||
|
oldPrinter.StateReason != newPrinter.StateReason ||
|
||||||
|
oldPrinter.Accepting != newPrinter.Accepting ||
|
||||||
len(oldPrinter.Jobs) != len(newPrinter.Jobs) {
|
len(oldPrinter.Jobs) != len(newPrinter.Jobs) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -334,3 +373,18 @@ func getBoolAttr(attrs ipp.Attributes, key string) bool {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getStringSliceAttr(attrs ipp.Attributes, key string) []string {
|
||||||
|
attr, ok := attrs[key]
|
||||||
|
if !ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
result := make([]string, 0, len(attr))
|
||||||
|
for _, a := range attr {
|
||||||
|
if val, ok := a.Value.(string); ok {
|
||||||
|
result = append(result, val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|||||||
184
core/internal/server/cups/pkhelper.go
Normal file
184
core/internal/server/cups/pkhelper.go
Normal file
@@ -0,0 +1,184 @@
|
|||||||
|
package cups
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/godbus/dbus/v5"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
pkHelperDest = "org.opensuse.CupsPkHelper.Mechanism"
|
||||||
|
pkHelperPath = "/"
|
||||||
|
pkHelperInterface = "org.opensuse.CupsPkHelper.Mechanism"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PkHelper interface {
|
||||||
|
DevicesGet(timeout, limit int, includeSchemes, excludeSchemes []string) ([]Device, error)
|
||||||
|
PrinterAdd(name, uri, ppd, info, location string) error
|
||||||
|
PrinterDelete(name string) error
|
||||||
|
PrinterSetEnabled(name string, enabled bool) error
|
||||||
|
PrinterSetAcceptJobs(name string, enabled bool, reason string) error
|
||||||
|
PrinterSetInfo(name, info string) error
|
||||||
|
PrinterSetLocation(name, location string) error
|
||||||
|
PrinterSetShared(name string, shared bool) error
|
||||||
|
ClassAddPrinter(className, printerName string) error
|
||||||
|
ClassDeletePrinter(className, printerName string) error
|
||||||
|
ClassDelete(className string) error
|
||||||
|
JobCancelPurge(jobID int, purge bool) error
|
||||||
|
JobRestart(jobID int) error
|
||||||
|
JobSetHoldUntil(jobID int, holdUntil string) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type DBusPkHelper struct {
|
||||||
|
conn *dbus.Conn
|
||||||
|
obj dbus.BusObject
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPkHelper() (*DBusPkHelper, error) {
|
||||||
|
conn, err := dbus.SystemBus()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to connect to system bus: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &DBusPkHelper{
|
||||||
|
conn: conn,
|
||||||
|
obj: conn.Object(pkHelperDest, pkHelperPath),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *DBusPkHelper) DevicesGet(timeout, limit int, includeSchemes, excludeSchemes []string) ([]Device, error) {
|
||||||
|
if includeSchemes == nil {
|
||||||
|
includeSchemes = []string{}
|
||||||
|
}
|
||||||
|
if excludeSchemes == nil {
|
||||||
|
excludeSchemes = []string{}
|
||||||
|
}
|
||||||
|
|
||||||
|
var errStr string
|
||||||
|
var devicesMap map[string]string
|
||||||
|
|
||||||
|
call := p.obj.Call(pkHelperInterface+".DevicesGet", 0, int32(timeout), int32(limit), includeSchemes, excludeSchemes)
|
||||||
|
if call.Err != nil {
|
||||||
|
return nil, call.Err
|
||||||
|
}
|
||||||
|
if err := call.Store(&errStr, &devicesMap); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if errStr != "" {
|
||||||
|
return nil, fmt.Errorf("%s", errStr)
|
||||||
|
}
|
||||||
|
|
||||||
|
return parseDevicesMap(devicesMap), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseDevicesMap(devicesMap map[string]string) []Device {
|
||||||
|
devicesByIndex := make(map[string]*Device)
|
||||||
|
|
||||||
|
for key, value := range devicesMap {
|
||||||
|
idx := strings.LastIndex(key, ":")
|
||||||
|
if idx == -1 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
attr := key[:idx]
|
||||||
|
index := key[idx+1:]
|
||||||
|
|
||||||
|
dev, ok := devicesByIndex[index]
|
||||||
|
if !ok {
|
||||||
|
dev = &Device{}
|
||||||
|
devicesByIndex[index] = dev
|
||||||
|
}
|
||||||
|
|
||||||
|
switch attr {
|
||||||
|
case "device-uri":
|
||||||
|
dev.URI = value
|
||||||
|
case "device-class":
|
||||||
|
dev.Class = value
|
||||||
|
case "device-info":
|
||||||
|
dev.Info = value
|
||||||
|
case "device-make-and-model":
|
||||||
|
dev.MakeModel = value
|
||||||
|
case "device-id":
|
||||||
|
dev.ID = value
|
||||||
|
case "device-location":
|
||||||
|
dev.Location = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
devices := make([]Device, 0, len(devicesByIndex))
|
||||||
|
for _, dev := range devicesByIndex {
|
||||||
|
if dev.URI != "" {
|
||||||
|
devices = append(devices, *dev)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return devices
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *DBusPkHelper) PrinterAdd(name, uri, ppd, info, location string) error {
|
||||||
|
return p.callSimple("PrinterAdd", name, uri, ppd, info, location)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *DBusPkHelper) PrinterDelete(name string) error {
|
||||||
|
return p.callSimple("PrinterDelete", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *DBusPkHelper) PrinterSetEnabled(name string, enabled bool) error {
|
||||||
|
return p.callSimple("PrinterSetEnabled", name, enabled)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *DBusPkHelper) PrinterSetAcceptJobs(name string, enabled bool, reason string) error {
|
||||||
|
return p.callSimple("PrinterSetAcceptJobs", name, enabled, reason)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *DBusPkHelper) PrinterSetInfo(name, info string) error {
|
||||||
|
return p.callSimple("PrinterSetInfo", name, info)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *DBusPkHelper) PrinterSetLocation(name, location string) error {
|
||||||
|
return p.callSimple("PrinterSetLocation", name, location)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *DBusPkHelper) PrinterSetShared(name string, shared bool) error {
|
||||||
|
return p.callSimple("PrinterSetShared", name, shared)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *DBusPkHelper) ClassAddPrinter(className, printerName string) error {
|
||||||
|
return p.callSimple("ClassAddPrinter", className, printerName)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *DBusPkHelper) ClassDeletePrinter(className, printerName string) error {
|
||||||
|
return p.callSimple("ClassDeletePrinter", className, printerName)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *DBusPkHelper) ClassDelete(className string) error {
|
||||||
|
return p.callSimple("ClassDelete", className)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *DBusPkHelper) JobCancelPurge(jobID int, purge bool) error {
|
||||||
|
return p.callSimple("JobCancelPurge", int32(jobID), purge)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *DBusPkHelper) JobRestart(jobID int) error {
|
||||||
|
return p.callSimple("JobRestart", int32(jobID))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *DBusPkHelper) JobSetHoldUntil(jobID int, holdUntil string) error {
|
||||||
|
return p.callSimple("JobSetHoldUntil", int32(jobID), holdUntil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *DBusPkHelper) callSimple(method string, args ...interface{}) error {
|
||||||
|
var errStr string
|
||||||
|
|
||||||
|
call := p.obj.Call(pkHelperInterface+"."+method, 0, args...)
|
||||||
|
if call.Err != nil {
|
||||||
|
return call.Err
|
||||||
|
}
|
||||||
|
if err := call.Store(&errStr); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if errStr != "" {
|
||||||
|
return fmt.Errorf("%s", errStr)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
95
core/internal/server/cups/pkhelper_test.go
Normal file
95
core/internal/server/cups/pkhelper_test.go
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
package cups
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestParseDevicesMap(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
input map[string]string
|
||||||
|
wantLen int
|
||||||
|
wantURIs []string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "empty",
|
||||||
|
input: map[string]string{},
|
||||||
|
wantLen: 0,
|
||||||
|
wantURIs: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "single_device",
|
||||||
|
input: map[string]string{
|
||||||
|
"device-uri:0": "usb://HP/LaserJet",
|
||||||
|
"device-class:0": "direct",
|
||||||
|
"device-info:0": "HP LaserJet",
|
||||||
|
"device-make-and-model:0": "HP LaserJet 1020",
|
||||||
|
"device-id:0": "MFG:HP;MDL:LaserJet",
|
||||||
|
},
|
||||||
|
wantLen: 1,
|
||||||
|
wantURIs: []string{"usb://HP/LaserJet"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "multiple_devices",
|
||||||
|
input: map[string]string{
|
||||||
|
"device-uri:0": "usb://HP/LaserJet",
|
||||||
|
"device-class:0": "direct",
|
||||||
|
"device-info:0": "HP LaserJet",
|
||||||
|
"device-uri:1": "socket://192.168.1.100",
|
||||||
|
"device-class:1": "network",
|
||||||
|
"device-info:1": "Network Printer",
|
||||||
|
},
|
||||||
|
wantLen: 2,
|
||||||
|
wantURIs: []string{"usb://HP/LaserJet", "socket://192.168.1.100"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "malformed_key",
|
||||||
|
input: map[string]string{
|
||||||
|
"no-colon-here": "value",
|
||||||
|
},
|
||||||
|
wantLen: 0,
|
||||||
|
wantURIs: nil,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got := parseDevicesMap(tt.input)
|
||||||
|
assert.Len(t, got, tt.wantLen)
|
||||||
|
|
||||||
|
if tt.wantURIs != nil {
|
||||||
|
gotURIs := make(map[string]bool)
|
||||||
|
for _, d := range got {
|
||||||
|
gotURIs[d.URI] = true
|
||||||
|
}
|
||||||
|
for _, uri := range tt.wantURIs {
|
||||||
|
assert.True(t, gotURIs[uri], "expected URI %s not found", uri)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParseDevicesMap_Attributes(t *testing.T) {
|
||||||
|
input := map[string]string{
|
||||||
|
"device-uri:0": "usb://HP/LaserJet",
|
||||||
|
"device-class:0": "direct",
|
||||||
|
"device-info:0": "HP LaserJet",
|
||||||
|
"device-make-and-model:0": "HP LaserJet 1020",
|
||||||
|
"device-id:0": "MFG:HP;MDL:LaserJet",
|
||||||
|
"device-location:0": "USB Port",
|
||||||
|
}
|
||||||
|
|
||||||
|
got := parseDevicesMap(input)
|
||||||
|
assert.Len(t, got, 1)
|
||||||
|
|
||||||
|
dev := got[0]
|
||||||
|
assert.Equal(t, "usb://HP/LaserJet", dev.URI)
|
||||||
|
assert.Equal(t, "direct", dev.Class)
|
||||||
|
assert.Equal(t, "HP LaserJet", dev.Info)
|
||||||
|
assert.Equal(t, "HP LaserJet 1020", dev.MakeModel)
|
||||||
|
assert.Equal(t, "MFG:HP;MDL:LaserJet", dev.ID)
|
||||||
|
assert.Equal(t, "USB Port", dev.Location)
|
||||||
|
}
|
||||||
13
core/internal/server/cups/testing.go
Normal file
13
core/internal/server/cups/testing.go
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package cups
|
||||||
|
|
||||||
|
func NewTestManager(client CUPSClientInterface, pkHelper PkHelper) *Manager {
|
||||||
|
return &Manager{
|
||||||
|
client: client,
|
||||||
|
pkHelper: pkHelper,
|
||||||
|
state: &CUPSState{
|
||||||
|
Printers: make(map[string]*Printer),
|
||||||
|
},
|
||||||
|
stopChan: make(chan struct{}),
|
||||||
|
dirty: make(chan struct{}, 1),
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -35,9 +35,38 @@ type Job struct {
|
|||||||
TimeCreated time.Time `json:"timeCreated"`
|
TimeCreated time.Time `json:"timeCreated"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Device struct {
|
||||||
|
URI string `json:"uri"`
|
||||||
|
Class string `json:"class"`
|
||||||
|
Info string `json:"info"`
|
||||||
|
MakeModel string `json:"makeModel"`
|
||||||
|
ID string `json:"id"`
|
||||||
|
Location string `json:"location"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type PPD struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
NaturalLanguage string `json:"naturalLanguage"`
|
||||||
|
MakeModel string `json:"makeModel"`
|
||||||
|
DeviceID string `json:"deviceId"`
|
||||||
|
Product string `json:"product"`
|
||||||
|
PSVersion string `json:"psVersion"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type PrinterClass struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
URI string `json:"uri"`
|
||||||
|
State string `json:"state"`
|
||||||
|
Members []string `json:"members"`
|
||||||
|
Location string `json:"location"`
|
||||||
|
Info string `json:"info"`
|
||||||
|
}
|
||||||
|
|
||||||
type Manager struct {
|
type Manager struct {
|
||||||
state *CUPSState
|
state *CUPSState
|
||||||
client CUPSClientInterface
|
client CUPSClientInterface
|
||||||
|
pkHelper PkHelper
|
||||||
subscription SubscriptionManagerInterface
|
subscription SubscriptionManagerInterface
|
||||||
stateMutex sync.RWMutex
|
stateMutex sync.RWMutex
|
||||||
subscribers syncmap.Map[string, chan CUPSState]
|
subscribers syncmap.Map[string, chan CUPSState]
|
||||||
@@ -63,6 +92,24 @@ type CUPSClientInterface interface {
|
|||||||
ResumePrinter(printer string) error
|
ResumePrinter(printer string) error
|
||||||
CancelAllJob(printer string, purge bool) error
|
CancelAllJob(printer string, purge bool) error
|
||||||
SendRequest(url string, req *ipp.Request, additionalResponseData io.Writer) (*ipp.Response, error)
|
SendRequest(url string, req *ipp.Request, additionalResponseData io.Writer) (*ipp.Response, error)
|
||||||
|
|
||||||
|
GetDevices() (map[string]ipp.Attributes, error)
|
||||||
|
GetPPDs() (map[string]ipp.Attributes, error)
|
||||||
|
GetClasses(attributes []string) (map[string]ipp.Attributes, error)
|
||||||
|
CreatePrinter(name, deviceURI, ppd string, shared bool, errorPolicy, information, location string) error
|
||||||
|
DeletePrinter(printer string) error
|
||||||
|
AcceptJobs(printer string) error
|
||||||
|
RejectJobs(printer string) error
|
||||||
|
SetPrinterIsShared(printer string, shared bool) error
|
||||||
|
SetPrinterLocation(printer, location string) error
|
||||||
|
SetPrinterInformation(printer, information string) error
|
||||||
|
MoveJob(jobID int, destPrinter string) error
|
||||||
|
PrintTestPage(printer string, testPageData io.Reader, size int) (int, error)
|
||||||
|
AddPrinterToClass(class, printer string) error
|
||||||
|
DeletePrinterFromClass(class, printer string) error
|
||||||
|
DeleteClass(class string) error
|
||||||
|
RestartJob(jobID int) error
|
||||||
|
HoldJobUntil(jobID int, holdUntil string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type SubscriptionEvent struct {
|
type SubscriptionEvent struct {
|
||||||
|
|||||||
@@ -31,7 +31,9 @@ import (
|
|||||||
"github.com/AvengeMedia/DankMaterialShell/core/pkg/syncmap"
|
"github.com/AvengeMedia/DankMaterialShell/core/pkg/syncmap"
|
||||||
)
|
)
|
||||||
|
|
||||||
const APIVersion = 21
|
const APIVersion = 22
|
||||||
|
|
||||||
|
var CLIVersion = "dev"
|
||||||
|
|
||||||
type Capabilities struct {
|
type Capabilities struct {
|
||||||
Capabilities []string `json:"capabilities"`
|
Capabilities []string `json:"capabilities"`
|
||||||
@@ -39,6 +41,7 @@ type Capabilities struct {
|
|||||||
|
|
||||||
type ServerInfo struct {
|
type ServerInfo struct {
|
||||||
APIVersion int `json:"apiVersion"`
|
APIVersion int `json:"apiVersion"`
|
||||||
|
CLIVersion string `json:"cliVersion,omitempty"`
|
||||||
Capabilities []string `json:"capabilities"`
|
Capabilities []string `json:"capabilities"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -431,6 +434,7 @@ func getServerInfo() ServerInfo {
|
|||||||
|
|
||||||
return ServerInfo{
|
return ServerInfo{
|
||||||
APIVersion: APIVersion,
|
APIVersion: APIVersion,
|
||||||
|
CLIVersion: CLIVersion,
|
||||||
Capabilities: caps,
|
Capabilities: caps,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -288,6 +288,7 @@ const (
|
|||||||
// useful mime types for ipp
|
// useful mime types for ipp
|
||||||
const (
|
const (
|
||||||
MimeTypePostscript = "application/postscript"
|
MimeTypePostscript = "application/postscript"
|
||||||
|
MimeTypePDF = "application/pdf"
|
||||||
MimeTypeOctetStream = "application/octet-stream"
|
MimeTypeOctetStream = "application/octet-stream"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package ipp
|
package ipp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -300,22 +300,13 @@ func (c *CUPSClient) GetClasses(attributes []string) (map[string]Attributes, err
|
|||||||
return printerNameMap, nil
|
return printerNameMap, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// PrintTestPage prints a test page of type application/vnd.cups-pdf-banner
|
// PrintTestPage prints a test page using the provided PDF data
|
||||||
func (c *CUPSClient) PrintTestPage(printer string) (int, error) {
|
func (c *CUPSClient) PrintTestPage(printer string, testPageData io.Reader, size int) (int, error) {
|
||||||
testPage := new(bytes.Buffer)
|
return c.PrintJob(Document{
|
||||||
testPage.WriteString("#PDF-BANNER\n")
|
Document: testPageData,
|
||||||
testPage.WriteString("Template default-testpage.pdf\n")
|
Name: "Test Page",
|
||||||
testPage.WriteString("Show printer-name printer-info printer-location printer-make-and-model printer-driver-name")
|
Size: size,
|
||||||
testPage.WriteString("printer-driver-version paper-size imageable-area job-id options time-at-creation")
|
MimeType: MimeTypePDF,
|
||||||
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{}{
|
}, printer, map[string]interface{}{
|
||||||
AttributeJobName: "Test Page",
|
AttributeJobName: "Test Page",
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -146,13 +146,30 @@ FocusScope {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
id: launcherLoader
|
id: printerLoader
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
active: root.currentIndex === 7
|
active: root.currentIndex === 7
|
||||||
visible: active
|
visible: active
|
||||||
focus: active
|
focus: active
|
||||||
|
|
||||||
|
sourceComponent: PrinterTab {}
|
||||||
|
|
||||||
|
onActiveChanged: {
|
||||||
|
if (active && item) {
|
||||||
|
Qt.callLater(() => item.forceActiveFocus());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: launcherLoader
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
active: root.currentIndex === 8
|
||||||
|
visible: active
|
||||||
|
focus: active
|
||||||
|
|
||||||
sourceComponent: LauncherTab {}
|
sourceComponent: LauncherTab {}
|
||||||
|
|
||||||
onActiveChanged: {
|
onActiveChanged: {
|
||||||
@@ -166,7 +183,7 @@ FocusScope {
|
|||||||
id: themeColorsLoader
|
id: themeColorsLoader
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
active: root.currentIndex === 8
|
active: root.currentIndex === 9
|
||||||
visible: active
|
visible: active
|
||||||
focus: active
|
focus: active
|
||||||
|
|
||||||
@@ -183,7 +200,7 @@ FocusScope {
|
|||||||
id: powerLoader
|
id: powerLoader
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
active: root.currentIndex === 9
|
active: root.currentIndex === 10
|
||||||
visible: active
|
visible: active
|
||||||
focus: active
|
focus: active
|
||||||
|
|
||||||
@@ -200,7 +217,7 @@ FocusScope {
|
|||||||
id: pluginsLoader
|
id: pluginsLoader
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
active: root.currentIndex === 10
|
active: root.currentIndex === 11
|
||||||
visible: active
|
visible: active
|
||||||
focus: active
|
focus: active
|
||||||
|
|
||||||
@@ -219,7 +236,7 @@ FocusScope {
|
|||||||
id: aboutLoader
|
id: aboutLoader
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
active: root.currentIndex === 11
|
active: root.currentIndex === 12
|
||||||
visible: active
|
visible: active
|
||||||
focus: active
|
focus: active
|
||||||
|
|
||||||
|
|||||||
@@ -67,6 +67,15 @@ FloatingWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
active: settingsModal.visible
|
||||||
|
sourceComponent: Component {
|
||||||
|
Ref {
|
||||||
|
service: CupsService
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FileBrowserModal {
|
FileBrowserModal {
|
||||||
id: profileBrowser
|
id: profileBrowser
|
||||||
|
|
||||||
@@ -112,7 +121,7 @@ FloatingWindow {
|
|||||||
focus: true
|
focus: true
|
||||||
|
|
||||||
Keys.onPressed: event => {
|
Keys.onPressed: event => {
|
||||||
const tabCount = 12;
|
const tabCount = 13;
|
||||||
if (event.key === Qt.Key_Escape) {
|
if (event.key === Qt.Key_Escape) {
|
||||||
hide();
|
hide();
|
||||||
event.accepted = true;
|
event.accepted = true;
|
||||||
|
|||||||
@@ -48,33 +48,45 @@ Rectangle {
|
|||||||
"dmsOnly": true,
|
"dmsOnly": true,
|
||||||
"tabIndex": 6
|
"tabIndex": 6
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"text": I18n.tr("Printers"),
|
||||||
|
"icon": "print",
|
||||||
|
"cupsOnly": true,
|
||||||
|
"tabIndex": 7
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"text": I18n.tr("Launcher"),
|
"text": I18n.tr("Launcher"),
|
||||||
"icon": "apps",
|
"icon": "apps",
|
||||||
"tabIndex": 7
|
"tabIndex": 8
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"text": I18n.tr("Theme & Colors"),
|
"text": I18n.tr("Theme & Colors"),
|
||||||
"icon": "palette",
|
"icon": "palette",
|
||||||
"tabIndex": 8
|
"tabIndex": 9
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"text": I18n.tr("Power & Security"),
|
"text": I18n.tr("Power & Security"),
|
||||||
"icon": "power",
|
"icon": "power",
|
||||||
"tabIndex": 9
|
"tabIndex": 10
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"text": I18n.tr("Plugins"),
|
"text": I18n.tr("Plugins"),
|
||||||
"icon": "extension",
|
"icon": "extension",
|
||||||
"tabIndex": 10
|
"tabIndex": 11
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"text": I18n.tr("About"),
|
"text": I18n.tr("About"),
|
||||||
"icon": "info",
|
"icon": "info",
|
||||||
"tabIndex": 11
|
"tabIndex": 12
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
readonly property var sidebarItems: allSidebarItems.filter(item => !item.dmsOnly || !NetworkService.usingLegacy)
|
readonly property var sidebarItems: allSidebarItems.filter(item => {
|
||||||
|
if (item.dmsOnly && NetworkService.usingLegacy)
|
||||||
|
return false;
|
||||||
|
if (item.cupsOnly && !CupsService.cupsAvailable)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
|
||||||
function navigateNext() {
|
function navigateNext() {
|
||||||
const currentItemIndex = sidebarItems.findIndex(item => item.tabIndex === currentIndex);
|
const currentItemIndex = sidebarItems.findIndex(item => item.tabIndex === currentIndex);
|
||||||
|
|||||||
@@ -41,16 +41,10 @@ QtObject {
|
|||||||
|
|
||||||
onItemChanged: {
|
onItemChanged: {
|
||||||
root.cupsBuiltinInstance = item;
|
root.cupsBuiltinInstance = item;
|
||||||
if (item && !DMSService.activeSubscriptions.includes("cups") && !DMSService.activeSubscriptions.includes("all")) {
|
|
||||||
DMSService.addSubscription("cups");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onActiveChanged: {
|
onActiveChanged: {
|
||||||
if (!active) {
|
if (!active) {
|
||||||
if (DMSService.activeSubscriptions.includes("cups")) {
|
|
||||||
DMSService.removeSubscription("cups");
|
|
||||||
}
|
|
||||||
root.cupsBuiltinInstance = null;
|
root.cupsBuiltinInstance = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,15 @@ BasePill {
|
|||||||
property bool showBatteryIcon: SettingsData.controlCenterShowBatteryIcon
|
property bool showBatteryIcon: SettingsData.controlCenterShowBatteryIcon
|
||||||
property bool showPrinterIcon: SettingsData.controlCenterShowPrinterIcon
|
property bool showPrinterIcon: SettingsData.controlCenterShowPrinterIcon
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
active: root.showPrinterIcon
|
||||||
|
sourceComponent: Component {
|
||||||
|
Ref {
|
||||||
|
service: CupsService
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function getNetworkIconName() {
|
function getNetworkIconName() {
|
||||||
if (NetworkService.wifiToggling)
|
if (NetworkService.wifiToggling)
|
||||||
return "sync";
|
return "sync";
|
||||||
|
|||||||
@@ -595,6 +595,159 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StyledRect {
|
||||||
|
visible: DMSService.isConnected
|
||||||
|
width: parent.width
|
||||||
|
height: backendSection.implicitHeight + Theme.spacingL * 2
|
||||||
|
radius: Theme.cornerRadius
|
||||||
|
color: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency)
|
||||||
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
|
||||||
|
border.width: 0
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: backendSection
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: Theme.spacingL
|
||||||
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
|
Row {
|
||||||
|
width: parent.width
|
||||||
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: "dns"
|
||||||
|
size: Theme.iconSize
|
||||||
|
color: Theme.primary
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: I18n.tr("Backend")
|
||||||
|
font.pixelSize: Theme.fontSizeLarge
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: Theme.surfaceText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
spacing: Theme.spacingL
|
||||||
|
|
||||||
|
Column {
|
||||||
|
spacing: 2
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: I18n.tr("Version")
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.surfaceVariantText
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: DMSService.cliVersion || "—"
|
||||||
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: Theme.surfaceText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: 1
|
||||||
|
height: 32
|
||||||
|
color: Theme.outlineVariant
|
||||||
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
spacing: 2
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: I18n.tr("API")
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.surfaceVariantText
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: `v${DMSService.apiVersion}`
|
||||||
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: Theme.surfaceText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: 1
|
||||||
|
height: 32
|
||||||
|
color: Theme.outlineVariant
|
||||||
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
spacing: 2
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: I18n.tr("Status")
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.surfaceVariantText
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
spacing: 4
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: 8
|
||||||
|
height: 8
|
||||||
|
radius: 4
|
||||||
|
color: Theme.success
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: I18n.tr("Connected")
|
||||||
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: Theme.surfaceText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
width: parent.width
|
||||||
|
spacing: Theme.spacingS
|
||||||
|
visible: DMSService.capabilities.length > 0
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: I18n.tr("Capabilities")
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.surfaceVariantText
|
||||||
|
}
|
||||||
|
|
||||||
|
Flow {
|
||||||
|
width: parent.width
|
||||||
|
spacing: 6
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: DMSService.capabilities
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: capText.implicitWidth + 16
|
||||||
|
height: 26
|
||||||
|
radius: 13
|
||||||
|
color: Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12)
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
id: capText
|
||||||
|
anchors.centerIn: parent
|
||||||
|
text: modelData
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.primary
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Support Section
|
// Support Section
|
||||||
StyledRect {
|
StyledRect {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
|
|||||||
1360
quickshell/Modules/Settings/PrinterTab.qml
Normal file
1360
quickshell/Modules/Settings/PrinterTab.qml
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,10 +1,8 @@
|
|||||||
pragma Singleton
|
pragma Singleton
|
||||||
|
|
||||||
pragma ComponentBehavior: Bound
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Io
|
|
||||||
import qs.Common
|
import qs.Common
|
||||||
|
|
||||||
Singleton {
|
Singleton {
|
||||||
@@ -12,20 +10,179 @@ Singleton {
|
|||||||
|
|
||||||
property int refCount: 0
|
property int refCount: 0
|
||||||
|
|
||||||
|
onRefCountChanged: {
|
||||||
|
if (refCount > 0) {
|
||||||
|
ensureSubscription();
|
||||||
|
} else if (refCount === 0 && DMSService.activeSubscriptions.includes("cups")) {
|
||||||
|
DMSService.removeSubscription("cups");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function ensureSubscription() {
|
||||||
|
if (refCount <= 0)
|
||||||
|
return;
|
||||||
|
if (!DMSService.isConnected)
|
||||||
|
return;
|
||||||
|
if (DMSService.activeSubscriptions.includes("cups"))
|
||||||
|
return;
|
||||||
|
if (DMSService.activeSubscriptions.includes("all"))
|
||||||
|
return;
|
||||||
|
DMSService.addSubscription("cups");
|
||||||
|
if (cupsAvailable) {
|
||||||
|
getState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
property var printerNames: []
|
property var printerNames: []
|
||||||
property var printers: []
|
property var printers: []
|
||||||
property string selectedPrinter: ""
|
property string selectedPrinter: ""
|
||||||
|
property string expandedPrinter: ""
|
||||||
|
|
||||||
property bool cupsAvailable: false
|
property bool cupsAvailable: false
|
||||||
property bool stateInitialized: false
|
property bool stateInitialized: false
|
||||||
|
|
||||||
|
property var devices: []
|
||||||
|
property var ppds: []
|
||||||
|
property var printerClasses: []
|
||||||
|
|
||||||
|
readonly property var filteredDevices: {
|
||||||
|
if (!devices || devices.length === 0)
|
||||||
|
return [];
|
||||||
|
const bareProtocols = ["ipp", "ipps", "http", "https", "lpd", "socket", "beh", "dnssd", "mdns", "smb", "file", "cups-brf"];
|
||||||
|
|
||||||
|
// First pass: filter out invalid/bare protocol entries
|
||||||
|
const validDevices = devices.filter(d => {
|
||||||
|
if (!d.uri)
|
||||||
|
return false;
|
||||||
|
const uriLower = d.uri.toLowerCase();
|
||||||
|
for (let proto of bareProtocols) {
|
||||||
|
if (uriLower === proto || uriLower === proto + ":")
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (d.class === "network" && d.info === "Backend Error Handler")
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Second pass: prefer IPP over LPD for the same printer
|
||||||
|
// _printer._tcp (LPD) doesn't work well with driverless printing
|
||||||
|
// _ipp._tcp or _ipps._tcp (IPP) should be preferred
|
||||||
|
const ippDeviceHosts = new Set();
|
||||||
|
for (const d of validDevices) {
|
||||||
|
if (!d.uri)
|
||||||
|
continue;
|
||||||
|
// Extract hostname from dnssd URIs like dnssd://Name%20[mac]._ipp._tcp.local
|
||||||
|
const ippMatch = d.uri.match(/dnssd:\/\/[^/]*\._ipps?\._tcp/);
|
||||||
|
if (ippMatch) {
|
||||||
|
// Extract the unique identifier (usually MAC address in brackets)
|
||||||
|
const macMatch = d.uri.match(/\[([a-f0-9]+)\]/i);
|
||||||
|
if (macMatch)
|
||||||
|
ippDeviceHosts.add(macMatch[1].toLowerCase());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter out _printer._tcp devices when we have _ipp._tcp for the same printer
|
||||||
|
return validDevices.filter(d => {
|
||||||
|
if (!d.uri)
|
||||||
|
return true;
|
||||||
|
// If this is an LPD device, check if we have an IPP alternative
|
||||||
|
if (d.uri.includes("._printer._tcp")) {
|
||||||
|
const macMatch = d.uri.match(/\[([a-f0-9]+)\]/i);
|
||||||
|
if (macMatch && ippDeviceHosts.has(macMatch[1].toLowerCase())) {
|
||||||
|
return false; // Skip LPD device, we have IPP
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function decodeUri(str) {
|
||||||
|
if (!str)
|
||||||
|
return "";
|
||||||
|
try {
|
||||||
|
return decodeURIComponent(str.replace(/\+/g, " "));
|
||||||
|
} catch (e) {
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDeviceDisplayName(device) {
|
||||||
|
if (!device)
|
||||||
|
return "";
|
||||||
|
if (device.info && device.info.length > 0) {
|
||||||
|
return decodeUri(device.info);
|
||||||
|
}
|
||||||
|
if (device.makeModel && device.makeModel.length > 0) {
|
||||||
|
return decodeUri(device.makeModel);
|
||||||
|
}
|
||||||
|
return decodeUri(device.uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDeviceSubtitle(device) {
|
||||||
|
if (!device)
|
||||||
|
return "";
|
||||||
|
const parts = [];
|
||||||
|
if (device.class) {
|
||||||
|
switch (device.class) {
|
||||||
|
case "direct":
|
||||||
|
parts.push(I18n.tr("Local"));
|
||||||
|
break;
|
||||||
|
case "network":
|
||||||
|
parts.push(I18n.tr("Network"));
|
||||||
|
break;
|
||||||
|
case "file":
|
||||||
|
parts.push(I18n.tr("File"));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
parts.push(device.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (device.location)
|
||||||
|
parts.push(decodeUri(device.location));
|
||||||
|
return parts.join(" • ");
|
||||||
|
}
|
||||||
|
|
||||||
|
function suggestPrinterName(device) {
|
||||||
|
if (!device)
|
||||||
|
return "";
|
||||||
|
let name = device.info || device.makeModel || "";
|
||||||
|
name = name.replace(/[^a-zA-Z0-9_-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
|
||||||
|
return name.substring(0, 32) || "Printer";
|
||||||
|
}
|
||||||
|
|
||||||
|
function getMatchingPPDs(device) {
|
||||||
|
if (!device || !ppds || ppds.length === 0)
|
||||||
|
return [];
|
||||||
|
const isDnssd = device.uri && (device.uri.startsWith("dnssd://") || device.uri.startsWith("ipp://") || device.uri.startsWith("ipps://"));
|
||||||
|
if (isDnssd) {
|
||||||
|
const driverless = ppds.filter(p => p.name === "driverless" || p.name === "everywhere" || (p.makeModel && p.makeModel.toLowerCase().includes("driverless")));
|
||||||
|
if (driverless.length > 0)
|
||||||
|
return driverless;
|
||||||
|
}
|
||||||
|
if (!device.makeModel)
|
||||||
|
return [];
|
||||||
|
const makeModelLower = device.makeModel.toLowerCase();
|
||||||
|
const words = makeModelLower.split(/[\s_-]+/).filter(w => w.length > 2);
|
||||||
|
return ppds.filter(p => {
|
||||||
|
if (!p.makeModel)
|
||||||
|
return false;
|
||||||
|
const ppdLower = p.makeModel.toLowerCase();
|
||||||
|
return words.some(w => ppdLower.includes(w));
|
||||||
|
}).slice(0, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
property bool loadingDevices: false
|
||||||
|
property bool loadingPPDs: false
|
||||||
|
property bool loadingClasses: false
|
||||||
|
property bool creatingPrinter: false
|
||||||
|
|
||||||
signal cupsStateUpdate
|
signal cupsStateUpdate
|
||||||
|
|
||||||
readonly property string socketPath: Quickshell.env("DMS_SOCKET")
|
readonly property string socketPath: Quickshell.env("DMS_SOCKET")
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
if (socketPath && socketPath.length > 0) {
|
if (socketPath && socketPath.length > 0) {
|
||||||
checkDMSCapabilities()
|
checkDMSCapabilities();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,7 +191,8 @@ Singleton {
|
|||||||
|
|
||||||
function onConnectionStateChanged() {
|
function onConnectionStateChanged() {
|
||||||
if (DMSService.isConnected) {
|
if (DMSService.isConnected) {
|
||||||
checkDMSCapabilities()
|
checkDMSCapabilities();
|
||||||
|
ensureSubscription();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -44,328 +202,641 @@ Singleton {
|
|||||||
enabled: DMSService.isConnected
|
enabled: DMSService.isConnected
|
||||||
|
|
||||||
function onCupsStateUpdate(data) {
|
function onCupsStateUpdate(data) {
|
||||||
console.log("CupsService: Subscription update received")
|
console.log("CupsService: Subscription update received");
|
||||||
getState()
|
getState();
|
||||||
}
|
}
|
||||||
|
|
||||||
function onCapabilitiesChanged() {
|
function onCapabilitiesChanged() {
|
||||||
checkDMSCapabilities()
|
checkDMSCapabilities();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkDMSCapabilities() {
|
function checkDMSCapabilities() {
|
||||||
if (!DMSService.isConnected) {
|
if (!DMSService.isConnected)
|
||||||
return
|
return;
|
||||||
}
|
if (DMSService.capabilities.length === 0)
|
||||||
|
return;
|
||||||
if (DMSService.capabilities.length === 0) {
|
cupsAvailable = DMSService.capabilities.includes("cups");
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
cupsAvailable = DMSService.capabilities.includes("cups")
|
|
||||||
|
|
||||||
if (cupsAvailable && !stateInitialized) {
|
if (cupsAvailable && !stateInitialized) {
|
||||||
stateInitialized = true
|
stateInitialized = true;
|
||||||
getState()
|
getState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getState() {
|
function getState() {
|
||||||
if (!cupsAvailable)
|
if (!cupsAvailable)
|
||||||
return
|
return;
|
||||||
|
|
||||||
DMSService.sendRequest("cups.getPrinters", null, response => {
|
DMSService.sendRequest("cups.getPrinters", null, response => {
|
||||||
if (response.result) {
|
if (response.result) {
|
||||||
updatePrinters(response.result)
|
updatePrinters(response.result);
|
||||||
fetchAllJobs()
|
fetchAllJobs();
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function updatePrinters(printersData) {
|
function updatePrinters(printersData) {
|
||||||
printerNames = printersData.map(p => p.name)
|
printerNames = printersData.map(p => p.name);
|
||||||
|
|
||||||
let printersObj = {}
|
let printersObj = {};
|
||||||
for (var i = 0; i < printersData.length; i++) {
|
for (var i = 0; i < printersData.length; i++) {
|
||||||
let printer = printersData[i]
|
let printer = printersData[i];
|
||||||
printersObj[printer.name] = {
|
printersObj[printer.name] = {
|
||||||
|
"name": printer.name,
|
||||||
|
"uri": printer.uri || "",
|
||||||
"state": printer.state,
|
"state": printer.state,
|
||||||
"stateReason": printer.stateReason,
|
"stateReason": printer.stateReason,
|
||||||
|
"location": printer.location || "",
|
||||||
|
"info": printer.info || "",
|
||||||
|
"makeModel": printer.makeModel || "",
|
||||||
|
"accepting": printer.accepting !== false,
|
||||||
"jobs": []
|
"jobs": []
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
printers = printersObj
|
printers = printersObj;
|
||||||
|
|
||||||
if (printerNames.length > 0) {
|
if (printerNames.length > 0) {
|
||||||
if (selectedPrinter.length > 0) {
|
if (selectedPrinter.length > 0) {
|
||||||
if (!printerNames.includes(selectedPrinter)) {
|
if (!printerNames.includes(selectedPrinter)) {
|
||||||
selectedPrinter = printerNames[0]
|
selectedPrinter = printerNames[0];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
selectedPrinter = printerNames[0]
|
selectedPrinter = printerNames[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function fetchAllJobs() {
|
function fetchAllJobs() {
|
||||||
for (var i = 0; i < printerNames.length; i++) {
|
for (var i = 0; i < printerNames.length; i++) {
|
||||||
fetchJobsForPrinter(printerNames[i])
|
fetchJobsForPrinter(printerNames[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function fetchJobsForPrinter(printerName) {
|
function fetchJobsForPrinter(printerName) {
|
||||||
const params = {
|
const params = {
|
||||||
"printerName": printerName
|
"printerName": printerName
|
||||||
}
|
};
|
||||||
|
|
||||||
DMSService.sendRequest("cups.getJobs", params, response => {
|
DMSService.sendRequest("cups.getJobs", params, response => {
|
||||||
if (response.result && printers[printerName]) {
|
if (response.result && printers[printerName]) {
|
||||||
let updatedPrinters = Object.assign({}, printers)
|
let updatedPrinters = Object.assign({}, printers);
|
||||||
updatedPrinters[printerName].jobs = response.result
|
updatedPrinters[printerName].jobs = response.result;
|
||||||
printers = updatedPrinters
|
printers = updatedPrinters;
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSelectedPrinter() {
|
function getSelectedPrinter() {
|
||||||
return selectedPrinter
|
return selectedPrinter;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setSelectedPrinter(printerName) {
|
function setSelectedPrinter(printerName) {
|
||||||
if (printerNames.length > 0) {
|
if (printerNames.length > 0) {
|
||||||
if (printerNames.includes(printerName)) {
|
if (printerNames.includes(printerName)) {
|
||||||
selectedPrinter = printerName
|
selectedPrinter = printerName;
|
||||||
} else {
|
} else {
|
||||||
selectedPrinter = printerNames[0]
|
selectedPrinter = printerNames[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPrintersNum() {
|
function getPrintersNum() {
|
||||||
if (!cupsAvailable)
|
if (!cupsAvailable)
|
||||||
return 0
|
return 0;
|
||||||
|
|
||||||
return printerNames.length
|
return printerNames.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPrintersNames() {
|
function getPrintersNames() {
|
||||||
if (!cupsAvailable)
|
if (!cupsAvailable)
|
||||||
return []
|
return [];
|
||||||
|
|
||||||
return printerNames
|
return printerNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTotalJobsNum() {
|
function getTotalJobsNum() {
|
||||||
if (!cupsAvailable)
|
if (!cupsAvailable)
|
||||||
return 0
|
return 0;
|
||||||
|
|
||||||
var result = 0
|
var result = 0;
|
||||||
for (var i = 0; i < printerNames.length; i++) {
|
for (var i = 0; i < printerNames.length; i++) {
|
||||||
var printerName = printerNames[i]
|
var printerName = printerNames[i];
|
||||||
if (printers[printerName] && printers[printerName].jobs) {
|
if (printers[printerName] && printers[printerName].jobs) {
|
||||||
result += printers[printerName].jobs.length
|
result += printers[printerName].jobs.length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCurrentPrinterState() {
|
function getCurrentPrinterState() {
|
||||||
if (!cupsAvailable || !selectedPrinter)
|
if (!cupsAvailable || !selectedPrinter)
|
||||||
return ""
|
return "";
|
||||||
|
|
||||||
var printer = printers[selectedPrinter]
|
var printer = printers[selectedPrinter];
|
||||||
return printer.state
|
return printer.state;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCurrentPrinterStatePrettyShort() {
|
function getCurrentPrinterStatePrettyShort() {
|
||||||
if (!cupsAvailable || !selectedPrinter)
|
if (!cupsAvailable || !selectedPrinter)
|
||||||
return ""
|
return "";
|
||||||
|
|
||||||
var printer = printers[selectedPrinter]
|
var printer = printers[selectedPrinter];
|
||||||
return getPrinterStateTranslation(printer.state) + " (" + getPrinterStateReasonTranslation(printer.stateReason) + ")"
|
return getPrinterStateTranslation(printer.state) + " (" + getPrinterStateReasonTranslation(printer.stateReason) + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCurrentPrinterStatePretty() {
|
function getCurrentPrinterStatePretty() {
|
||||||
if (!cupsAvailable || !selectedPrinter)
|
if (!cupsAvailable || !selectedPrinter)
|
||||||
return ""
|
return "";
|
||||||
|
|
||||||
var printer = printers[selectedPrinter]
|
var printer = printers[selectedPrinter];
|
||||||
return getPrinterStateTranslation(printer.state) + " (" + I18n.tr("Reason") + ": " + getPrinterStateReasonTranslation(printer.stateReason) + ")"
|
return getPrinterStateTranslation(printer.state) + " (" + I18n.tr("Reason") + ": " + getPrinterStateReasonTranslation(printer.stateReason) + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCurrentPrinterJobs() {
|
function getCurrentPrinterJobs() {
|
||||||
if (!cupsAvailable || !selectedPrinter)
|
if (!cupsAvailable || !selectedPrinter)
|
||||||
return []
|
return [];
|
||||||
|
|
||||||
return getJobs(selectedPrinter)
|
return getJobs(selectedPrinter);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getJobs(printerName) {
|
function getJobs(printerName) {
|
||||||
if (!cupsAvailable)
|
if (!cupsAvailable)
|
||||||
return ""
|
return "";
|
||||||
|
|
||||||
var printer = printers[printerName]
|
var printer = printers[printerName];
|
||||||
return printer.jobs
|
return printer.jobs;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getJobsNum(printerName) {
|
function getJobsNum(printerName) {
|
||||||
if (!cupsAvailable)
|
if (!cupsAvailable)
|
||||||
return 0
|
return 0;
|
||||||
|
|
||||||
var printer = printers[printerName]
|
var printer = printers[printerName];
|
||||||
return printer.jobs.length
|
return printer.jobs.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
function pausePrinter(printerName) {
|
function pausePrinter(printerName) {
|
||||||
if (!cupsAvailable)
|
if (!cupsAvailable)
|
||||||
return
|
return;
|
||||||
|
|
||||||
const params = {
|
const params = {
|
||||||
"printerName": printerName
|
"printerName": printerName
|
||||||
}
|
};
|
||||||
|
|
||||||
DMSService.sendRequest("cups.pausePrinter", params, response => {
|
DMSService.sendRequest("cups.pausePrinter", params, response => {
|
||||||
if (response.error) {
|
if (response.error) {
|
||||||
ToastService.showError(I18n.tr("Failed to pause printer") + " - " + response.error)
|
ToastService.showError(I18n.tr("Failed to pause printer") + " - " + response.error);
|
||||||
} else {
|
} else {
|
||||||
getState()
|
getState();
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function resumePrinter(printerName) {
|
function resumePrinter(printerName) {
|
||||||
if (!cupsAvailable)
|
if (!cupsAvailable)
|
||||||
return
|
return;
|
||||||
|
|
||||||
const params = {
|
const params = {
|
||||||
"printerName": printerName
|
"printerName": printerName
|
||||||
}
|
};
|
||||||
|
|
||||||
DMSService.sendRequest("cups.resumePrinter", params, response => {
|
DMSService.sendRequest("cups.resumePrinter", params, response => {
|
||||||
if (response.error) {
|
if (response.error) {
|
||||||
ToastService.showError(I18n.tr("Failed to resume printer") + " - " + response.error)
|
ToastService.showError(I18n.tr("Failed to resume printer") + " - " + response.error);
|
||||||
} else {
|
} else {
|
||||||
getState()
|
getState();
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function cancelJob(printerName, jobID) {
|
function cancelJob(printerName, jobID) {
|
||||||
if (!cupsAvailable)
|
if (!cupsAvailable)
|
||||||
return
|
return;
|
||||||
|
|
||||||
const params = {
|
const params = {
|
||||||
"printerName": printerName,
|
"printerName": printerName,
|
||||||
"jobID": jobID
|
"jobID": jobID
|
||||||
}
|
};
|
||||||
|
|
||||||
DMSService.sendRequest("cups.cancelJob", params, response => {
|
DMSService.sendRequest("cups.cancelJob", params, response => {
|
||||||
if (response.error) {
|
if (response.error) {
|
||||||
ToastService.showError(I18n.tr("Failed to cancel selected job") + " - " + response.error)
|
ToastService.showError(I18n.tr("Failed to cancel selected job") + " - " + response.error);
|
||||||
} else {
|
} else {
|
||||||
fetchJobsForPrinter(printerName)
|
fetchJobsForPrinter(printerName);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function purgeJobs(printerName) {
|
function purgeJobs(printerName) {
|
||||||
if (!cupsAvailable)
|
if (!cupsAvailable)
|
||||||
return
|
return;
|
||||||
|
|
||||||
const params = {
|
const params = {
|
||||||
"printerName": printerName
|
"printerName": printerName
|
||||||
}
|
};
|
||||||
|
|
||||||
DMSService.sendRequest("cups.purgeJobs", params, response => {
|
DMSService.sendRequest("cups.purgeJobs", params, response => {
|
||||||
if (response.error) {
|
if (response.error) {
|
||||||
ToastService.showError(I18n.tr("Failed to cancel all jobs") + " - " + response.error)
|
ToastService.showError(I18n.tr("Failed to cancel all jobs") + " - " + response.error);
|
||||||
} else {
|
} else {
|
||||||
fetchJobsForPrinter(printerName)
|
fetchJobsForPrinter(printerName);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDevices() {
|
||||||
|
if (!cupsAvailable)
|
||||||
|
return;
|
||||||
|
loadingDevices = true;
|
||||||
|
DMSService.sendRequest("cups.getDevices", null, response => {
|
||||||
|
loadingDevices = false;
|
||||||
|
if (response.result) {
|
||||||
|
devices = response.result;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPPDs() {
|
||||||
|
if (!cupsAvailable)
|
||||||
|
return;
|
||||||
|
loadingPPDs = true;
|
||||||
|
DMSService.sendRequest("cups.getPPDs", null, response => {
|
||||||
|
loadingPPDs = false;
|
||||||
|
if (response.result) {
|
||||||
|
ppds = response.result;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getClasses() {
|
||||||
|
if (!cupsAvailable)
|
||||||
|
return;
|
||||||
|
loadingClasses = true;
|
||||||
|
DMSService.sendRequest("cups.getClasses", null, response => {
|
||||||
|
loadingClasses = false;
|
||||||
|
if (response.result) {
|
||||||
|
printerClasses = response.result;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function createPrinter(name, deviceURI, ppd, options) {
|
||||||
|
if (!cupsAvailable)
|
||||||
|
return;
|
||||||
|
creatingPrinter = true;
|
||||||
|
const params = {
|
||||||
|
"name": name,
|
||||||
|
"deviceURI": deviceURI,
|
||||||
|
"ppd": ppd
|
||||||
|
};
|
||||||
|
if (options) {
|
||||||
|
if (options.shared !== undefined)
|
||||||
|
params.shared = options.shared;
|
||||||
|
if (options.location)
|
||||||
|
params.location = options.location;
|
||||||
|
if (options.information)
|
||||||
|
params.information = options.information;
|
||||||
|
if (options.errorPolicy)
|
||||||
|
params.errorPolicy = options.errorPolicy;
|
||||||
|
}
|
||||||
|
|
||||||
|
DMSService.sendRequest("cups.createPrinter", params, response => {
|
||||||
|
creatingPrinter = false;
|
||||||
|
if (response.error) {
|
||||||
|
ToastService.showError(I18n.tr("Failed to create printer") + " - " + response.error);
|
||||||
|
} else {
|
||||||
|
ToastService.showInfo(I18n.tr("Printer created successfully"));
|
||||||
|
getState();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function deletePrinter(printerName) {
|
||||||
|
if (!cupsAvailable)
|
||||||
|
return;
|
||||||
|
const params = {
|
||||||
|
"printerName": printerName
|
||||||
|
};
|
||||||
|
|
||||||
|
DMSService.sendRequest("cups.deletePrinter", params, response => {
|
||||||
|
if (response.error) {
|
||||||
|
ToastService.showError(I18n.tr("Failed to delete printer") + " - " + response.error);
|
||||||
|
} else {
|
||||||
|
ToastService.showInfo(I18n.tr("Printer deleted"));
|
||||||
|
if (selectedPrinter === printerName) {
|
||||||
|
selectedPrinter = "";
|
||||||
|
}
|
||||||
|
getState();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function acceptJobs(printerName) {
|
||||||
|
if (!cupsAvailable)
|
||||||
|
return;
|
||||||
|
const params = {
|
||||||
|
"printerName": printerName
|
||||||
|
};
|
||||||
|
|
||||||
|
DMSService.sendRequest("cups.acceptJobs", params, response => {
|
||||||
|
if (response.error) {
|
||||||
|
ToastService.showError(I18n.tr("Failed to enable job acceptance") + " - " + response.error);
|
||||||
|
} else {
|
||||||
|
getState();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function rejectJobs(printerName) {
|
||||||
|
if (!cupsAvailable)
|
||||||
|
return;
|
||||||
|
const params = {
|
||||||
|
"printerName": printerName
|
||||||
|
};
|
||||||
|
|
||||||
|
DMSService.sendRequest("cups.rejectJobs", params, response => {
|
||||||
|
if (response.error) {
|
||||||
|
ToastService.showError(I18n.tr("Failed to disable job acceptance") + " - " + response.error);
|
||||||
|
} else {
|
||||||
|
getState();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function setPrinterShared(printerName, shared) {
|
||||||
|
if (!cupsAvailable)
|
||||||
|
return;
|
||||||
|
const params = {
|
||||||
|
"printerName": printerName,
|
||||||
|
"shared": shared
|
||||||
|
};
|
||||||
|
|
||||||
|
DMSService.sendRequest("cups.setPrinterShared", params, response => {
|
||||||
|
if (response.error) {
|
||||||
|
ToastService.showError(I18n.tr("Failed to update sharing") + " - " + response.error);
|
||||||
|
} else {
|
||||||
|
getState();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function setPrinterLocation(printerName, location) {
|
||||||
|
if (!cupsAvailable)
|
||||||
|
return;
|
||||||
|
const params = {
|
||||||
|
"printerName": printerName,
|
||||||
|
"location": location
|
||||||
|
};
|
||||||
|
|
||||||
|
DMSService.sendRequest("cups.setPrinterLocation", params, response => {
|
||||||
|
if (response.error) {
|
||||||
|
ToastService.showError(I18n.tr("Failed to update location") + " - " + response.error);
|
||||||
|
} else {
|
||||||
|
getState();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function setPrinterInfo(printerName, info) {
|
||||||
|
if (!cupsAvailable)
|
||||||
|
return;
|
||||||
|
const params = {
|
||||||
|
"printerName": printerName,
|
||||||
|
"info": info
|
||||||
|
};
|
||||||
|
|
||||||
|
DMSService.sendRequest("cups.setPrinterInfo", params, response => {
|
||||||
|
if (response.error) {
|
||||||
|
ToastService.showError(I18n.tr("Failed to update description") + " - " + response.error);
|
||||||
|
} else {
|
||||||
|
getState();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function printTestPage(printerName) {
|
||||||
|
if (!cupsAvailable)
|
||||||
|
return;
|
||||||
|
const params = {
|
||||||
|
"printerName": printerName
|
||||||
|
};
|
||||||
|
|
||||||
|
DMSService.sendRequest("cups.printTestPage", params, response => {
|
||||||
|
if (response.error) {
|
||||||
|
ToastService.showError(I18n.tr("Failed to print test page") + " - " + response.error);
|
||||||
|
} else {
|
||||||
|
ToastService.showInfo(I18n.tr("Test page sent to printer"));
|
||||||
|
fetchJobsForPrinter(printerName);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function moveJob(jobID, destPrinter) {
|
||||||
|
if (!cupsAvailable)
|
||||||
|
return;
|
||||||
|
const params = {
|
||||||
|
"jobID": jobID,
|
||||||
|
"destPrinter": destPrinter
|
||||||
|
};
|
||||||
|
|
||||||
|
DMSService.sendRequest("cups.moveJob", params, response => {
|
||||||
|
if (response.error) {
|
||||||
|
ToastService.showError(I18n.tr("Failed to move job") + " - " + response.error);
|
||||||
|
} else {
|
||||||
|
fetchAllJobs();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function restartJob(jobID) {
|
||||||
|
if (!cupsAvailable)
|
||||||
|
return;
|
||||||
|
const params = {
|
||||||
|
"jobID": jobID
|
||||||
|
};
|
||||||
|
|
||||||
|
DMSService.sendRequest("cups.restartJob", params, response => {
|
||||||
|
if (response.error) {
|
||||||
|
ToastService.showError(I18n.tr("Failed to restart job") + " - " + response.error);
|
||||||
|
} else {
|
||||||
|
fetchAllJobs();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function holdJob(jobID, holdUntil) {
|
||||||
|
if (!cupsAvailable)
|
||||||
|
return;
|
||||||
|
const params = {
|
||||||
|
"jobID": jobID
|
||||||
|
};
|
||||||
|
if (holdUntil) {
|
||||||
|
params.holdUntil = holdUntil;
|
||||||
|
}
|
||||||
|
|
||||||
|
DMSService.sendRequest("cups.holdJob", params, response => {
|
||||||
|
if (response.error) {
|
||||||
|
ToastService.showError(I18n.tr("Failed to hold job") + " - " + response.error);
|
||||||
|
} else {
|
||||||
|
fetchAllJobs();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function addPrinterToClass(className, printerName) {
|
||||||
|
if (!cupsAvailable)
|
||||||
|
return;
|
||||||
|
const params = {
|
||||||
|
"className": className,
|
||||||
|
"printerName": printerName
|
||||||
|
};
|
||||||
|
|
||||||
|
DMSService.sendRequest("cups.addPrinterToClass", params, response => {
|
||||||
|
if (response.error) {
|
||||||
|
ToastService.showError(I18n.tr("Failed to add printer to class") + " - " + response.error);
|
||||||
|
} else {
|
||||||
|
getClasses();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function removePrinterFromClass(className, printerName) {
|
||||||
|
if (!cupsAvailable)
|
||||||
|
return;
|
||||||
|
const params = {
|
||||||
|
"className": className,
|
||||||
|
"printerName": printerName
|
||||||
|
};
|
||||||
|
|
||||||
|
DMSService.sendRequest("cups.removePrinterFromClass", params, response => {
|
||||||
|
if (response.error) {
|
||||||
|
ToastService.showError(I18n.tr("Failed to remove printer from class") + " - " + response.error);
|
||||||
|
} else {
|
||||||
|
getClasses();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteClass(className) {
|
||||||
|
if (!cupsAvailable)
|
||||||
|
return;
|
||||||
|
const params = {
|
||||||
|
"className": className
|
||||||
|
};
|
||||||
|
|
||||||
|
DMSService.sendRequest("cups.deleteClass", params, response => {
|
||||||
|
if (response.error) {
|
||||||
|
ToastService.showError(I18n.tr("Failed to delete class") + " - " + response.error);
|
||||||
|
} else {
|
||||||
|
getClasses();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPrinterData(printerName) {
|
||||||
|
if (!printers || !printers[printerName])
|
||||||
|
return null;
|
||||||
|
return printers[printerName];
|
||||||
|
}
|
||||||
|
|
||||||
|
function getJobStateTranslation(state) {
|
||||||
|
switch (state) {
|
||||||
|
case "pending":
|
||||||
|
return I18n.tr("Pending");
|
||||||
|
case "pending-held":
|
||||||
|
return I18n.tr("Held");
|
||||||
|
case "processing":
|
||||||
|
return I18n.tr("Processing");
|
||||||
|
case "processing-stopped":
|
||||||
|
return I18n.tr("Stopped");
|
||||||
|
case "canceled":
|
||||||
|
return I18n.tr("Canceled");
|
||||||
|
case "aborted":
|
||||||
|
return I18n.tr("Aborted");
|
||||||
|
case "completed":
|
||||||
|
return I18n.tr("Completed");
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
readonly property var states: ({
|
readonly property var states: ({
|
||||||
"idle": I18n.tr("Idle"),
|
"idle": I18n.tr("Idle"),
|
||||||
"processing": I18n.tr("Processing"),
|
"processing": I18n.tr("Processing"),
|
||||||
"stopped": I18n.tr("Stopped")
|
"stopped": I18n.tr("Stopped")
|
||||||
})
|
})
|
||||||
|
|
||||||
readonly property var reasonsGeneral: ({
|
readonly property var reasonsGeneral: ({
|
||||||
"none": I18n.tr("None"),
|
"none": I18n.tr("None"),
|
||||||
"other": I18n.tr("Other")
|
"other": I18n.tr("Other")
|
||||||
})
|
})
|
||||||
|
|
||||||
readonly property var reasonsSupplies: ({
|
readonly property var reasonsSupplies: ({
|
||||||
"toner-low": I18n.tr("Toner Low"),
|
"toner-low": I18n.tr("Toner Low"),
|
||||||
"toner-empty": I18n.tr("Toner Empty"),
|
"toner-empty": I18n.tr("Toner Empty"),
|
||||||
"marker-supply-low": I18n.tr("Marker Supply Low"),
|
"marker-supply-low": I18n.tr("Marker Supply Low"),
|
||||||
"marker-supply-empty": I18n.tr("Marker Supply Empty"),
|
"marker-supply-empty": I18n.tr("Marker Supply Empty"),
|
||||||
"marker-waste-almost-full": I18n.tr("Marker Waste Almost Full"),
|
"marker-waste-almost-full": I18n.tr("Marker Waste Almost Full"),
|
||||||
"marker-waste-full": I18n.tr("Marker Waste Full")
|
"marker-waste-full": I18n.tr("Marker Waste Full")
|
||||||
})
|
})
|
||||||
|
|
||||||
readonly property var reasonsMedia: ({
|
readonly property var reasonsMedia: ({
|
||||||
"media-low": I18n.tr("Media Low"),
|
"media-low": I18n.tr("Media Low"),
|
||||||
"media-empty": I18n.tr("Media Empty"),
|
"media-empty": I18n.tr("Media Empty"),
|
||||||
"media-needed": I18n.tr("Media Needed"),
|
"media-needed": I18n.tr("Media Needed"),
|
||||||
"media-jam": I18n.tr("Media Jam")
|
"media-jam": I18n.tr("Media Jam")
|
||||||
})
|
})
|
||||||
|
|
||||||
readonly property var reasonsParts: ({
|
readonly property var reasonsParts: ({
|
||||||
"cover-open": I18n.tr("Cover Open"),
|
"cover-open": I18n.tr("Cover Open"),
|
||||||
"door-open": I18n.tr("Door Open"),
|
"door-open": I18n.tr("Door Open"),
|
||||||
"interlock-open": I18n.tr("Interlock Open"),
|
"interlock-open": I18n.tr("Interlock Open"),
|
||||||
"output-tray-missing": I18n.tr("Output Tray Missing"),
|
"output-tray-missing": I18n.tr("Output Tray Missing"),
|
||||||
"output-area-almost-full": I18n.tr("Output Area Almost Full"),
|
"output-area-almost-full": I18n.tr("Output Area Almost Full"),
|
||||||
"output-area-full": I18n.tr("Output Area Full")
|
"output-area-full": I18n.tr("Output Area Full")
|
||||||
})
|
})
|
||||||
|
|
||||||
readonly property var reasonsErrors: ({
|
readonly property var reasonsErrors: ({
|
||||||
"paused": I18n.tr("Paused"),
|
"paused": I18n.tr("Paused"),
|
||||||
"shutdown": I18n.tr("Shutdown"),
|
"shutdown": I18n.tr("Shutdown"),
|
||||||
"connecting-to-device": I18n.tr("Connecting to Device"),
|
"connecting-to-device": I18n.tr("Connecting to Device"),
|
||||||
"timed-out": I18n.tr("Timed Out"),
|
"timed-out": I18n.tr("Timed Out"),
|
||||||
"stopping": I18n.tr("Stopping"),
|
"stopping": I18n.tr("Stopping"),
|
||||||
"stopped-partly": I18n.tr("Stopped Partly")
|
"stopped-partly": I18n.tr("Stopped Partly")
|
||||||
})
|
})
|
||||||
|
|
||||||
readonly property var reasonsService: ({
|
readonly property var reasonsService: ({
|
||||||
"spool-area-full": I18n.tr("Spool Area Full"),
|
"spool-area-full": I18n.tr("Spool Area Full"),
|
||||||
"cups-missing-filter-warning": I18n.tr("CUPS Missing Filter Warning"),
|
"cups-missing-filter-warning": I18n.tr("CUPS Missing Filter Warning"),
|
||||||
"cups-insecure-filter-warning": I18n.tr("CUPS Insecure Filter Warning")
|
"cups-insecure-filter-warning": I18n.tr("CUPS Insecure Filter Warning")
|
||||||
})
|
})
|
||||||
|
|
||||||
readonly property var reasonsConnectivity: ({
|
readonly property var reasonsConnectivity: ({
|
||||||
"offline-report": I18n.tr("Offline Report"),
|
"offline-report": I18n.tr("Offline Report"),
|
||||||
"moving-to-paused": I18n.tr("Moving to Paused")
|
"moving-to-paused": I18n.tr("Moving to Paused")
|
||||||
})
|
})
|
||||||
|
|
||||||
readonly property var severitySuffixes: ({
|
readonly property var severitySuffixes: ({
|
||||||
"-error": I18n.tr("Error"),
|
"-error": I18n.tr("Error"),
|
||||||
"-warning": I18n.tr("Warning"),
|
"-warning": I18n.tr("Warning"),
|
||||||
"-report": I18n.tr("Report")
|
"-report": I18n.tr("Report")
|
||||||
})
|
})
|
||||||
|
|
||||||
function getPrinterStateTranslation(state) {
|
function getPrinterStateTranslation(state) {
|
||||||
return states[state] || state
|
return states[state] || state;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPrinterStateReasonTranslation(reason) {
|
function getPrinterStateReasonTranslation(reason) {
|
||||||
let allReasons = Object.assign({}, reasonsGeneral, reasonsSupplies, reasonsMedia, reasonsParts, reasonsErrors, reasonsService, reasonsConnectivity)
|
let allReasons = Object.assign({}, reasonsGeneral, reasonsSupplies, reasonsMedia, reasonsParts, reasonsErrors, reasonsService, reasonsConnectivity);
|
||||||
|
|
||||||
let basReason = reason
|
let basReason = reason;
|
||||||
let suffix = ""
|
let suffix = "";
|
||||||
|
|
||||||
for (let s in severitySuffixes) {
|
for (let s in severitySuffixes) {
|
||||||
if (reason.endsWith(s)) {
|
if (reason.endsWith(s)) {
|
||||||
basReason = reason.slice(0, -s.length)
|
basReason = reason.slice(0, -s.length);
|
||||||
suffix = severitySuffixes[s]
|
suffix = severitySuffixes[s];
|
||||||
break
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let translation = allReasons[basReason] || basReason
|
let translation = allReasons[basReason] || basReason;
|
||||||
return suffix ? translation + " (" + suffix + ")" : translation
|
return suffix ? translation + " (" + suffix + ")" : translation;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
pragma Singleton
|
pragma Singleton
|
||||||
|
|
||||||
pragma ComponentBehavior: Bound
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
import QtCore
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Io
|
import Quickshell.Io
|
||||||
@@ -14,6 +12,7 @@ Singleton {
|
|||||||
property bool dmsAvailable: false
|
property bool dmsAvailable: false
|
||||||
property var capabilities: []
|
property var capabilities: []
|
||||||
property int apiVersion: 0
|
property int apiVersion: 0
|
||||||
|
property string cliVersion: ""
|
||||||
readonly property int expectedApiVersion: 1
|
readonly property int expectedApiVersion: 1
|
||||||
property var availablePlugins: []
|
property var availablePlugins: []
|
||||||
property var installedPlugins: []
|
property var installedPlugins: []
|
||||||
@@ -57,18 +56,18 @@ Singleton {
|
|||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
if (socketPath && socketPath.length > 0) {
|
if (socketPath && socketPath.length > 0) {
|
||||||
detectUpdateCommand()
|
detectUpdateCommand();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function detectUpdateCommand() {
|
function detectUpdateCommand() {
|
||||||
checkingUpdateCommand = true
|
checkingUpdateCommand = true;
|
||||||
checkAurHelper.running = true
|
checkAurHelper.running = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function startSocketConnection() {
|
function startSocketConnection() {
|
||||||
if (socketPath && socketPath.length > 0) {
|
if (socketPath && socketPath.length > 0) {
|
||||||
testProcess.running = true
|
testProcess.running = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,26 +78,26 @@ Singleton {
|
|||||||
|
|
||||||
stdout: StdioCollector {
|
stdout: StdioCollector {
|
||||||
onStreamFinished: {
|
onStreamFinished: {
|
||||||
const helper = text.trim()
|
const helper = text.trim();
|
||||||
if (helper.includes("paru")) {
|
if (helper.includes("paru")) {
|
||||||
checkDmsPackage.helper = "paru"
|
checkDmsPackage.helper = "paru";
|
||||||
checkDmsPackage.running = true
|
checkDmsPackage.running = true;
|
||||||
} else if (helper.includes("yay")) {
|
} else if (helper.includes("yay")) {
|
||||||
checkDmsPackage.helper = "yay"
|
checkDmsPackage.helper = "yay";
|
||||||
checkDmsPackage.running = true
|
checkDmsPackage.running = true;
|
||||||
} else {
|
} else {
|
||||||
updateCommand = "dms update"
|
updateCommand = "dms update";
|
||||||
checkingUpdateCommand = false
|
checkingUpdateCommand = false;
|
||||||
startSocketConnection()
|
startSocketConnection();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onExited: exitCode => {
|
onExited: exitCode => {
|
||||||
if (exitCode !== 0) {
|
if (exitCode !== 0) {
|
||||||
updateCommand = "dms update"
|
updateCommand = "dms update";
|
||||||
checkingUpdateCommand = false
|
checkingUpdateCommand = false;
|
||||||
startSocketConnection()
|
startSocketConnection();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -112,22 +111,22 @@ Singleton {
|
|||||||
stdout: StdioCollector {
|
stdout: StdioCollector {
|
||||||
onStreamFinished: {
|
onStreamFinished: {
|
||||||
if (text.includes("dms-shell-git")) {
|
if (text.includes("dms-shell-git")) {
|
||||||
updateCommand = checkDmsPackage.helper + " -S dms-shell-git"
|
updateCommand = checkDmsPackage.helper + " -S dms-shell-git";
|
||||||
} else if (text.includes("dms-shell-bin")) {
|
} else if (text.includes("dms-shell-bin")) {
|
||||||
updateCommand = checkDmsPackage.helper + " -S dms-shell-bin"
|
updateCommand = checkDmsPackage.helper + " -S dms-shell-bin";
|
||||||
} else {
|
} else {
|
||||||
updateCommand = "dms update"
|
updateCommand = "dms update";
|
||||||
}
|
}
|
||||||
checkingUpdateCommand = false
|
checkingUpdateCommand = false;
|
||||||
startSocketConnection()
|
startSocketConnection();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onExited: exitCode => {
|
onExited: exitCode => {
|
||||||
if (exitCode !== 0) {
|
if (exitCode !== 0) {
|
||||||
updateCommand = "dms update"
|
updateCommand = "dms update";
|
||||||
checkingUpdateCommand = false
|
checkingUpdateCommand = false;
|
||||||
startSocketConnection()
|
startSocketConnection();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -138,21 +137,21 @@ Singleton {
|
|||||||
|
|
||||||
onExited: exitCode => {
|
onExited: exitCode => {
|
||||||
if (exitCode === 0) {
|
if (exitCode === 0) {
|
||||||
root.dmsAvailable = true
|
root.dmsAvailable = true;
|
||||||
connectSocket()
|
connectSocket();
|
||||||
} else {
|
} else {
|
||||||
root.dmsAvailable = false
|
root.dmsAvailable = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function connectSocket() {
|
function connectSocket() {
|
||||||
if (!dmsAvailable || isConnected || isConnecting) {
|
if (!dmsAvailable || isConnected || isConnecting) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
isConnecting = true
|
isConnecting = true;
|
||||||
requestSocket.connected = true
|
requestSocket.connected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
DankSocket {
|
DankSocket {
|
||||||
@@ -162,32 +161,32 @@ Singleton {
|
|||||||
|
|
||||||
onConnectionStateChanged: {
|
onConnectionStateChanged: {
|
||||||
if (connected) {
|
if (connected) {
|
||||||
root.isConnected = true
|
root.isConnected = true;
|
||||||
root.isConnecting = false
|
root.isConnecting = false;
|
||||||
root.connectionStateChanged()
|
root.connectionStateChanged();
|
||||||
subscribeSocket.connected = true
|
subscribeSocket.connected = true;
|
||||||
} else {
|
} else {
|
||||||
root.isConnected = false
|
root.isConnected = false;
|
||||||
root.isConnecting = false
|
root.isConnecting = false;
|
||||||
root.apiVersion = 0
|
root.apiVersion = 0;
|
||||||
root.capabilities = []
|
root.capabilities = [];
|
||||||
root.connectionStateChanged()
|
root.connectionStateChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parser: SplitParser {
|
parser: SplitParser {
|
||||||
onRead: line => {
|
onRead: line => {
|
||||||
if (!line || line.length === 0) {
|
if (!line || line.length === 0) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("DMSService: Request socket <<", line)
|
console.log("DMSService: Request socket <<", line);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = JSON.parse(line)
|
const response = JSON.parse(line);
|
||||||
handleResponse(response)
|
handleResponse(response);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn("DMSService: Failed to parse request response:", line, e)
|
console.warn("DMSService: Failed to parse request response:", line, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -199,25 +198,25 @@ Singleton {
|
|||||||
connected: false
|
connected: false
|
||||||
|
|
||||||
onConnectionStateChanged: {
|
onConnectionStateChanged: {
|
||||||
root.subscribeConnected = connected
|
root.subscribeConnected = connected;
|
||||||
if (connected) {
|
if (connected) {
|
||||||
sendSubscribeRequest()
|
sendSubscribeRequest();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parser: SplitParser {
|
parser: SplitParser {
|
||||||
onRead: line => {
|
onRead: line => {
|
||||||
if (!line || line.length === 0) {
|
if (!line || line.length === 0) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("DMSService: Subscribe socket <<", line)
|
console.log("DMSService: Subscribe socket <<", line);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = JSON.parse(line)
|
const response = JSON.parse(line);
|
||||||
handleSubscriptionEvent(response)
|
handleSubscriptionEvent(response);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn("DMSService: Failed to parse subscription event:", line, e)
|
console.warn("DMSService: Failed to parse subscription event:", line, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -226,319 +225,317 @@ Singleton {
|
|||||||
function sendSubscribeRequest() {
|
function sendSubscribeRequest() {
|
||||||
const request = {
|
const request = {
|
||||||
"method": "subscribe"
|
"method": "subscribe"
|
||||||
}
|
};
|
||||||
|
|
||||||
if (activeSubscriptions.length > 0) {
|
if (activeSubscriptions.length > 0) {
|
||||||
request.params = {
|
request.params = {
|
||||||
"services": activeSubscriptions
|
"services": activeSubscriptions
|
||||||
}
|
};
|
||||||
console.log("DMSService: Subscribing to services:", JSON.stringify(activeSubscriptions))
|
console.log("DMSService: Subscribing to services:", JSON.stringify(activeSubscriptions));
|
||||||
} else {
|
} else {
|
||||||
console.log("DMSService: Subscribing to all services")
|
console.log("DMSService: Subscribing to all services");
|
||||||
}
|
}
|
||||||
|
|
||||||
subscribeSocket.send(request)
|
subscribeSocket.send(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
function subscribe(services) {
|
function subscribe(services) {
|
||||||
if (!Array.isArray(services)) {
|
if (!Array.isArray(services)) {
|
||||||
services = [services]
|
services = [services];
|
||||||
}
|
}
|
||||||
|
|
||||||
activeSubscriptions = services
|
activeSubscriptions = services;
|
||||||
|
|
||||||
if (subscribeConnected) {
|
if (subscribeConnected) {
|
||||||
subscribeSocket.connected = false
|
subscribeSocket.connected = false;
|
||||||
Qt.callLater(() => {
|
Qt.callLater(() => {
|
||||||
subscribeSocket.connected = true
|
subscribeSocket.connected = true;
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function addSubscription(service) {
|
function addSubscription(service) {
|
||||||
if (activeSubscriptions.includes("all")) {
|
if (activeSubscriptions.includes("all"))
|
||||||
console.warn("DMSService: Cannot add specific subscription when subscribed to 'all'")
|
return;
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!activeSubscriptions.includes(service)) {
|
if (!activeSubscriptions.includes(service)) {
|
||||||
const newSubs = [...activeSubscriptions, service]
|
const newSubs = [...activeSubscriptions, service];
|
||||||
subscribe(newSubs)
|
subscribe(newSubs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeSubscription(service) {
|
function removeSubscription(service) {
|
||||||
if (activeSubscriptions.includes("all")) {
|
if (activeSubscriptions.includes("all")) {
|
||||||
const allServices = ["network", "loginctl", "freedesktop", "gamma", "bluetooth", "dwl", "brightness", "extworkspace"]
|
const allServices = ["network", "loginctl", "freedesktop", "gamma", "bluetooth", "dwl", "brightness", "extworkspace"];
|
||||||
const filtered = allServices.filter(s => s !== service)
|
const filtered = allServices.filter(s => s !== service);
|
||||||
subscribe(filtered)
|
subscribe(filtered);
|
||||||
} else {
|
} else {
|
||||||
const filtered = activeSubscriptions.filter(s => s !== service)
|
const filtered = activeSubscriptions.filter(s => s !== service);
|
||||||
if (filtered.length === 0) {
|
if (filtered.length === 0) {
|
||||||
console.warn("DMSService: Cannot remove last subscription")
|
console.warn("DMSService: Cannot remove last subscription");
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
subscribe(filtered)
|
subscribe(filtered);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function subscribeAll() {
|
function subscribeAll() {
|
||||||
subscribe(["all"])
|
subscribe(["all"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function subscribeAllExcept(excludeServices) {
|
function subscribeAllExcept(excludeServices) {
|
||||||
if (!Array.isArray(excludeServices)) {
|
if (!Array.isArray(excludeServices)) {
|
||||||
excludeServices = [excludeServices]
|
excludeServices = [excludeServices];
|
||||||
}
|
}
|
||||||
|
|
||||||
const allServices = ["network", "loginctl", "freedesktop", "gamma", "bluetooth", "cups", "dwl", "brightness", "extworkspace"]
|
const allServices = ["network", "loginctl", "freedesktop", "gamma", "bluetooth", "cups", "dwl", "brightness", "extworkspace"];
|
||||||
const filtered = allServices.filter(s => !excludeServices.includes(s))
|
const filtered = allServices.filter(s => !excludeServices.includes(s));
|
||||||
subscribe(filtered)
|
subscribe(filtered);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleSubscriptionEvent(response) {
|
function handleSubscriptionEvent(response) {
|
||||||
if (response.error) {
|
if (response.error) {
|
||||||
if (response.error.includes("unknown method") && response.error.includes("subscribe")) {
|
if (response.error.includes("unknown method") && response.error.includes("subscribe")) {
|
||||||
if (!shownOutdatedError) {
|
if (!shownOutdatedError) {
|
||||||
console.error("DMSService: Server does not support subscribe method")
|
console.error("DMSService: Server does not support subscribe method");
|
||||||
ToastService.showError(I18n.tr("DMS out of date"), I18n.tr("To update, run the following command:"), updateCommand)
|
ToastService.showError(I18n.tr("DMS out of date"), I18n.tr("To update, run the following command:"), updateCommand);
|
||||||
shownOutdatedError = true
|
shownOutdatedError = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!response.result) {
|
if (!response.result) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const service = response.result.service
|
const service = response.result.service;
|
||||||
const data = response.result.data
|
const data = response.result.data;
|
||||||
|
|
||||||
if (service === "server") {
|
if (service === "server") {
|
||||||
apiVersion = data.apiVersion || 0
|
apiVersion = data.apiVersion || 0;
|
||||||
capabilities = data.capabilities || []
|
cliVersion = data.cliVersion || "";
|
||||||
|
capabilities = data.capabilities || [];
|
||||||
|
|
||||||
console.info("DMSService: Connected (API v" + apiVersion + ") -", JSON.stringify(capabilities))
|
console.info("DMSService: Connected (API v" + apiVersion + ", CLI " + cliVersion + ") -", JSON.stringify(capabilities));
|
||||||
|
|
||||||
if (apiVersion < expectedApiVersion) {
|
if (apiVersion < expectedApiVersion) {
|
||||||
ToastService.showError("DMS server is outdated (API v" + apiVersion + ", expected v" + expectedApiVersion + ")")
|
ToastService.showError("DMS server is outdated (API v" + apiVersion + ", expected v" + expectedApiVersion + ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
capabilitiesReceived()
|
capabilitiesReceived();
|
||||||
} else if (service === "network") {
|
} else if (service === "network") {
|
||||||
networkStateUpdate(data)
|
networkStateUpdate(data);
|
||||||
} else if (service === "network.credentials") {
|
} else if (service === "network.credentials") {
|
||||||
credentialsRequest(data)
|
credentialsRequest(data);
|
||||||
} else if (service === "loginctl") {
|
} else if (service === "loginctl") {
|
||||||
if (data.event) {
|
if (data.event) {
|
||||||
loginctlEvent(data)
|
loginctlEvent(data);
|
||||||
} else {
|
} else {
|
||||||
loginctlStateUpdate(data)
|
loginctlStateUpdate(data);
|
||||||
}
|
}
|
||||||
} else if (service === "bluetooth.pairing") {
|
} else if (service === "bluetooth.pairing") {
|
||||||
bluetoothPairingRequest(data)
|
bluetoothPairingRequest(data);
|
||||||
} else if (service === "cups") {
|
} else if (service === "cups") {
|
||||||
cupsStateUpdate(data)
|
cupsStateUpdate(data);
|
||||||
} else if (service === "dwl") {
|
} else if (service === "dwl") {
|
||||||
dwlStateUpdate(data)
|
dwlStateUpdate(data);
|
||||||
} else if (service === "brightness") {
|
} else if (service === "brightness") {
|
||||||
brightnessStateUpdate(data)
|
brightnessStateUpdate(data);
|
||||||
} else if (service === "brightness.update") {
|
} else if (service === "brightness.update") {
|
||||||
if (data.device) {
|
if (data.device) {
|
||||||
brightnessDeviceUpdate(data.device)
|
brightnessDeviceUpdate(data.device);
|
||||||
}
|
}
|
||||||
} else if (service === "extworkspace") {
|
} else if (service === "extworkspace") {
|
||||||
extWorkspaceStateUpdate(data)
|
extWorkspaceStateUpdate(data);
|
||||||
} else if (service === "wlroutput") {
|
} else if (service === "wlroutput") {
|
||||||
wlrOutputStateUpdate(data)
|
wlrOutputStateUpdate(data);
|
||||||
} else if (service === "evdev") {
|
} else if (service === "evdev") {
|
||||||
if (data.capsLock !== undefined) {
|
if (data.capsLock !== undefined) {
|
||||||
capsLockState = data.capsLock
|
capsLockState = data.capsLock;
|
||||||
}
|
}
|
||||||
evdevStateUpdate(data)
|
evdevStateUpdate(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendRequest(method, params, callback) {
|
function sendRequest(method, params, callback) {
|
||||||
if (!isConnected) {
|
if (!isConnected) {
|
||||||
console.warn("DMSService.sendRequest: Not connected, method:", method)
|
console.warn("DMSService.sendRequest: Not connected, method:", method);
|
||||||
if (callback) {
|
if (callback) {
|
||||||
callback({
|
callback({
|
||||||
"error": "not connected to DMS socket"
|
"error": "not connected to DMS socket"
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
requestIdCounter++
|
requestIdCounter++;
|
||||||
const id = Date.now() + requestIdCounter
|
const id = Date.now() + requestIdCounter;
|
||||||
const request = {
|
const request = {
|
||||||
"id": id,
|
"id": id,
|
||||||
"method": method
|
"method": method
|
||||||
}
|
};
|
||||||
|
|
||||||
if (params) {
|
if (params) {
|
||||||
request.params = params
|
request.params = params;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (callback) {
|
if (callback) {
|
||||||
pendingRequests[id] = callback
|
pendingRequests[id] = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("DMSService.sendRequest: Sending request id=" + id + " method=" + method)
|
console.log("DMSService.sendRequest: Sending request id=" + id + " method=" + method);
|
||||||
requestSocket.send(request)
|
requestSocket.send(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleResponse(response) {
|
function handleResponse(response) {
|
||||||
const callback = pendingRequests[response.id]
|
const callback = pendingRequests[response.id];
|
||||||
|
|
||||||
if (callback) {
|
if (callback) {
|
||||||
delete pendingRequests[response.id]
|
delete pendingRequests[response.id];
|
||||||
callback(response)
|
callback(response);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function ping(callback) {
|
function ping(callback) {
|
||||||
sendRequest("ping", null, callback)
|
sendRequest("ping", null, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
function listPlugins(callback) {
|
function listPlugins(callback) {
|
||||||
sendRequest("plugins.list", null, response => {
|
sendRequest("plugins.list", null, response => {
|
||||||
if (response.result) {
|
if (response.result) {
|
||||||
availablePlugins = response.result
|
availablePlugins = response.result;
|
||||||
pluginsListReceived(response.result)
|
pluginsListReceived(response.result);
|
||||||
}
|
}
|
||||||
if (callback) {
|
if (callback) {
|
||||||
callback(response)
|
callback(response);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function listInstalled(callback) {
|
function listInstalled(callback) {
|
||||||
sendRequest("plugins.listInstalled", null, response => {
|
sendRequest("plugins.listInstalled", null, response => {
|
||||||
if (response.result) {
|
if (response.result) {
|
||||||
installedPlugins = response.result
|
installedPlugins = response.result;
|
||||||
installedPluginsReceived(response.result)
|
installedPluginsReceived(response.result);
|
||||||
}
|
}
|
||||||
if (callback) {
|
if (callback) {
|
||||||
callback(response)
|
callback(response);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function search(query, category, compositor, capability, callback) {
|
function search(query, category, compositor, capability, callback) {
|
||||||
const params = {
|
const params = {
|
||||||
"query": query
|
"query": query
|
||||||
}
|
};
|
||||||
if (category) {
|
if (category) {
|
||||||
params.category = category
|
params.category = category;
|
||||||
}
|
}
|
||||||
if (compositor) {
|
if (compositor) {
|
||||||
params.compositor = compositor
|
params.compositor = compositor;
|
||||||
}
|
}
|
||||||
if (capability) {
|
if (capability) {
|
||||||
params.capability = capability
|
params.capability = capability;
|
||||||
}
|
}
|
||||||
|
|
||||||
sendRequest("plugins.search", params, response => {
|
sendRequest("plugins.search", params, response => {
|
||||||
if (response.result) {
|
if (response.result) {
|
||||||
searchResultsReceived(response.result)
|
searchResultsReceived(response.result);
|
||||||
}
|
}
|
||||||
if (callback) {
|
if (callback) {
|
||||||
callback(response)
|
callback(response);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function install(pluginName, callback) {
|
function install(pluginName, callback) {
|
||||||
sendRequest("plugins.install", {
|
sendRequest("plugins.install", {
|
||||||
"name": pluginName
|
"name": pluginName
|
||||||
}, response => {
|
}, response => {
|
||||||
if (callback) {
|
if (callback) {
|
||||||
callback(response)
|
callback(response);
|
||||||
}
|
}
|
||||||
if (!response.error) {
|
if (!response.error) {
|
||||||
listInstalled()
|
listInstalled();
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function uninstall(pluginName, callback) {
|
function uninstall(pluginName, callback) {
|
||||||
sendRequest("plugins.uninstall", {
|
sendRequest("plugins.uninstall", {
|
||||||
"name": pluginName
|
"name": pluginName
|
||||||
}, response => {
|
}, response => {
|
||||||
if (callback) {
|
if (callback) {
|
||||||
callback(response)
|
callback(response);
|
||||||
}
|
}
|
||||||
if (!response.error) {
|
if (!response.error) {
|
||||||
listInstalled()
|
listInstalled();
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function update(pluginName, callback) {
|
function update(pluginName, callback) {
|
||||||
sendRequest("plugins.update", {
|
sendRequest("plugins.update", {
|
||||||
"name": pluginName
|
"name": pluginName
|
||||||
}, response => {
|
}, response => {
|
||||||
if (callback) {
|
if (callback) {
|
||||||
callback(response)
|
callback(response);
|
||||||
}
|
}
|
||||||
if (!response.error) {
|
if (!response.error) {
|
||||||
listInstalled()
|
listInstalled();
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function lockSession(callback) {
|
function lockSession(callback) {
|
||||||
sendRequest("loginctl.lock", null, callback)
|
sendRequest("loginctl.lock", null, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
function unlockSession(callback) {
|
function unlockSession(callback) {
|
||||||
sendRequest("loginctl.unlock", null, callback)
|
sendRequest("loginctl.unlock", null, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
function bluetoothPair(devicePath, callback) {
|
function bluetoothPair(devicePath, callback) {
|
||||||
sendRequest("bluetooth.pair", {
|
sendRequest("bluetooth.pair", {
|
||||||
"device": devicePath
|
"device": devicePath
|
||||||
}, callback)
|
}, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
function bluetoothConnect(devicePath, callback) {
|
function bluetoothConnect(devicePath, callback) {
|
||||||
sendRequest("bluetooth.connect", {
|
sendRequest("bluetooth.connect", {
|
||||||
"device": devicePath
|
"device": devicePath
|
||||||
}, callback)
|
}, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
function bluetoothDisconnect(devicePath, callback) {
|
function bluetoothDisconnect(devicePath, callback) {
|
||||||
sendRequest("bluetooth.disconnect", {
|
sendRequest("bluetooth.disconnect", {
|
||||||
"device": devicePath
|
"device": devicePath
|
||||||
}, callback)
|
}, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
function bluetoothRemove(devicePath, callback) {
|
function bluetoothRemove(devicePath, callback) {
|
||||||
sendRequest("bluetooth.remove", {
|
sendRequest("bluetooth.remove", {
|
||||||
"device": devicePath
|
"device": devicePath
|
||||||
}, callback)
|
}, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
function bluetoothTrust(devicePath, callback) {
|
function bluetoothTrust(devicePath, callback) {
|
||||||
sendRequest("bluetooth.trust", {
|
sendRequest("bluetooth.trust", {
|
||||||
"device": devicePath
|
"device": devicePath
|
||||||
}, callback)
|
}, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
function bluetoothSubmitPairing(token, secrets, accept, callback) {
|
function bluetoothSubmitPairing(token, secrets, accept, callback) {
|
||||||
sendRequest("bluetooth.pairing.submit", {
|
sendRequest("bluetooth.pairing.submit", {
|
||||||
"token": token,
|
"token": token,
|
||||||
"secrets": secrets,
|
"secrets": secrets,
|
||||||
"accept": accept
|
"accept": accept
|
||||||
}, callback)
|
}, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
function bluetoothCancelPairing(token, callback) {
|
function bluetoothCancelPairing(token, callback) {
|
||||||
sendRequest("bluetooth.pairing.cancel", {
|
sendRequest("bluetooth.pairing.cancel", {
|
||||||
"token": token
|
"token": token
|
||||||
}, callback)
|
}, callback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,17 @@ Item {
|
|||||||
property var options: []
|
property var options: []
|
||||||
property var optionIcons: []
|
property var optionIcons: []
|
||||||
property bool enableFuzzySearch: false
|
property bool enableFuzzySearch: false
|
||||||
|
|
||||||
|
onOptionsChanged: {
|
||||||
|
if (dropdownMenu.visible) {
|
||||||
|
dropdownMenu.fzfFinder = new Fzf.Finder(options, {
|
||||||
|
"selector": option => option,
|
||||||
|
"limit": 50,
|
||||||
|
"casing": "case-insensitive"
|
||||||
|
});
|
||||||
|
dropdownMenu.updateFilteredOptions();
|
||||||
|
}
|
||||||
|
}
|
||||||
property int popupWidthOffset: 0
|
property int popupWidthOffset: 0
|
||||||
property int maxPopupHeight: 400
|
property int maxPopupHeight: 400
|
||||||
property bool openUpwards: false
|
property bool openUpwards: false
|
||||||
@@ -30,9 +41,9 @@ Item {
|
|||||||
implicitHeight: compactMode ? 40 : Math.max(60, labelColumn.implicitHeight + Theme.spacingM)
|
implicitHeight: compactMode ? 40 : Math.max(60, labelColumn.implicitHeight + Theme.spacingM)
|
||||||
|
|
||||||
Component.onDestruction: {
|
Component.onDestruction: {
|
||||||
const popup = dropdownMenu
|
const popup = dropdownMenu;
|
||||||
if (popup && popup.visible) {
|
if (popup && popup.visible) {
|
||||||
popup.close()
|
popup.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,38 +96,38 @@ Item {
|
|||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (dropdownMenu.visible) {
|
if (dropdownMenu.visible) {
|
||||||
dropdownMenu.close()
|
dropdownMenu.close();
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dropdownMenu.searchQuery = ""
|
dropdownMenu.searchQuery = "";
|
||||||
dropdownMenu.updateFilteredOptions()
|
dropdownMenu.updateFilteredOptions();
|
||||||
|
|
||||||
dropdownMenu.open()
|
dropdownMenu.open();
|
||||||
|
|
||||||
const pos = dropdown.mapToItem(Overlay.overlay, 0, 0)
|
const pos = dropdown.mapToItem(Overlay.overlay, 0, 0);
|
||||||
const popupWidth = dropdownMenu.width
|
const popupWidth = dropdownMenu.width;
|
||||||
const popupHeight = dropdownMenu.height
|
const popupHeight = dropdownMenu.height;
|
||||||
const overlayHeight = Overlay.overlay.height
|
const overlayHeight = Overlay.overlay.height;
|
||||||
|
|
||||||
if (root.openUpwards || pos.y + dropdown.height + popupHeight + 4 > overlayHeight) {
|
if (root.openUpwards || pos.y + dropdown.height + popupHeight + 4 > overlayHeight) {
|
||||||
if (root.alignPopupRight) {
|
if (root.alignPopupRight) {
|
||||||
dropdownMenu.x = pos.x + dropdown.width - popupWidth
|
dropdownMenu.x = pos.x + dropdown.width - popupWidth;
|
||||||
} else {
|
} else {
|
||||||
dropdownMenu.x = pos.x - (root.popupWidthOffset / 2)
|
dropdownMenu.x = pos.x - (root.popupWidthOffset / 2);
|
||||||
}
|
}
|
||||||
dropdownMenu.y = pos.y - popupHeight - 4
|
dropdownMenu.y = pos.y - popupHeight - 4;
|
||||||
} else {
|
} else {
|
||||||
if (root.alignPopupRight) {
|
if (root.alignPopupRight) {
|
||||||
dropdownMenu.x = pos.x + dropdown.width - popupWidth
|
dropdownMenu.x = pos.x + dropdown.width - popupWidth;
|
||||||
} else {
|
} else {
|
||||||
dropdownMenu.x = pos.x - (root.popupWidthOffset / 2)
|
dropdownMenu.x = pos.x - (root.popupWidthOffset / 2);
|
||||||
}
|
}
|
||||||
dropdownMenu.y = pos.y + dropdown.height + 4
|
dropdownMenu.y = pos.y + dropdown.height + 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (root.enableFuzzySearch && searchField.visible) {
|
if (root.enableFuzzySearch && searchField.visible) {
|
||||||
searchField.forceActiveFocus()
|
searchField.forceActiveFocus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -133,8 +144,8 @@ Item {
|
|||||||
|
|
||||||
DankIcon {
|
DankIcon {
|
||||||
name: {
|
name: {
|
||||||
const currentIndex = root.options.indexOf(root.currentValue)
|
const currentIndex = root.options.indexOf(root.currentValue);
|
||||||
return currentIndex >= 0 && root.optionIcons.length > currentIndex ? root.optionIcons[currentIndex] : ""
|
return currentIndex >= 0 && root.optionIcons.length > currentIndex ? root.optionIcons[currentIndex] : "";
|
||||||
}
|
}
|
||||||
size: 18
|
size: 18
|
||||||
color: Theme.surfaceText
|
color: Theme.surfaceText
|
||||||
@@ -186,39 +197,39 @@ Item {
|
|||||||
|
|
||||||
function updateFilteredOptions() {
|
function updateFilteredOptions() {
|
||||||
if (!root.enableFuzzySearch || searchQuery.length === 0) {
|
if (!root.enableFuzzySearch || searchQuery.length === 0) {
|
||||||
filteredOptions = root.options
|
filteredOptions = root.options;
|
||||||
selectedIndex = -1
|
selectedIndex = -1;
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const results = fzfFinder.find(searchQuery)
|
const results = fzfFinder.find(searchQuery);
|
||||||
filteredOptions = results.map(result => result.item)
|
filteredOptions = results.map(result => result.item);
|
||||||
selectedIndex = -1
|
selectedIndex = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectNext() {
|
function selectNext() {
|
||||||
if (filteredOptions.length === 0) {
|
if (filteredOptions.length === 0) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
selectedIndex = (selectedIndex + 1) % filteredOptions.length
|
selectedIndex = (selectedIndex + 1) % filteredOptions.length;
|
||||||
listView.positionViewAtIndex(selectedIndex, ListView.Contain)
|
listView.positionViewAtIndex(selectedIndex, ListView.Contain);
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectPrevious() {
|
function selectPrevious() {
|
||||||
if (filteredOptions.length === 0) {
|
if (filteredOptions.length === 0) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
selectedIndex = selectedIndex <= 0 ? filteredOptions.length - 1 : selectedIndex - 1
|
selectedIndex = selectedIndex <= 0 ? filteredOptions.length - 1 : selectedIndex - 1;
|
||||||
listView.positionViewAtIndex(selectedIndex, ListView.Contain)
|
listView.positionViewAtIndex(selectedIndex, ListView.Contain);
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectCurrent() {
|
function selectCurrent() {
|
||||||
if (selectedIndex < 0 || selectedIndex >= filteredOptions.length) {
|
if (selectedIndex < 0 || selectedIndex >= filteredOptions.length) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
root.currentValue = filteredOptions[selectedIndex]
|
root.currentValue = filteredOptions[selectedIndex];
|
||||||
root.valueChanged(filteredOptions[selectedIndex])
|
root.valueChanged(filteredOptions[selectedIndex]);
|
||||||
close()
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
parent: Overlay.overlay
|
parent: Overlay.overlay
|
||||||
@@ -270,8 +281,8 @@ Item {
|
|||||||
topPadding: Theme.spacingS
|
topPadding: Theme.spacingS
|
||||||
bottomPadding: Theme.spacingS
|
bottomPadding: Theme.spacingS
|
||||||
onTextChanged: {
|
onTextChanged: {
|
||||||
dropdownMenu.searchQuery = text
|
dropdownMenu.searchQuery = text;
|
||||||
dropdownMenu.updateFilteredOptions()
|
dropdownMenu.updateFilteredOptions();
|
||||||
}
|
}
|
||||||
Keys.onDownPressed: dropdownMenu.selectNext()
|
Keys.onDownPressed: dropdownMenu.selectNext()
|
||||||
Keys.onUpPressed: dropdownMenu.selectPrevious()
|
Keys.onUpPressed: dropdownMenu.selectPrevious()
|
||||||
@@ -279,17 +290,17 @@ Item {
|
|||||||
Keys.onEnterPressed: dropdownMenu.selectCurrent()
|
Keys.onEnterPressed: dropdownMenu.selectCurrent()
|
||||||
Keys.onPressed: event => {
|
Keys.onPressed: event => {
|
||||||
if (event.key === Qt.Key_N && event.modifiers & Qt.ControlModifier) {
|
if (event.key === Qt.Key_N && event.modifiers & Qt.ControlModifier) {
|
||||||
dropdownMenu.selectNext()
|
dropdownMenu.selectNext();
|
||||||
event.accepted = true
|
event.accepted = true;
|
||||||
} else if (event.key === Qt.Key_P && event.modifiers & Qt.ControlModifier) {
|
} else if (event.key === Qt.Key_P && event.modifiers & Qt.ControlModifier) {
|
||||||
dropdownMenu.selectPrevious()
|
dropdownMenu.selectPrevious();
|
||||||
event.accepted = true
|
event.accepted = true;
|
||||||
} else if (event.key === Qt.Key_J && event.modifiers & Qt.ControlModifier) {
|
} else if (event.key === Qt.Key_J && event.modifiers & Qt.ControlModifier) {
|
||||||
dropdownMenu.selectNext()
|
dropdownMenu.selectNext();
|
||||||
event.accepted = true
|
event.accepted = true;
|
||||||
} else if (event.key === Qt.Key_K && event.modifiers & Qt.ControlModifier) {
|
} else if (event.key === Qt.Key_K && event.modifiers & Qt.ControlModifier) {
|
||||||
dropdownMenu.selectPrevious()
|
dropdownMenu.selectPrevious();
|
||||||
event.accepted = true
|
event.accepted = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -362,9 +373,9 @@ Item {
|
|||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
root.currentValue = modelData
|
root.currentValue = modelData;
|
||||||
root.valueChanged(modelData)
|
root.valueChanged(modelData);
|
||||||
dropdownMenu.close()
|
dropdownMenu.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user