1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-01-24 21:42:51 -05:00
Files
DankMaterialShell/core/internal/server/cups/handlers.go

467 lines
13 KiB
Go

package cups
import (
"encoding/json"
"fmt"
"net"
"github.com/AvengeMedia/DankMaterialShell/core/internal/server/models"
"github.com/AvengeMedia/DankMaterialShell/core/internal/server/params"
)
type CUPSEvent struct {
Type string `json:"type"`
Data CUPSState `json:"data"`
}
type TestPageResult struct {
Success bool `json:"success"`
JobID int `json:"jobId"`
Message string `json:"message"`
}
func HandleRequest(conn net.Conn, req models.Request, manager *Manager) {
switch req.Method {
case "cups.subscribe":
handleSubscribe(conn, req, manager)
case "cups.getPrinters":
handleGetPrinters(conn, req, manager)
case "cups.getJobs":
handleGetJobs(conn, req, manager)
case "cups.pausePrinter":
handlePausePrinter(conn, req, manager)
case "cups.resumePrinter":
handleResumePrinter(conn, req, manager)
case "cups.cancelJob":
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))
}
}
func handleGetPrinters(conn net.Conn, req models.Request, manager *Manager) {
printers, err := manager.GetPrinters()
if err != nil {
models.RespondError(conn, req.ID, err.Error())
return
}
models.Respond(conn, req.ID, printers)
}
func handleGetJobs(conn net.Conn, req models.Request, manager *Manager) {
printerName, err := params.String(req.Params, "printerName")
if err != nil {
models.RespondError(conn, req.ID, err.Error())
return
}
jobs, err := manager.GetJobs(printerName, "not-completed")
if err != nil {
models.RespondError(conn, req.ID, err.Error())
return
}
models.Respond(conn, req.ID, jobs)
}
func handlePausePrinter(conn net.Conn, req models.Request, manager *Manager) {
printerName, err := params.String(req.Params, "printerName")
if err != nil {
models.RespondError(conn, req.ID, err.Error())
return
}
if err := manager.PausePrinter(printerName); err != nil {
models.RespondError(conn, req.ID, err.Error())
return
}
models.Respond(conn, req.ID, models.SuccessResult{Success: true, Message: "paused"})
}
func handleResumePrinter(conn net.Conn, req models.Request, manager *Manager) {
printerName, err := params.String(req.Params, "printerName")
if err != nil {
models.RespondError(conn, req.ID, err.Error())
return
}
if err := manager.ResumePrinter(printerName); err != nil {
models.RespondError(conn, req.ID, err.Error())
return
}
models.Respond(conn, req.ID, models.SuccessResult{Success: true, Message: "resumed"})
}
func handleCancelJob(conn net.Conn, req models.Request, manager *Manager) {
jobID, err := params.Int(req.Params, "jobID")
if err != nil {
models.RespondError(conn, req.ID, err.Error())
return
}
if err := manager.CancelJob(jobID); err != nil {
models.RespondError(conn, req.ID, err.Error())
return
}
models.Respond(conn, req.ID, models.SuccessResult{Success: true, Message: "job canceled"})
}
func handlePurgeJobs(conn net.Conn, req models.Request, manager *Manager) {
printerName, err := params.String(req.Params, "printerName")
if err != nil {
models.RespondError(conn, req.ID, err.Error())
return
}
if err := manager.PurgeJobs(printerName); err != nil {
models.RespondError(conn, req.ID, err.Error())
return
}
models.Respond(conn, req.ID, models.SuccessResult{Success: true, Message: "jobs canceled"})
}
func handleSubscribe(conn net.Conn, req models.Request, manager *Manager) {
clientID := fmt.Sprintf("client-%p", conn)
stateChan := manager.Subscribe(clientID)
defer manager.Unsubscribe(clientID)
initialState := manager.GetState()
event := CUPSEvent{
Type: "state_changed",
Data: initialState,
}
if err := json.NewEncoder(conn).Encode(models.Response[CUPSEvent]{
ID: req.ID,
Result: &event,
}); err != nil {
return
}
for state := range stateChan {
event := CUPSEvent{
Type: "state_changed",
Data: state,
}
if err := json.NewEncoder(conn).Encode(models.Response[CUPSEvent]{
Result: &event,
}); err != nil {
return
}
}
}
func handleGetDevices(conn net.Conn, req models.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 models.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 models.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 models.Request, manager *Manager) {
name, err := params.StringNonEmpty(req.Params, "name")
if err != nil {
models.RespondError(conn, req.ID, err.Error())
return
}
deviceURI, err := params.StringNonEmpty(req.Params, "deviceURI")
if err != nil {
models.RespondError(conn, req.ID, err.Error())
return
}
ppd, err := params.StringNonEmpty(req.Params, "ppd")
if err != nil {
models.RespondError(conn, req.ID, err.Error())
return
}
shared := params.BoolOpt(req.Params, "shared", false)
errorPolicy := params.StringOpt(req.Params, "errorPolicy", "")
information := params.StringOpt(req.Params, "information", "")
location := params.StringOpt(req.Params, "location", "")
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, models.SuccessResult{Success: true, Message: "printer created"})
}
func handleDeletePrinter(conn net.Conn, req models.Request, manager *Manager) {
printerName, err := params.StringNonEmpty(req.Params, "printerName")
if err != nil {
models.RespondError(conn, req.ID, err.Error())
return
}
if err := manager.DeletePrinter(printerName); err != nil {
models.RespondError(conn, req.ID, err.Error())
return
}
models.Respond(conn, req.ID, models.SuccessResult{Success: true, Message: "printer deleted"})
}
func handleAcceptJobs(conn net.Conn, req models.Request, manager *Manager) {
printerName, err := params.StringNonEmpty(req.Params, "printerName")
if err != nil {
models.RespondError(conn, req.ID, err.Error())
return
}
if err := manager.AcceptJobs(printerName); err != nil {
models.RespondError(conn, req.ID, err.Error())
return
}
models.Respond(conn, req.ID, models.SuccessResult{Success: true, Message: "accepting jobs"})
}
func handleRejectJobs(conn net.Conn, req models.Request, manager *Manager) {
printerName, err := params.StringNonEmpty(req.Params, "printerName")
if err != nil {
models.RespondError(conn, req.ID, err.Error())
return
}
if err := manager.RejectJobs(printerName); err != nil {
models.RespondError(conn, req.ID, err.Error())
return
}
models.Respond(conn, req.ID, models.SuccessResult{Success: true, Message: "rejecting jobs"})
}
func handleSetPrinterShared(conn net.Conn, req models.Request, manager *Manager) {
printerName, err := params.StringNonEmpty(req.Params, "printerName")
if err != nil {
models.RespondError(conn, req.ID, err.Error())
return
}
shared, err := params.Bool(req.Params, "shared")
if err != nil {
models.RespondError(conn, req.ID, err.Error())
return
}
if err := manager.SetPrinterShared(printerName, shared); err != nil {
models.RespondError(conn, req.ID, err.Error())
return
}
models.Respond(conn, req.ID, models.SuccessResult{Success: true, Message: "sharing updated"})
}
func handleSetPrinterLocation(conn net.Conn, req models.Request, manager *Manager) {
printerName, err := params.StringNonEmpty(req.Params, "printerName")
if err != nil {
models.RespondError(conn, req.ID, err.Error())
return
}
location, err := params.String(req.Params, "location")
if err != nil {
models.RespondError(conn, req.ID, err.Error())
return
}
if err := manager.SetPrinterLocation(printerName, location); err != nil {
models.RespondError(conn, req.ID, err.Error())
return
}
models.Respond(conn, req.ID, models.SuccessResult{Success: true, Message: "location updated"})
}
func handleSetPrinterInfo(conn net.Conn, req models.Request, manager *Manager) {
printerName, err := params.StringNonEmpty(req.Params, "printerName")
if err != nil {
models.RespondError(conn, req.ID, err.Error())
return
}
info, err := params.String(req.Params, "info")
if err != nil {
models.RespondError(conn, req.ID, err.Error())
return
}
if err := manager.SetPrinterInfo(printerName, info); err != nil {
models.RespondError(conn, req.ID, err.Error())
return
}
models.Respond(conn, req.ID, models.SuccessResult{Success: true, Message: "info updated"})
}
func handleMoveJob(conn net.Conn, req models.Request, manager *Manager) {
jobID, err := params.Int(req.Params, "jobID")
if err != nil {
models.RespondError(conn, req.ID, err.Error())
return
}
destPrinter, err := params.StringNonEmpty(req.Params, "destPrinter")
if err != nil {
models.RespondError(conn, req.ID, err.Error())
return
}
if err := manager.MoveJob(jobID, destPrinter); err != nil {
models.RespondError(conn, req.ID, err.Error())
return
}
models.Respond(conn, req.ID, models.SuccessResult{Success: true, Message: "job moved"})
}
func handlePrintTestPage(conn net.Conn, req models.Request, manager *Manager) {
printerName, err := params.StringNonEmpty(req.Params, "printerName")
if err != nil {
models.RespondError(conn, req.ID, err.Error())
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 models.Request, manager *Manager) {
className, err := params.StringNonEmpty(req.Params, "className")
if err != nil {
models.RespondError(conn, req.ID, err.Error())
return
}
printerName, err := params.StringNonEmpty(req.Params, "printerName")
if err != nil {
models.RespondError(conn, req.ID, err.Error())
return
}
if err := manager.AddPrinterToClass(className, printerName); err != nil {
models.RespondError(conn, req.ID, err.Error())
return
}
models.Respond(conn, req.ID, models.SuccessResult{Success: true, Message: "printer added to class"})
}
func handleRemovePrinterFromClass(conn net.Conn, req models.Request, manager *Manager) {
className, err := params.StringNonEmpty(req.Params, "className")
if err != nil {
models.RespondError(conn, req.ID, err.Error())
return
}
printerName, err := params.StringNonEmpty(req.Params, "printerName")
if err != nil {
models.RespondError(conn, req.ID, err.Error())
return
}
if err := manager.RemovePrinterFromClass(className, printerName); err != nil {
models.RespondError(conn, req.ID, err.Error())
return
}
models.Respond(conn, req.ID, models.SuccessResult{Success: true, Message: "printer removed from class"})
}
func handleDeleteClass(conn net.Conn, req models.Request, manager *Manager) {
className, err := params.StringNonEmpty(req.Params, "className")
if err != nil {
models.RespondError(conn, req.ID, err.Error())
return
}
if err := manager.DeleteClass(className); err != nil {
models.RespondError(conn, req.ID, err.Error())
return
}
models.Respond(conn, req.ID, models.SuccessResult{Success: true, Message: "class deleted"})
}
func handleRestartJob(conn net.Conn, req models.Request, manager *Manager) {
jobID, err := params.Int(req.Params, "jobID")
if err != nil {
models.RespondError(conn, req.ID, err.Error())
return
}
if err := manager.RestartJob(jobID); err != nil {
models.RespondError(conn, req.ID, err.Error())
return
}
models.Respond(conn, req.ID, models.SuccessResult{Success: true, Message: "job restarted"})
}
func handleHoldJob(conn net.Conn, req models.Request, manager *Manager) {
jobID, err := params.Int(req.Params, "jobID")
if err != nil {
models.RespondError(conn, req.ID, err.Error())
return
}
holdUntil := params.StringOpt(req.Params, "holdUntil", "indefinite")
if err := manager.HoldJob(jobID, holdUntil); err != nil {
models.RespondError(conn, req.ID, err.Error())
return
}
models.Respond(conn, req.ID, models.SuccessResult{Success: true, Message: "job held"})
}