mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2025-12-05 21:15:38 -05:00
Compare commits
3 Commits
1d3fe81ff7
...
e6c3ae9397
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e6c3ae9397 | ||
|
|
df663aceb9 | ||
|
|
db7e597f67 |
@@ -34,12 +34,16 @@ packages:
|
||||
outpkg: mocks_network
|
||||
interfaces:
|
||||
Backend:
|
||||
github.com/AvengeMedia/danklinux/internal/server/cups:
|
||||
github.com/AvengeMedia/DankMaterialShell/core/internal/server/cups:
|
||||
config:
|
||||
dir: "internal/mocks/cups"
|
||||
outpkg: mocks_cups
|
||||
interfaces:
|
||||
CUPSClientInterface:
|
||||
PkHelper:
|
||||
config:
|
||||
dir: "internal/mocks/cups_pkhelper"
|
||||
outpkg: mocks_cups_pkhelper
|
||||
github.com/AvengeMedia/DankMaterialShell/core/internal/server/evdev:
|
||||
config:
|
||||
dir: "internal/mocks/evdev"
|
||||
|
||||
@@ -140,6 +140,7 @@ func runVersion(cmd *cobra.Command, args []string) {
|
||||
}
|
||||
|
||||
func startDebugServer() error {
|
||||
server.CLIVersion = Version
|
||||
return server.Start(true)
|
||||
}
|
||||
|
||||
|
||||
@@ -298,7 +298,8 @@ func ensureGreetdEnabled() error {
|
||||
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...")
|
||||
enableCmd := exec.Command("sudo", "systemctl", "enable", "greetd")
|
||||
enableCmd.Stdout = os.Stdout
|
||||
@@ -307,9 +308,9 @@ func ensureGreetdEnabled() error {
|
||||
return fmt.Errorf("failed to enable greetd: %w", err)
|
||||
}
|
||||
fmt.Println(" ✓ Enabled greetd service")
|
||||
} else if state.EnabledState == "enabled" || state.EnabledState == "enabled-runtime" {
|
||||
case "enabled", "enabled-runtime":
|
||||
fmt.Println(" ✓ greetd is already enabled")
|
||||
} else {
|
||||
default:
|
||||
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)
|
||||
}
|
||||
}()
|
||||
server.CLIVersion = Version
|
||||
if err := server.Start(false); err != nil {
|
||||
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}
|
||||
}
|
||||
|
||||
// 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
|
||||
func (_m *MockCUPSClientInterface) CancelAllJob(printer string, purge bool) error {
|
||||
ret := _m.Called(printer, purge)
|
||||
@@ -116,6 +209,312 @@ func (_c *MockCUPSClientInterface_CancelJob_Call) RunAndReturn(run func(int, boo
|
||||
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
|
||||
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)
|
||||
@@ -180,6 +579,63 @@ func (_c *MockCUPSClientInterface_GetJobs_Call) RunAndReturn(run func(string, st
|
||||
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
|
||||
func (_m *MockCUPSClientInterface) GetPrinters(attributes []string) (map[string]ipp.Attributes, error) {
|
||||
ret := _m.Called(attributes)
|
||||
@@ -238,6 +694,100 @@ func (_c *MockCUPSClientInterface_GetPrinters_Call) RunAndReturn(run func([]stri
|
||||
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
|
||||
func (_m *MockCUPSClientInterface) PausePrinter(printer string) error {
|
||||
ret := _m.Called(printer)
|
||||
@@ -284,6 +834,156 @@ func (_c *MockCUPSClientInterface_PausePrinter_Call) RunAndReturn(run func(strin
|
||||
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
|
||||
func (_m *MockCUPSClientInterface) ResumePrinter(printer string) error {
|
||||
ret := _m.Called(printer)
|
||||
@@ -390,6 +1090,147 @@ func (_c *MockCUPSClientInterface_SendRequest_Call) RunAndReturn(run func(string
|
||||
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.
|
||||
// The first argument is typically a *testing.T value.
|
||||
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
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/AvengeMedia/DankMaterialShell/core/internal/config"
|
||||
"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) {
|
||||
attributes := []string{
|
||||
ipp.AttributePrinterName,
|
||||
@@ -21,6 +43,9 @@ func (m *Manager) GetPrinters() ([]Printer, error) {
|
||||
|
||||
printerAttrs, err := m.client.GetPrinters(attributes)
|
||||
if err != nil {
|
||||
if isNoPrintersError(err) {
|
||||
return []Printer{}, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -91,17 +116,289 @@ func (m *Manager) GetJobs(printerName string, whichJobs string) ([]Job, 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 {
|
||||
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 {
|
||||
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 {
|
||||
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) {
|
||||
tests := []struct {
|
||||
name string
|
||||
mockErr error
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "success",
|
||||
mockErr: nil,
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "error",
|
||||
mockErr: errors.New("test error"),
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||
mockClient.EXPECT().CancelJob(1, false).Return(nil)
|
||||
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
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)
|
||||
}
|
||||
})
|
||||
}
|
||||
m := NewTestManager(mockClient, nil)
|
||||
assert.NoError(t, m.CancelJob(1))
|
||||
}
|
||||
|
||||
func TestManager_PausePrinter(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
mockErr error
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "success",
|
||||
mockErr: nil,
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "error",
|
||||
mockErr: errors.New("test error"),
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||
mockClient.EXPECT().PausePrinter("printer1").Return(nil)
|
||||
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
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)
|
||||
}
|
||||
})
|
||||
}
|
||||
m := NewTestManager(mockClient, nil)
|
||||
assert.NoError(t, m.PausePrinter("printer1"))
|
||||
}
|
||||
|
||||
func TestManager_ResumePrinter(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
mockErr error
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "success",
|
||||
mockErr: nil,
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "error",
|
||||
mockErr: errors.New("test error"),
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||
mockClient.EXPECT().ResumePrinter("printer1").Return(nil)
|
||||
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
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)
|
||||
}
|
||||
})
|
||||
}
|
||||
m := NewTestManager(mockClient, nil)
|
||||
assert.NoError(t, m.ResumePrinter("printer1"))
|
||||
}
|
||||
|
||||
func TestManager_PurgeJobs(t *testing.T) {
|
||||
@@ -269,11 +185,12 @@ func TestManager_PurgeJobs(t *testing.T) {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||
mockClient.EXPECT().CancelAllJob("printer1", true).Return(tt.mockErr)
|
||||
|
||||
m := &Manager{
|
||||
client: mockClient,
|
||||
if !tt.wantErr {
|
||||
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||
}
|
||||
|
||||
m := NewTestManager(mockClient, nil)
|
||||
|
||||
err := m.PurgeJobs("printer1")
|
||||
if tt.wantErr {
|
||||
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)
|
||||
case "cups.purgeJobs":
|
||||
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:
|
||||
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) {
|
||||
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||
mockClient.EXPECT().PausePrinter("printer1").Return(nil)
|
||||
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||
|
||||
m := &Manager{
|
||||
client: mockClient,
|
||||
}
|
||||
m := NewTestManager(mockClient, nil)
|
||||
|
||||
buf := &bytes.Buffer{}
|
||||
conn := &mockConn{Buffer: buf}
|
||||
@@ -173,10 +172,9 @@ func TestHandlePausePrinter(t *testing.T) {
|
||||
func TestHandleResumePrinter(t *testing.T) {
|
||||
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||
mockClient.EXPECT().ResumePrinter("printer1").Return(nil)
|
||||
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||
|
||||
m := &Manager{
|
||||
client: mockClient,
|
||||
}
|
||||
m := NewTestManager(mockClient, nil)
|
||||
|
||||
buf := &bytes.Buffer{}
|
||||
conn := &mockConn{Buffer: buf}
|
||||
@@ -201,10 +199,9 @@ func TestHandleResumePrinter(t *testing.T) {
|
||||
func TestHandleCancelJob(t *testing.T) {
|
||||
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||
mockClient.EXPECT().CancelJob(1, false).Return(nil)
|
||||
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||
|
||||
m := &Manager{
|
||||
client: mockClient,
|
||||
}
|
||||
m := NewTestManager(mockClient, nil)
|
||||
|
||||
buf := &bytes.Buffer{}
|
||||
conn := &mockConn{Buffer: buf}
|
||||
@@ -229,10 +226,9 @@ func TestHandleCancelJob(t *testing.T) {
|
||||
func TestHandlePurgeJobs(t *testing.T) {
|
||||
mockClient := mocks_cups.NewMockCUPSClientInterface(t)
|
||||
mockClient.EXPECT().CancelAllJob("printer1", true).Return(nil)
|
||||
mockClient.EXPECT().GetPrinters(mock.Anything).Return(map[string]ipp.Attributes{}, nil)
|
||||
|
||||
m := &Manager{
|
||||
client: mockClient,
|
||||
}
|
||||
m := NewTestManager(mockClient, nil)
|
||||
|
||||
buf := &bytes.Buffer{}
|
||||
conn := &mockConn{Buffer: buf}
|
||||
@@ -277,3 +273,439 @@ func TestHandleRequest_UnknownMethod(t *testing.T) {
|
||||
assert.Nil(t, resp.Result)
|
||||
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
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
@@ -31,11 +32,21 @@ func NewManager() (*Manager, error) {
|
||||
client := ipp.NewCUPSClient(host, port, username, password, false)
|
||||
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{
|
||||
state: &CUPSState{
|
||||
Printers: make(map[string]*Printer),
|
||||
},
|
||||
client: client,
|
||||
pkHelper: pkHelper,
|
||||
baseURL: baseURL,
|
||||
stateMutex: sync.RWMutex{},
|
||||
stopChan: make(chan struct{}),
|
||||
@@ -98,6 +109,12 @@ func (m *Manager) eventHandler() {
|
||||
func (m *Manager) updateState() error {
|
||||
printers, err := m.GetPrinters()
|
||||
if err != nil {
|
||||
if isNoPrintersError(err) {
|
||||
m.stateMutex.Lock()
|
||||
m.state.Printers = make(map[string]*Printer)
|
||||
m.stateMutex.Unlock()
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -119,6 +136,19 @@ func (m *Manager) updateState() error {
|
||||
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() {
|
||||
defer m.notifierWg.Done()
|
||||
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 {
|
||||
return m.snapshotState()
|
||||
}
|
||||
@@ -256,6 +294,7 @@ func stateChanged(old, new *CUPSState) bool {
|
||||
}
|
||||
if oldPrinter.State != newPrinter.State ||
|
||||
oldPrinter.StateReason != newPrinter.StateReason ||
|
||||
oldPrinter.Accepting != newPrinter.Accepting ||
|
||||
len(oldPrinter.Jobs) != len(newPrinter.Jobs) {
|
||||
return true
|
||||
}
|
||||
@@ -334,3 +373,18 @@ func getBoolAttr(attrs ipp.Attributes, key string) bool {
|
||||
}
|
||||
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"`
|
||||
}
|
||||
|
||||
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 {
|
||||
state *CUPSState
|
||||
client CUPSClientInterface
|
||||
pkHelper PkHelper
|
||||
subscription SubscriptionManagerInterface
|
||||
stateMutex sync.RWMutex
|
||||
subscribers syncmap.Map[string, chan CUPSState]
|
||||
@@ -63,6 +92,24 @@ type CUPSClientInterface interface {
|
||||
ResumePrinter(printer string) error
|
||||
CancelAllJob(printer string, purge bool) 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 {
|
||||
|
||||
@@ -31,7 +31,9 @@ import (
|
||||
"github.com/AvengeMedia/DankMaterialShell/core/pkg/syncmap"
|
||||
)
|
||||
|
||||
const APIVersion = 21
|
||||
const APIVersion = 22
|
||||
|
||||
var CLIVersion = "dev"
|
||||
|
||||
type Capabilities struct {
|
||||
Capabilities []string `json:"capabilities"`
|
||||
@@ -39,6 +41,7 @@ type Capabilities struct {
|
||||
|
||||
type ServerInfo struct {
|
||||
APIVersion int `json:"apiVersion"`
|
||||
CLIVersion string `json:"cliVersion,omitempty"`
|
||||
Capabilities []string `json:"capabilities"`
|
||||
}
|
||||
|
||||
@@ -431,6 +434,7 @@ func getServerInfo() ServerInfo {
|
||||
|
||||
return ServerInfo{
|
||||
APIVersion: APIVersion,
|
||||
CLIVersion: CLIVersion,
|
||||
Capabilities: caps,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -288,6 +288,7 @@ const (
|
||||
// useful mime types for ipp
|
||||
const (
|
||||
MimeTypePostscript = "application/postscript"
|
||||
MimeTypePDF = "application/pdf"
|
||||
MimeTypeOctetStream = "application/octet-stream"
|
||||
)
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package ipp
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@@ -300,22 +300,13 @@ func (c *CUPSClient) GetClasses(attributes []string) (map[string]Attributes, err
|
||||
return printerNameMap, nil
|
||||
}
|
||||
|
||||
// PrintTestPage prints a test page of type application/vnd.cups-pdf-banner
|
||||
func (c *CUPSClient) PrintTestPage(printer string) (int, error) {
|
||||
testPage := new(bytes.Buffer)
|
||||
testPage.WriteString("#PDF-BANNER\n")
|
||||
testPage.WriteString("Template default-testpage.pdf\n")
|
||||
testPage.WriteString("Show printer-name printer-info printer-location printer-make-and-model printer-driver-name")
|
||||
testPage.WriteString("printer-driver-version paper-size imageable-area job-id options time-at-creation")
|
||||
testPage.WriteString("time-at-processing\n\n")
|
||||
|
||||
return c.PrintDocuments([]Document{
|
||||
{
|
||||
Document: testPage,
|
||||
Name: "Test Page",
|
||||
Size: testPage.Len(),
|
||||
MimeType: MimeTypePostscript,
|
||||
},
|
||||
// PrintTestPage prints a test page using the provided PDF data
|
||||
func (c *CUPSClient) PrintTestPage(printer string, testPageData io.Reader, size int) (int, error) {
|
||||
return c.PrintJob(Document{
|
||||
Document: testPageData,
|
||||
Name: "Test Page",
|
||||
Size: size,
|
||||
MimeType: MimeTypePDF,
|
||||
}, printer, map[string]interface{}{
|
||||
AttributeJobName: "Test Page",
|
||||
})
|
||||
|
||||
@@ -146,13 +146,30 @@ FocusScope {
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: launcherLoader
|
||||
id: printerLoader
|
||||
|
||||
anchors.fill: parent
|
||||
active: root.currentIndex === 7
|
||||
visible: 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 {}
|
||||
|
||||
onActiveChanged: {
|
||||
@@ -166,7 +183,7 @@ FocusScope {
|
||||
id: themeColorsLoader
|
||||
|
||||
anchors.fill: parent
|
||||
active: root.currentIndex === 8
|
||||
active: root.currentIndex === 9
|
||||
visible: active
|
||||
focus: active
|
||||
|
||||
@@ -183,7 +200,7 @@ FocusScope {
|
||||
id: powerLoader
|
||||
|
||||
anchors.fill: parent
|
||||
active: root.currentIndex === 9
|
||||
active: root.currentIndex === 10
|
||||
visible: active
|
||||
focus: active
|
||||
|
||||
@@ -200,7 +217,7 @@ FocusScope {
|
||||
id: pluginsLoader
|
||||
|
||||
anchors.fill: parent
|
||||
active: root.currentIndex === 10
|
||||
active: root.currentIndex === 11
|
||||
visible: active
|
||||
focus: active
|
||||
|
||||
@@ -219,7 +236,7 @@ FocusScope {
|
||||
id: aboutLoader
|
||||
|
||||
anchors.fill: parent
|
||||
active: root.currentIndex === 11
|
||||
active: root.currentIndex === 12
|
||||
visible: active
|
||||
focus: active
|
||||
|
||||
|
||||
@@ -67,6 +67,15 @@ FloatingWindow {
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
active: settingsModal.visible
|
||||
sourceComponent: Component {
|
||||
Ref {
|
||||
service: CupsService
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FileBrowserModal {
|
||||
id: profileBrowser
|
||||
|
||||
@@ -112,7 +121,7 @@ FloatingWindow {
|
||||
focus: true
|
||||
|
||||
Keys.onPressed: event => {
|
||||
const tabCount = 12;
|
||||
const tabCount = 13;
|
||||
if (event.key === Qt.Key_Escape) {
|
||||
hide();
|
||||
event.accepted = true;
|
||||
|
||||
@@ -48,33 +48,45 @@ Rectangle {
|
||||
"dmsOnly": true,
|
||||
"tabIndex": 6
|
||||
},
|
||||
{
|
||||
"text": I18n.tr("Printers"),
|
||||
"icon": "print",
|
||||
"cupsOnly": true,
|
||||
"tabIndex": 7
|
||||
},
|
||||
{
|
||||
"text": I18n.tr("Launcher"),
|
||||
"icon": "apps",
|
||||
"tabIndex": 7
|
||||
"tabIndex": 8
|
||||
},
|
||||
{
|
||||
"text": I18n.tr("Theme & Colors"),
|
||||
"icon": "palette",
|
||||
"tabIndex": 8
|
||||
"tabIndex": 9
|
||||
},
|
||||
{
|
||||
"text": I18n.tr("Power & Security"),
|
||||
"icon": "power",
|
||||
"tabIndex": 9
|
||||
"tabIndex": 10
|
||||
},
|
||||
{
|
||||
"text": I18n.tr("Plugins"),
|
||||
"icon": "extension",
|
||||
"tabIndex": 10
|
||||
"tabIndex": 11
|
||||
},
|
||||
{
|
||||
"text": I18n.tr("About"),
|
||||
"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() {
|
||||
const currentItemIndex = sidebarItems.findIndex(item => item.tabIndex === currentIndex);
|
||||
|
||||
@@ -41,16 +41,10 @@ QtObject {
|
||||
|
||||
onItemChanged: {
|
||||
root.cupsBuiltinInstance = item;
|
||||
if (item && !DMSService.activeSubscriptions.includes("cups") && !DMSService.activeSubscriptions.includes("all")) {
|
||||
DMSService.addSubscription("cups");
|
||||
}
|
||||
}
|
||||
|
||||
onActiveChanged: {
|
||||
if (!active) {
|
||||
if (DMSService.activeSubscriptions.includes("cups")) {
|
||||
DMSService.removeSubscription("cups");
|
||||
}
|
||||
root.cupsBuiltinInstance = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,15 @@ BasePill {
|
||||
property bool showBatteryIcon: SettingsData.controlCenterShowBatteryIcon
|
||||
property bool showPrinterIcon: SettingsData.controlCenterShowPrinterIcon
|
||||
|
||||
Loader {
|
||||
active: root.showPrinterIcon
|
||||
sourceComponent: Component {
|
||||
Ref {
|
||||
service: CupsService
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getNetworkIconName() {
|
||||
if (NetworkService.wifiToggling)
|
||||
return "sync";
|
||||
|
||||
@@ -374,7 +374,7 @@ DankPopout {
|
||||
active: root.currentTabIndex === 2
|
||||
tabBarItem: tabBar
|
||||
keyForwardTarget: mainContainer
|
||||
targetScreen: root.triggerScreen
|
||||
targetScreen: root.screen
|
||||
parentPopout: root
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ import QtCore
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Effects
|
||||
import Quickshell
|
||||
import qs.Common
|
||||
import qs.Modals.FileBrowser
|
||||
import qs.Widgets
|
||||
@@ -244,6 +245,12 @@ Item {
|
||||
setInitialSelection();
|
||||
}
|
||||
}
|
||||
function onPerMonitorWallpaperChanged() {
|
||||
loadWallpaperDirectory();
|
||||
if (visible && active) {
|
||||
setInitialSelection();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onTargetScreenNameChanged: {
|
||||
|
||||
@@ -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
|
||||
StyledRect {
|
||||
width: parent.width
|
||||
|
||||
@@ -288,7 +288,7 @@ Item {
|
||||
return I18n.tr("%1 connected").arg(connected);
|
||||
}
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: NetworkService.ethernetConnected ? Theme.success : Theme.surfaceVariantText
|
||||
color: NetworkService.ethernetConnected ? Theme.primary : Theme.surfaceVariantText
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -758,7 +758,7 @@ Item {
|
||||
return I18n.tr("Not connected");
|
||||
}
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: NetworkService.wifiConnected ? Theme.success : Theme.surfaceVariantText
|
||||
color: NetworkService.wifiConnected ? Theme.primary : Theme.surfaceVariantText
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1430,7 +1430,7 @@ Item {
|
||||
return names[0] + " +" + (names.length - 1);
|
||||
}
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: DMSNetworkService.connected ? Theme.success : Theme.surfaceVariantText
|
||||
color: DMSNetworkService.connected ? Theme.primary : Theme.surfaceVariantText
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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 ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import qs.Common
|
||||
|
||||
Singleton {
|
||||
@@ -12,20 +10,179 @@ Singleton {
|
||||
|
||||
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 printers: []
|
||||
property string selectedPrinter: ""
|
||||
property string expandedPrinter: ""
|
||||
|
||||
property bool cupsAvailable: 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
|
||||
|
||||
readonly property string socketPath: Quickshell.env("DMS_SOCKET")
|
||||
|
||||
Component.onCompleted: {
|
||||
if (socketPath && socketPath.length > 0) {
|
||||
checkDMSCapabilities()
|
||||
checkDMSCapabilities();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +191,8 @@ Singleton {
|
||||
|
||||
function onConnectionStateChanged() {
|
||||
if (DMSService.isConnected) {
|
||||
checkDMSCapabilities()
|
||||
checkDMSCapabilities();
|
||||
ensureSubscription();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -44,328 +202,641 @@ Singleton {
|
||||
enabled: DMSService.isConnected
|
||||
|
||||
function onCupsStateUpdate(data) {
|
||||
console.log("CupsService: Subscription update received")
|
||||
getState()
|
||||
console.log("CupsService: Subscription update received");
|
||||
getState();
|
||||
}
|
||||
|
||||
function onCapabilitiesChanged() {
|
||||
checkDMSCapabilities()
|
||||
checkDMSCapabilities();
|
||||
}
|
||||
}
|
||||
|
||||
function checkDMSCapabilities() {
|
||||
if (!DMSService.isConnected) {
|
||||
return
|
||||
}
|
||||
|
||||
if (DMSService.capabilities.length === 0) {
|
||||
return
|
||||
}
|
||||
|
||||
cupsAvailable = DMSService.capabilities.includes("cups")
|
||||
if (!DMSService.isConnected)
|
||||
return;
|
||||
if (DMSService.capabilities.length === 0)
|
||||
return;
|
||||
cupsAvailable = DMSService.capabilities.includes("cups");
|
||||
|
||||
if (cupsAvailable && !stateInitialized) {
|
||||
stateInitialized = true
|
||||
getState()
|
||||
stateInitialized = true;
|
||||
getState();
|
||||
}
|
||||
}
|
||||
|
||||
function getState() {
|
||||
if (!cupsAvailable)
|
||||
return
|
||||
|
||||
return;
|
||||
DMSService.sendRequest("cups.getPrinters", null, response => {
|
||||
if (response.result) {
|
||||
updatePrinters(response.result)
|
||||
fetchAllJobs()
|
||||
}
|
||||
})
|
||||
if (response.result) {
|
||||
updatePrinters(response.result);
|
||||
fetchAllJobs();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
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++) {
|
||||
let printer = printersData[i]
|
||||
let printer = printersData[i];
|
||||
printersObj[printer.name] = {
|
||||
"name": printer.name,
|
||||
"uri": printer.uri || "",
|
||||
"state": printer.state,
|
||||
"stateReason": printer.stateReason,
|
||||
"location": printer.location || "",
|
||||
"info": printer.info || "",
|
||||
"makeModel": printer.makeModel || "",
|
||||
"accepting": printer.accepting !== false,
|
||||
"jobs": []
|
||||
}
|
||||
};
|
||||
}
|
||||
printers = printersObj
|
||||
printers = printersObj;
|
||||
|
||||
if (printerNames.length > 0) {
|
||||
if (selectedPrinter.length > 0) {
|
||||
if (!printerNames.includes(selectedPrinter)) {
|
||||
selectedPrinter = printerNames[0]
|
||||
selectedPrinter = printerNames[0];
|
||||
}
|
||||
} else {
|
||||
selectedPrinter = printerNames[0]
|
||||
selectedPrinter = printerNames[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function fetchAllJobs() {
|
||||
for (var i = 0; i < printerNames.length; i++) {
|
||||
fetchJobsForPrinter(printerNames[i])
|
||||
fetchJobsForPrinter(printerNames[i]);
|
||||
}
|
||||
}
|
||||
|
||||
function fetchJobsForPrinter(printerName) {
|
||||
const params = {
|
||||
"printerName": printerName
|
||||
}
|
||||
};
|
||||
|
||||
DMSService.sendRequest("cups.getJobs", params, response => {
|
||||
if (response.result && printers[printerName]) {
|
||||
let updatedPrinters = Object.assign({}, printers)
|
||||
updatedPrinters[printerName].jobs = response.result
|
||||
printers = updatedPrinters
|
||||
}
|
||||
})
|
||||
if (response.result && printers[printerName]) {
|
||||
let updatedPrinters = Object.assign({}, printers);
|
||||
updatedPrinters[printerName].jobs = response.result;
|
||||
printers = updatedPrinters;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getSelectedPrinter() {
|
||||
return selectedPrinter
|
||||
return selectedPrinter;
|
||||
}
|
||||
|
||||
function setSelectedPrinter(printerName) {
|
||||
if (printerNames.length > 0) {
|
||||
if (printerNames.includes(printerName)) {
|
||||
selectedPrinter = printerName
|
||||
selectedPrinter = printerName;
|
||||
} else {
|
||||
selectedPrinter = printerNames[0]
|
||||
selectedPrinter = printerNames[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getPrintersNum() {
|
||||
if (!cupsAvailable)
|
||||
return 0
|
||||
return 0;
|
||||
|
||||
return printerNames.length
|
||||
return printerNames.length;
|
||||
}
|
||||
|
||||
function getPrintersNames() {
|
||||
if (!cupsAvailable)
|
||||
return []
|
||||
return [];
|
||||
|
||||
return printerNames
|
||||
return printerNames;
|
||||
}
|
||||
|
||||
function getTotalJobsNum() {
|
||||
if (!cupsAvailable)
|
||||
return 0
|
||||
return 0;
|
||||
|
||||
var result = 0
|
||||
var result = 0;
|
||||
for (var i = 0; i < printerNames.length; i++) {
|
||||
var printerName = printerNames[i]
|
||||
var printerName = printerNames[i];
|
||||
if (printers[printerName] && printers[printerName].jobs) {
|
||||
result += printers[printerName].jobs.length
|
||||
result += printers[printerName].jobs.length;
|
||||
}
|
||||
}
|
||||
return result
|
||||
return result;
|
||||
}
|
||||
|
||||
function getCurrentPrinterState() {
|
||||
if (!cupsAvailable || !selectedPrinter)
|
||||
return ""
|
||||
return "";
|
||||
|
||||
var printer = printers[selectedPrinter]
|
||||
return printer.state
|
||||
var printer = printers[selectedPrinter];
|
||||
return printer.state;
|
||||
}
|
||||
|
||||
function getCurrentPrinterStatePrettyShort() {
|
||||
if (!cupsAvailable || !selectedPrinter)
|
||||
return ""
|
||||
return "";
|
||||
|
||||
var printer = printers[selectedPrinter]
|
||||
return getPrinterStateTranslation(printer.state) + " (" + getPrinterStateReasonTranslation(printer.stateReason) + ")"
|
||||
var printer = printers[selectedPrinter];
|
||||
return getPrinterStateTranslation(printer.state) + " (" + getPrinterStateReasonTranslation(printer.stateReason) + ")";
|
||||
}
|
||||
|
||||
function getCurrentPrinterStatePretty() {
|
||||
if (!cupsAvailable || !selectedPrinter)
|
||||
return ""
|
||||
return "";
|
||||
|
||||
var printer = printers[selectedPrinter]
|
||||
return getPrinterStateTranslation(printer.state) + " (" + I18n.tr("Reason") + ": " + getPrinterStateReasonTranslation(printer.stateReason) + ")"
|
||||
var printer = printers[selectedPrinter];
|
||||
return getPrinterStateTranslation(printer.state) + " (" + I18n.tr("Reason") + ": " + getPrinterStateReasonTranslation(printer.stateReason) + ")";
|
||||
}
|
||||
|
||||
function getCurrentPrinterJobs() {
|
||||
if (!cupsAvailable || !selectedPrinter)
|
||||
return []
|
||||
return [];
|
||||
|
||||
return getJobs(selectedPrinter)
|
||||
return getJobs(selectedPrinter);
|
||||
}
|
||||
|
||||
function getJobs(printerName) {
|
||||
if (!cupsAvailable)
|
||||
return ""
|
||||
return "";
|
||||
|
||||
var printer = printers[printerName]
|
||||
return printer.jobs
|
||||
var printer = printers[printerName];
|
||||
return printer.jobs;
|
||||
}
|
||||
|
||||
function getJobsNum(printerName) {
|
||||
if (!cupsAvailable)
|
||||
return 0
|
||||
return 0;
|
||||
|
||||
var printer = printers[printerName]
|
||||
return printer.jobs.length
|
||||
var printer = printers[printerName];
|
||||
return printer.jobs.length;
|
||||
}
|
||||
|
||||
function pausePrinter(printerName) {
|
||||
if (!cupsAvailable)
|
||||
return
|
||||
|
||||
return;
|
||||
const params = {
|
||||
"printerName": printerName
|
||||
}
|
||||
};
|
||||
|
||||
DMSService.sendRequest("cups.pausePrinter", params, response => {
|
||||
if (response.error) {
|
||||
ToastService.showError(I18n.tr("Failed to pause printer") + " - " + response.error)
|
||||
} else {
|
||||
getState()
|
||||
}
|
||||
})
|
||||
if (response.error) {
|
||||
ToastService.showError(I18n.tr("Failed to pause printer") + " - " + response.error);
|
||||
} else {
|
||||
getState();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function resumePrinter(printerName) {
|
||||
if (!cupsAvailable)
|
||||
return
|
||||
|
||||
return;
|
||||
const params = {
|
||||
"printerName": printerName
|
||||
}
|
||||
};
|
||||
|
||||
DMSService.sendRequest("cups.resumePrinter", params, response => {
|
||||
if (response.error) {
|
||||
ToastService.showError(I18n.tr("Failed to resume printer") + " - " + response.error)
|
||||
} else {
|
||||
getState()
|
||||
}
|
||||
})
|
||||
if (response.error) {
|
||||
ToastService.showError(I18n.tr("Failed to resume printer") + " - " + response.error);
|
||||
} else {
|
||||
getState();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function cancelJob(printerName, jobID) {
|
||||
if (!cupsAvailable)
|
||||
return
|
||||
|
||||
return;
|
||||
const params = {
|
||||
"printerName": printerName,
|
||||
"jobID": jobID
|
||||
}
|
||||
};
|
||||
|
||||
DMSService.sendRequest("cups.cancelJob", params, response => {
|
||||
if (response.error) {
|
||||
ToastService.showError(I18n.tr("Failed to cancel selected job") + " - " + response.error)
|
||||
} else {
|
||||
fetchJobsForPrinter(printerName)
|
||||
}
|
||||
})
|
||||
if (response.error) {
|
||||
ToastService.showError(I18n.tr("Failed to cancel selected job") + " - " + response.error);
|
||||
} else {
|
||||
fetchJobsForPrinter(printerName);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function purgeJobs(printerName) {
|
||||
if (!cupsAvailable)
|
||||
return
|
||||
|
||||
return;
|
||||
const params = {
|
||||
"printerName": printerName
|
||||
}
|
||||
};
|
||||
|
||||
DMSService.sendRequest("cups.purgeJobs", params, response => {
|
||||
if (response.error) {
|
||||
ToastService.showError(I18n.tr("Failed to cancel all jobs") + " - " + response.error)
|
||||
} else {
|
||||
fetchJobsForPrinter(printerName)
|
||||
}
|
||||
})
|
||||
if (response.error) {
|
||||
ToastService.showError(I18n.tr("Failed to cancel all jobs") + " - " + response.error);
|
||||
} else {
|
||||
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: ({
|
||||
"idle": I18n.tr("Idle"),
|
||||
"processing": I18n.tr("Processing"),
|
||||
"stopped": I18n.tr("Stopped")
|
||||
})
|
||||
"idle": I18n.tr("Idle"),
|
||||
"processing": I18n.tr("Processing"),
|
||||
"stopped": I18n.tr("Stopped")
|
||||
})
|
||||
|
||||
readonly property var reasonsGeneral: ({
|
||||
"none": I18n.tr("None"),
|
||||
"other": I18n.tr("Other")
|
||||
})
|
||||
"none": I18n.tr("None"),
|
||||
"other": I18n.tr("Other")
|
||||
})
|
||||
|
||||
readonly property var reasonsSupplies: ({
|
||||
"toner-low": I18n.tr("Toner Low"),
|
||||
"toner-empty": I18n.tr("Toner Empty"),
|
||||
"marker-supply-low": I18n.tr("Marker Supply Low"),
|
||||
"marker-supply-empty": I18n.tr("Marker Supply Empty"),
|
||||
"marker-waste-almost-full": I18n.tr("Marker Waste Almost Full"),
|
||||
"marker-waste-full": I18n.tr("Marker Waste Full")
|
||||
})
|
||||
"toner-low": I18n.tr("Toner Low"),
|
||||
"toner-empty": I18n.tr("Toner Empty"),
|
||||
"marker-supply-low": I18n.tr("Marker Supply Low"),
|
||||
"marker-supply-empty": I18n.tr("Marker Supply Empty"),
|
||||
"marker-waste-almost-full": I18n.tr("Marker Waste Almost Full"),
|
||||
"marker-waste-full": I18n.tr("Marker Waste Full")
|
||||
})
|
||||
|
||||
readonly property var reasonsMedia: ({
|
||||
"media-low": I18n.tr("Media Low"),
|
||||
"media-empty": I18n.tr("Media Empty"),
|
||||
"media-needed": I18n.tr("Media Needed"),
|
||||
"media-jam": I18n.tr("Media Jam")
|
||||
})
|
||||
"media-low": I18n.tr("Media Low"),
|
||||
"media-empty": I18n.tr("Media Empty"),
|
||||
"media-needed": I18n.tr("Media Needed"),
|
||||
"media-jam": I18n.tr("Media Jam")
|
||||
})
|
||||
|
||||
readonly property var reasonsParts: ({
|
||||
"cover-open": I18n.tr("Cover Open"),
|
||||
"door-open": I18n.tr("Door Open"),
|
||||
"interlock-open": I18n.tr("Interlock Open"),
|
||||
"output-tray-missing": I18n.tr("Output Tray Missing"),
|
||||
"output-area-almost-full": I18n.tr("Output Area Almost Full"),
|
||||
"output-area-full": I18n.tr("Output Area Full")
|
||||
})
|
||||
"cover-open": I18n.tr("Cover Open"),
|
||||
"door-open": I18n.tr("Door Open"),
|
||||
"interlock-open": I18n.tr("Interlock Open"),
|
||||
"output-tray-missing": I18n.tr("Output Tray Missing"),
|
||||
"output-area-almost-full": I18n.tr("Output Area Almost Full"),
|
||||
"output-area-full": I18n.tr("Output Area Full")
|
||||
})
|
||||
|
||||
readonly property var reasonsErrors: ({
|
||||
"paused": I18n.tr("Paused"),
|
||||
"shutdown": I18n.tr("Shutdown"),
|
||||
"connecting-to-device": I18n.tr("Connecting to Device"),
|
||||
"timed-out": I18n.tr("Timed Out"),
|
||||
"stopping": I18n.tr("Stopping"),
|
||||
"stopped-partly": I18n.tr("Stopped Partly")
|
||||
})
|
||||
"paused": I18n.tr("Paused"),
|
||||
"shutdown": I18n.tr("Shutdown"),
|
||||
"connecting-to-device": I18n.tr("Connecting to Device"),
|
||||
"timed-out": I18n.tr("Timed Out"),
|
||||
"stopping": I18n.tr("Stopping"),
|
||||
"stopped-partly": I18n.tr("Stopped Partly")
|
||||
})
|
||||
|
||||
readonly property var reasonsService: ({
|
||||
"spool-area-full": I18n.tr("Spool Area Full"),
|
||||
"cups-missing-filter-warning": I18n.tr("CUPS Missing Filter Warning"),
|
||||
"cups-insecure-filter-warning": I18n.tr("CUPS Insecure Filter Warning")
|
||||
})
|
||||
"spool-area-full": I18n.tr("Spool Area Full"),
|
||||
"cups-missing-filter-warning": I18n.tr("CUPS Missing Filter Warning"),
|
||||
"cups-insecure-filter-warning": I18n.tr("CUPS Insecure Filter Warning")
|
||||
})
|
||||
|
||||
readonly property var reasonsConnectivity: ({
|
||||
"offline-report": I18n.tr("Offline Report"),
|
||||
"moving-to-paused": I18n.tr("Moving to Paused")
|
||||
})
|
||||
"offline-report": I18n.tr("Offline Report"),
|
||||
"moving-to-paused": I18n.tr("Moving to Paused")
|
||||
})
|
||||
|
||||
readonly property var severitySuffixes: ({
|
||||
"-error": I18n.tr("Error"),
|
||||
"-warning": I18n.tr("Warning"),
|
||||
"-report": I18n.tr("Report")
|
||||
})
|
||||
"-error": I18n.tr("Error"),
|
||||
"-warning": I18n.tr("Warning"),
|
||||
"-report": I18n.tr("Report")
|
||||
})
|
||||
|
||||
function getPrinterStateTranslation(state) {
|
||||
return states[state] || state
|
||||
return states[state] || state;
|
||||
}
|
||||
|
||||
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 suffix = ""
|
||||
let basReason = reason;
|
||||
let suffix = "";
|
||||
|
||||
for (let s in severitySuffixes) {
|
||||
if (reason.endsWith(s)) {
|
||||
basReason = reason.slice(0, -s.length)
|
||||
suffix = severitySuffixes[s]
|
||||
break
|
||||
basReason = reason.slice(0, -s.length);
|
||||
suffix = severitySuffixes[s];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
let translation = allReasons[basReason] || basReason
|
||||
return suffix ? translation + " (" + suffix + ")" : translation
|
||||
let translation = allReasons[basReason] || basReason;
|
||||
return suffix ? translation + " (" + suffix + ")" : translation;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
pragma Singleton
|
||||
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtCore
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
@@ -14,6 +12,7 @@ Singleton {
|
||||
property bool dmsAvailable: false
|
||||
property var capabilities: []
|
||||
property int apiVersion: 0
|
||||
property string cliVersion: ""
|
||||
readonly property int expectedApiVersion: 1
|
||||
property var availablePlugins: []
|
||||
property var installedPlugins: []
|
||||
@@ -57,18 +56,18 @@ Singleton {
|
||||
|
||||
Component.onCompleted: {
|
||||
if (socketPath && socketPath.length > 0) {
|
||||
detectUpdateCommand()
|
||||
detectUpdateCommand();
|
||||
}
|
||||
}
|
||||
|
||||
function detectUpdateCommand() {
|
||||
checkingUpdateCommand = true
|
||||
checkAurHelper.running = true
|
||||
checkingUpdateCommand = true;
|
||||
checkAurHelper.running = true;
|
||||
}
|
||||
|
||||
function startSocketConnection() {
|
||||
if (socketPath && socketPath.length > 0) {
|
||||
testProcess.running = true
|
||||
testProcess.running = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,26 +78,26 @@ Singleton {
|
||||
|
||||
stdout: StdioCollector {
|
||||
onStreamFinished: {
|
||||
const helper = text.trim()
|
||||
const helper = text.trim();
|
||||
if (helper.includes("paru")) {
|
||||
checkDmsPackage.helper = "paru"
|
||||
checkDmsPackage.running = true
|
||||
checkDmsPackage.helper = "paru";
|
||||
checkDmsPackage.running = true;
|
||||
} else if (helper.includes("yay")) {
|
||||
checkDmsPackage.helper = "yay"
|
||||
checkDmsPackage.running = true
|
||||
checkDmsPackage.helper = "yay";
|
||||
checkDmsPackage.running = true;
|
||||
} else {
|
||||
updateCommand = "dms update"
|
||||
checkingUpdateCommand = false
|
||||
startSocketConnection()
|
||||
updateCommand = "dms update";
|
||||
checkingUpdateCommand = false;
|
||||
startSocketConnection();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onExited: exitCode => {
|
||||
if (exitCode !== 0) {
|
||||
updateCommand = "dms update"
|
||||
checkingUpdateCommand = false
|
||||
startSocketConnection()
|
||||
updateCommand = "dms update";
|
||||
checkingUpdateCommand = false;
|
||||
startSocketConnection();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -112,22 +111,22 @@ Singleton {
|
||||
stdout: StdioCollector {
|
||||
onStreamFinished: {
|
||||
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")) {
|
||||
updateCommand = checkDmsPackage.helper + " -S dms-shell-bin"
|
||||
updateCommand = checkDmsPackage.helper + " -S dms-shell-bin";
|
||||
} else {
|
||||
updateCommand = "dms update"
|
||||
updateCommand = "dms update";
|
||||
}
|
||||
checkingUpdateCommand = false
|
||||
startSocketConnection()
|
||||
checkingUpdateCommand = false;
|
||||
startSocketConnection();
|
||||
}
|
||||
}
|
||||
|
||||
onExited: exitCode => {
|
||||
if (exitCode !== 0) {
|
||||
updateCommand = "dms update"
|
||||
checkingUpdateCommand = false
|
||||
startSocketConnection()
|
||||
updateCommand = "dms update";
|
||||
checkingUpdateCommand = false;
|
||||
startSocketConnection();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -138,21 +137,21 @@ Singleton {
|
||||
|
||||
onExited: exitCode => {
|
||||
if (exitCode === 0) {
|
||||
root.dmsAvailable = true
|
||||
connectSocket()
|
||||
root.dmsAvailable = true;
|
||||
connectSocket();
|
||||
} else {
|
||||
root.dmsAvailable = false
|
||||
root.dmsAvailable = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function connectSocket() {
|
||||
if (!dmsAvailable || isConnected || isConnecting) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
|
||||
isConnecting = true
|
||||
requestSocket.connected = true
|
||||
isConnecting = true;
|
||||
requestSocket.connected = true;
|
||||
}
|
||||
|
||||
DankSocket {
|
||||
@@ -162,32 +161,32 @@ Singleton {
|
||||
|
||||
onConnectionStateChanged: {
|
||||
if (connected) {
|
||||
root.isConnected = true
|
||||
root.isConnecting = false
|
||||
root.connectionStateChanged()
|
||||
subscribeSocket.connected = true
|
||||
root.isConnected = true;
|
||||
root.isConnecting = false;
|
||||
root.connectionStateChanged();
|
||||
subscribeSocket.connected = true;
|
||||
} else {
|
||||
root.isConnected = false
|
||||
root.isConnecting = false
|
||||
root.apiVersion = 0
|
||||
root.capabilities = []
|
||||
root.connectionStateChanged()
|
||||
root.isConnected = false;
|
||||
root.isConnecting = false;
|
||||
root.apiVersion = 0;
|
||||
root.capabilities = [];
|
||||
root.connectionStateChanged();
|
||||
}
|
||||
}
|
||||
|
||||
parser: SplitParser {
|
||||
onRead: line => {
|
||||
if (!line || line.length === 0) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("DMSService: Request socket <<", line)
|
||||
console.log("DMSService: Request socket <<", line);
|
||||
|
||||
try {
|
||||
const response = JSON.parse(line)
|
||||
handleResponse(response)
|
||||
const response = JSON.parse(line);
|
||||
handleResponse(response);
|
||||
} 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
|
||||
|
||||
onConnectionStateChanged: {
|
||||
root.subscribeConnected = connected
|
||||
root.subscribeConnected = connected;
|
||||
if (connected) {
|
||||
sendSubscribeRequest()
|
||||
sendSubscribeRequest();
|
||||
}
|
||||
}
|
||||
|
||||
parser: SplitParser {
|
||||
onRead: line => {
|
||||
if (!line || line.length === 0) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("DMSService: Subscribe socket <<", line)
|
||||
console.log("DMSService: Subscribe socket <<", line);
|
||||
|
||||
try {
|
||||
const response = JSON.parse(line)
|
||||
handleSubscriptionEvent(response)
|
||||
const response = JSON.parse(line);
|
||||
handleSubscriptionEvent(response);
|
||||
} 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() {
|
||||
const request = {
|
||||
"method": "subscribe"
|
||||
}
|
||||
};
|
||||
|
||||
if (activeSubscriptions.length > 0) {
|
||||
request.params = {
|
||||
"services": activeSubscriptions
|
||||
}
|
||||
console.log("DMSService: Subscribing to services:", JSON.stringify(activeSubscriptions))
|
||||
};
|
||||
console.log("DMSService: Subscribing to services:", JSON.stringify(activeSubscriptions));
|
||||
} else {
|
||||
console.log("DMSService: Subscribing to all services")
|
||||
console.log("DMSService: Subscribing to all services");
|
||||
}
|
||||
|
||||
subscribeSocket.send(request)
|
||||
subscribeSocket.send(request);
|
||||
}
|
||||
|
||||
function subscribe(services) {
|
||||
if (!Array.isArray(services)) {
|
||||
services = [services]
|
||||
services = [services];
|
||||
}
|
||||
|
||||
activeSubscriptions = services
|
||||
activeSubscriptions = services;
|
||||
|
||||
if (subscribeConnected) {
|
||||
subscribeSocket.connected = false
|
||||
subscribeSocket.connected = false;
|
||||
Qt.callLater(() => {
|
||||
subscribeSocket.connected = true
|
||||
})
|
||||
subscribeSocket.connected = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function addSubscription(service) {
|
||||
if (activeSubscriptions.includes("all")) {
|
||||
console.warn("DMSService: Cannot add specific subscription when subscribed to 'all'")
|
||||
return
|
||||
}
|
||||
|
||||
if (activeSubscriptions.includes("all"))
|
||||
return;
|
||||
if (!activeSubscriptions.includes(service)) {
|
||||
const newSubs = [...activeSubscriptions, service]
|
||||
subscribe(newSubs)
|
||||
const newSubs = [...activeSubscriptions, service];
|
||||
subscribe(newSubs);
|
||||
}
|
||||
}
|
||||
|
||||
function removeSubscription(service) {
|
||||
if (activeSubscriptions.includes("all")) {
|
||||
const allServices = ["network", "loginctl", "freedesktop", "gamma", "bluetooth", "dwl", "brightness", "extworkspace"]
|
||||
const filtered = allServices.filter(s => s !== service)
|
||||
subscribe(filtered)
|
||||
const allServices = ["network", "loginctl", "freedesktop", "gamma", "bluetooth", "dwl", "brightness", "extworkspace"];
|
||||
const filtered = allServices.filter(s => s !== service);
|
||||
subscribe(filtered);
|
||||
} else {
|
||||
const filtered = activeSubscriptions.filter(s => s !== service)
|
||||
const filtered = activeSubscriptions.filter(s => s !== service);
|
||||
if (filtered.length === 0) {
|
||||
console.warn("DMSService: Cannot remove last subscription")
|
||||
return
|
||||
console.warn("DMSService: Cannot remove last subscription");
|
||||
return;
|
||||
}
|
||||
subscribe(filtered)
|
||||
subscribe(filtered);
|
||||
}
|
||||
}
|
||||
|
||||
function subscribeAll() {
|
||||
subscribe(["all"])
|
||||
subscribe(["all"]);
|
||||
}
|
||||
|
||||
function subscribeAllExcept(excludeServices) {
|
||||
if (!Array.isArray(excludeServices)) {
|
||||
excludeServices = [excludeServices]
|
||||
excludeServices = [excludeServices];
|
||||
}
|
||||
|
||||
const allServices = ["network", "loginctl", "freedesktop", "gamma", "bluetooth", "cups", "dwl", "brightness", "extworkspace"]
|
||||
const filtered = allServices.filter(s => !excludeServices.includes(s))
|
||||
subscribe(filtered)
|
||||
const allServices = ["network", "loginctl", "freedesktop", "gamma", "bluetooth", "cups", "dwl", "brightness", "extworkspace"];
|
||||
const filtered = allServices.filter(s => !excludeServices.includes(s));
|
||||
subscribe(filtered);
|
||||
}
|
||||
|
||||
function handleSubscriptionEvent(response) {
|
||||
if (response.error) {
|
||||
if (response.error.includes("unknown method") && response.error.includes("subscribe")) {
|
||||
if (!shownOutdatedError) {
|
||||
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)
|
||||
shownOutdatedError = true
|
||||
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);
|
||||
shownOutdatedError = true;
|
||||
}
|
||||
}
|
||||
return
|
||||
return;
|
||||
}
|
||||
|
||||
if (!response.result) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
|
||||
const service = response.result.service
|
||||
const data = response.result.data
|
||||
const service = response.result.service;
|
||||
const data = response.result.data;
|
||||
|
||||
if (service === "server") {
|
||||
apiVersion = data.apiVersion || 0
|
||||
capabilities = data.capabilities || []
|
||||
apiVersion = data.apiVersion || 0;
|
||||
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) {
|
||||
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") {
|
||||
networkStateUpdate(data)
|
||||
networkStateUpdate(data);
|
||||
} else if (service === "network.credentials") {
|
||||
credentialsRequest(data)
|
||||
credentialsRequest(data);
|
||||
} else if (service === "loginctl") {
|
||||
if (data.event) {
|
||||
loginctlEvent(data)
|
||||
loginctlEvent(data);
|
||||
} else {
|
||||
loginctlStateUpdate(data)
|
||||
loginctlStateUpdate(data);
|
||||
}
|
||||
} else if (service === "bluetooth.pairing") {
|
||||
bluetoothPairingRequest(data)
|
||||
bluetoothPairingRequest(data);
|
||||
} else if (service === "cups") {
|
||||
cupsStateUpdate(data)
|
||||
cupsStateUpdate(data);
|
||||
} else if (service === "dwl") {
|
||||
dwlStateUpdate(data)
|
||||
dwlStateUpdate(data);
|
||||
} else if (service === "brightness") {
|
||||
brightnessStateUpdate(data)
|
||||
brightnessStateUpdate(data);
|
||||
} else if (service === "brightness.update") {
|
||||
if (data.device) {
|
||||
brightnessDeviceUpdate(data.device)
|
||||
brightnessDeviceUpdate(data.device);
|
||||
}
|
||||
} else if (service === "extworkspace") {
|
||||
extWorkspaceStateUpdate(data)
|
||||
extWorkspaceStateUpdate(data);
|
||||
} else if (service === "wlroutput") {
|
||||
wlrOutputStateUpdate(data)
|
||||
wlrOutputStateUpdate(data);
|
||||
} else if (service === "evdev") {
|
||||
if (data.capsLock !== undefined) {
|
||||
capsLockState = data.capsLock
|
||||
capsLockState = data.capsLock;
|
||||
}
|
||||
evdevStateUpdate(data)
|
||||
evdevStateUpdate(data);
|
||||
}
|
||||
}
|
||||
|
||||
function sendRequest(method, params, callback) {
|
||||
if (!isConnected) {
|
||||
console.warn("DMSService.sendRequest: Not connected, method:", method)
|
||||
console.warn("DMSService.sendRequest: Not connected, method:", method);
|
||||
if (callback) {
|
||||
callback({
|
||||
"error": "not connected to DMS socket"
|
||||
})
|
||||
"error": "not connected to DMS socket"
|
||||
});
|
||||
}
|
||||
return
|
||||
return;
|
||||
}
|
||||
|
||||
requestIdCounter++
|
||||
const id = Date.now() + requestIdCounter
|
||||
requestIdCounter++;
|
||||
const id = Date.now() + requestIdCounter;
|
||||
const request = {
|
||||
"id": id,
|
||||
"method": method
|
||||
}
|
||||
};
|
||||
|
||||
if (params) {
|
||||
request.params = params
|
||||
request.params = params;
|
||||
}
|
||||
|
||||
if (callback) {
|
||||
pendingRequests[id] = callback
|
||||
pendingRequests[id] = callback;
|
||||
}
|
||||
|
||||
console.log("DMSService.sendRequest: Sending request id=" + id + " method=" + method)
|
||||
requestSocket.send(request)
|
||||
console.log("DMSService.sendRequest: Sending request id=" + id + " method=" + method);
|
||||
requestSocket.send(request);
|
||||
}
|
||||
|
||||
function handleResponse(response) {
|
||||
const callback = pendingRequests[response.id]
|
||||
const callback = pendingRequests[response.id];
|
||||
|
||||
if (callback) {
|
||||
delete pendingRequests[response.id]
|
||||
callback(response)
|
||||
delete pendingRequests[response.id];
|
||||
callback(response);
|
||||
}
|
||||
}
|
||||
|
||||
function ping(callback) {
|
||||
sendRequest("ping", null, callback)
|
||||
sendRequest("ping", null, callback);
|
||||
}
|
||||
|
||||
function listPlugins(callback) {
|
||||
sendRequest("plugins.list", null, response => {
|
||||
if (response.result) {
|
||||
availablePlugins = response.result
|
||||
pluginsListReceived(response.result)
|
||||
}
|
||||
if (callback) {
|
||||
callback(response)
|
||||
}
|
||||
})
|
||||
if (response.result) {
|
||||
availablePlugins = response.result;
|
||||
pluginsListReceived(response.result);
|
||||
}
|
||||
if (callback) {
|
||||
callback(response);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function listInstalled(callback) {
|
||||
sendRequest("plugins.listInstalled", null, response => {
|
||||
if (response.result) {
|
||||
installedPlugins = response.result
|
||||
installedPluginsReceived(response.result)
|
||||
}
|
||||
if (callback) {
|
||||
callback(response)
|
||||
}
|
||||
})
|
||||
if (response.result) {
|
||||
installedPlugins = response.result;
|
||||
installedPluginsReceived(response.result);
|
||||
}
|
||||
if (callback) {
|
||||
callback(response);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function search(query, category, compositor, capability, callback) {
|
||||
const params = {
|
||||
"query": query
|
||||
}
|
||||
};
|
||||
if (category) {
|
||||
params.category = category
|
||||
params.category = category;
|
||||
}
|
||||
if (compositor) {
|
||||
params.compositor = compositor
|
||||
params.compositor = compositor;
|
||||
}
|
||||
if (capability) {
|
||||
params.capability = capability
|
||||
params.capability = capability;
|
||||
}
|
||||
|
||||
sendRequest("plugins.search", params, response => {
|
||||
if (response.result) {
|
||||
searchResultsReceived(response.result)
|
||||
}
|
||||
if (callback) {
|
||||
callback(response)
|
||||
}
|
||||
})
|
||||
if (response.result) {
|
||||
searchResultsReceived(response.result);
|
||||
}
|
||||
if (callback) {
|
||||
callback(response);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function install(pluginName, callback) {
|
||||
sendRequest("plugins.install", {
|
||||
"name": pluginName
|
||||
}, response => {
|
||||
if (callback) {
|
||||
callback(response)
|
||||
}
|
||||
if (!response.error) {
|
||||
listInstalled()
|
||||
}
|
||||
})
|
||||
"name": pluginName
|
||||
}, response => {
|
||||
if (callback) {
|
||||
callback(response);
|
||||
}
|
||||
if (!response.error) {
|
||||
listInstalled();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function uninstall(pluginName, callback) {
|
||||
sendRequest("plugins.uninstall", {
|
||||
"name": pluginName
|
||||
}, response => {
|
||||
if (callback) {
|
||||
callback(response)
|
||||
}
|
||||
if (!response.error) {
|
||||
listInstalled()
|
||||
}
|
||||
})
|
||||
"name": pluginName
|
||||
}, response => {
|
||||
if (callback) {
|
||||
callback(response);
|
||||
}
|
||||
if (!response.error) {
|
||||
listInstalled();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function update(pluginName, callback) {
|
||||
sendRequest("plugins.update", {
|
||||
"name": pluginName
|
||||
}, response => {
|
||||
if (callback) {
|
||||
callback(response)
|
||||
}
|
||||
if (!response.error) {
|
||||
listInstalled()
|
||||
}
|
||||
})
|
||||
"name": pluginName
|
||||
}, response => {
|
||||
if (callback) {
|
||||
callback(response);
|
||||
}
|
||||
if (!response.error) {
|
||||
listInstalled();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function lockSession(callback) {
|
||||
sendRequest("loginctl.lock", null, callback)
|
||||
sendRequest("loginctl.lock", null, callback);
|
||||
}
|
||||
|
||||
function unlockSession(callback) {
|
||||
sendRequest("loginctl.unlock", null, callback)
|
||||
sendRequest("loginctl.unlock", null, callback);
|
||||
}
|
||||
|
||||
function bluetoothPair(devicePath, callback) {
|
||||
sendRequest("bluetooth.pair", {
|
||||
"device": devicePath
|
||||
}, callback)
|
||||
"device": devicePath
|
||||
}, callback);
|
||||
}
|
||||
|
||||
function bluetoothConnect(devicePath, callback) {
|
||||
sendRequest("bluetooth.connect", {
|
||||
"device": devicePath
|
||||
}, callback)
|
||||
"device": devicePath
|
||||
}, callback);
|
||||
}
|
||||
|
||||
function bluetoothDisconnect(devicePath, callback) {
|
||||
sendRequest("bluetooth.disconnect", {
|
||||
"device": devicePath
|
||||
}, callback)
|
||||
"device": devicePath
|
||||
}, callback);
|
||||
}
|
||||
|
||||
function bluetoothRemove(devicePath, callback) {
|
||||
sendRequest("bluetooth.remove", {
|
||||
"device": devicePath
|
||||
}, callback)
|
||||
"device": devicePath
|
||||
}, callback);
|
||||
}
|
||||
|
||||
function bluetoothTrust(devicePath, callback) {
|
||||
sendRequest("bluetooth.trust", {
|
||||
"device": devicePath
|
||||
}, callback)
|
||||
"device": devicePath
|
||||
}, callback);
|
||||
}
|
||||
|
||||
function bluetoothSubmitPairing(token, secrets, accept, callback) {
|
||||
sendRequest("bluetooth.pairing.submit", {
|
||||
"token": token,
|
||||
"secrets": secrets,
|
||||
"accept": accept
|
||||
}, callback)
|
||||
"token": token,
|
||||
"secrets": secrets,
|
||||
"accept": accept
|
||||
}, callback);
|
||||
}
|
||||
|
||||
function bluetoothCancelPairing(token, callback) {
|
||||
sendRequest("bluetooth.pairing.cancel", {
|
||||
"token": token
|
||||
}, callback)
|
||||
"token": token
|
||||
}, callback);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,17 @@ Item {
|
||||
property var options: []
|
||||
property var optionIcons: []
|
||||
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 maxPopupHeight: 400
|
||||
property bool openUpwards: false
|
||||
@@ -30,9 +41,9 @@ Item {
|
||||
implicitHeight: compactMode ? 40 : Math.max(60, labelColumn.implicitHeight + Theme.spacingM)
|
||||
|
||||
Component.onDestruction: {
|
||||
const popup = dropdownMenu
|
||||
const popup = dropdownMenu;
|
||||
if (popup && popup.visible) {
|
||||
popup.close()
|
||||
popup.close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,38 +96,38 @@ Item {
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
if (dropdownMenu.visible) {
|
||||
dropdownMenu.close()
|
||||
return
|
||||
dropdownMenu.close();
|
||||
return;
|
||||
}
|
||||
|
||||
dropdownMenu.searchQuery = ""
|
||||
dropdownMenu.updateFilteredOptions()
|
||||
dropdownMenu.searchQuery = "";
|
||||
dropdownMenu.updateFilteredOptions();
|
||||
|
||||
dropdownMenu.open()
|
||||
dropdownMenu.open();
|
||||
|
||||
const pos = dropdown.mapToItem(Overlay.overlay, 0, 0)
|
||||
const popupWidth = dropdownMenu.width
|
||||
const popupHeight = dropdownMenu.height
|
||||
const overlayHeight = Overlay.overlay.height
|
||||
const pos = dropdown.mapToItem(Overlay.overlay, 0, 0);
|
||||
const popupWidth = dropdownMenu.width;
|
||||
const popupHeight = dropdownMenu.height;
|
||||
const overlayHeight = Overlay.overlay.height;
|
||||
|
||||
if (root.openUpwards || pos.y + dropdown.height + popupHeight + 4 > overlayHeight) {
|
||||
if (root.alignPopupRight) {
|
||||
dropdownMenu.x = pos.x + dropdown.width - popupWidth
|
||||
dropdownMenu.x = pos.x + dropdown.width - popupWidth;
|
||||
} 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 {
|
||||
if (root.alignPopupRight) {
|
||||
dropdownMenu.x = pos.x + dropdown.width - popupWidth
|
||||
dropdownMenu.x = pos.x + dropdown.width - popupWidth;
|
||||
} 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) {
|
||||
searchField.forceActiveFocus()
|
||||
searchField.forceActiveFocus();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -133,8 +144,8 @@ Item {
|
||||
|
||||
DankIcon {
|
||||
name: {
|
||||
const currentIndex = root.options.indexOf(root.currentValue)
|
||||
return currentIndex >= 0 && root.optionIcons.length > currentIndex ? root.optionIcons[currentIndex] : ""
|
||||
const currentIndex = root.options.indexOf(root.currentValue);
|
||||
return currentIndex >= 0 && root.optionIcons.length > currentIndex ? root.optionIcons[currentIndex] : "";
|
||||
}
|
||||
size: 18
|
||||
color: Theme.surfaceText
|
||||
@@ -186,39 +197,39 @@ Item {
|
||||
|
||||
function updateFilteredOptions() {
|
||||
if (!root.enableFuzzySearch || searchQuery.length === 0) {
|
||||
filteredOptions = root.options
|
||||
selectedIndex = -1
|
||||
return
|
||||
filteredOptions = root.options;
|
||||
selectedIndex = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
const results = fzfFinder.find(searchQuery)
|
||||
filteredOptions = results.map(result => result.item)
|
||||
selectedIndex = -1
|
||||
const results = fzfFinder.find(searchQuery);
|
||||
filteredOptions = results.map(result => result.item);
|
||||
selectedIndex = -1;
|
||||
}
|
||||
|
||||
function selectNext() {
|
||||
if (filteredOptions.length === 0) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
selectedIndex = (selectedIndex + 1) % filteredOptions.length
|
||||
listView.positionViewAtIndex(selectedIndex, ListView.Contain)
|
||||
selectedIndex = (selectedIndex + 1) % filteredOptions.length;
|
||||
listView.positionViewAtIndex(selectedIndex, ListView.Contain);
|
||||
}
|
||||
|
||||
function selectPrevious() {
|
||||
if (filteredOptions.length === 0) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
selectedIndex = selectedIndex <= 0 ? filteredOptions.length - 1 : selectedIndex - 1
|
||||
listView.positionViewAtIndex(selectedIndex, ListView.Contain)
|
||||
selectedIndex = selectedIndex <= 0 ? filteredOptions.length - 1 : selectedIndex - 1;
|
||||
listView.positionViewAtIndex(selectedIndex, ListView.Contain);
|
||||
}
|
||||
|
||||
function selectCurrent() {
|
||||
if (selectedIndex < 0 || selectedIndex >= filteredOptions.length) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
root.currentValue = filteredOptions[selectedIndex]
|
||||
root.valueChanged(filteredOptions[selectedIndex])
|
||||
close()
|
||||
root.currentValue = filteredOptions[selectedIndex];
|
||||
root.valueChanged(filteredOptions[selectedIndex]);
|
||||
close();
|
||||
}
|
||||
|
||||
parent: Overlay.overlay
|
||||
@@ -270,8 +281,8 @@ Item {
|
||||
topPadding: Theme.spacingS
|
||||
bottomPadding: Theme.spacingS
|
||||
onTextChanged: {
|
||||
dropdownMenu.searchQuery = text
|
||||
dropdownMenu.updateFilteredOptions()
|
||||
dropdownMenu.searchQuery = text;
|
||||
dropdownMenu.updateFilteredOptions();
|
||||
}
|
||||
Keys.onDownPressed: dropdownMenu.selectNext()
|
||||
Keys.onUpPressed: dropdownMenu.selectPrevious()
|
||||
@@ -279,17 +290,17 @@ Item {
|
||||
Keys.onEnterPressed: dropdownMenu.selectCurrent()
|
||||
Keys.onPressed: event => {
|
||||
if (event.key === Qt.Key_N && event.modifiers & Qt.ControlModifier) {
|
||||
dropdownMenu.selectNext()
|
||||
event.accepted = true
|
||||
dropdownMenu.selectNext();
|
||||
event.accepted = true;
|
||||
} else if (event.key === Qt.Key_P && event.modifiers & Qt.ControlModifier) {
|
||||
dropdownMenu.selectPrevious()
|
||||
event.accepted = true
|
||||
dropdownMenu.selectPrevious();
|
||||
event.accepted = true;
|
||||
} else if (event.key === Qt.Key_J && event.modifiers & Qt.ControlModifier) {
|
||||
dropdownMenu.selectNext()
|
||||
event.accepted = true
|
||||
dropdownMenu.selectNext();
|
||||
event.accepted = true;
|
||||
} else if (event.key === Qt.Key_K && event.modifiers & Qt.ControlModifier) {
|
||||
dropdownMenu.selectPrevious()
|
||||
event.accepted = true
|
||||
dropdownMenu.selectPrevious();
|
||||
event.accepted = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -362,9 +373,9 @@ Item {
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
root.currentValue = modelData
|
||||
root.valueChanged(modelData)
|
||||
dropdownMenu.close()
|
||||
root.currentValue = modelData;
|
||||
root.valueChanged(modelData);
|
||||
dropdownMenu.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user