package service import ( "context" "github.com/cloudprint/cloudprint-backend/internal/service" pb "github.com/cloudprint/cloudprint-backend/proto/generated" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) type PrintServiceServer struct { pb.UnimplementedPrintServiceServer printService *service.PrintService } func NewPrintServiceServer(printService *service.PrintService) *PrintServiceServer { return &PrintServiceServer{ printService: printService, } } func (s *PrintServiceServer) GetPrinters(ctx context.Context, req *pb.GetPrintersRequest) (*pb.PrinterListResponse, error) { printers, err := s.printService.GetPrinters(ctx) if err != nil { return nil, status.Errorf(codes.Internal, "get printers failed: %v", err) } pbPrinters := make([]*pb.Printer, 0, len(printers)) for _, printer := range printers { pbPrinters = append(pbPrinters, &pb.Printer{ Id: printer.ID, Name: printer.Name, DisplayName: printer.DisplayName, IsActive: printer.IsActive, Status: int32(printer.Status), }) } return &pb.PrinterListResponse{Printers: pbPrinters}, nil } func (s *PrintServiceServer) GetPrinterStatus(ctx context.Context, req *pb.GetPrinterStatusRequest) (*pb.PrinterStatusResponse, error) { printer, queueCount, err := s.printService.GetPrinterStatus(ctx, req.PrinterId) if err != nil || printer == nil { return nil, status.Errorf(codes.NotFound, "printer not found") } return &pb.PrinterStatusResponse{ Printer: &pb.Printer{ Id: printer.ID, Name: printer.Name, DisplayName: printer.DisplayName, IsActive: printer.IsActive, Status: int32(printer.Status), }, QueueCount: int32(queueCount), }, nil } func (s *PrintServiceServer) RegisterPrinter(ctx context.Context, req *pb.RegisterPrinterRequest) (*pb.RegisterPrinterResponse, error) { printer, token, err := s.printService.RegisterPrinter(ctx, req.Name, req.DisplayName, req.ApiKey) if err != nil { return nil, status.Errorf(codes.Internal, "register printer failed: %v", err) } if printer == nil { return nil, status.Errorf(codes.AlreadyExists, "printer already exists") } return &pb.RegisterPrinterResponse{ PrinterId: printer.ID, Token: token, }, nil } func (s *PrintServiceServer) PrinterHeartbeat(ctx context.Context, req *pb.PrinterHeartbeatRequest) (*pb.Empty, error) { err := s.printService.PrinterHeartbeat(ctx, req.PrinterId, int8(req.Status), req.Token) if err != nil { return nil, status.Errorf(codes.Internal, "heartbeat failed: %v", err) } return &pb.Empty{}, nil } func (s *PrintServiceServer) SubmitPrintJob(ctx context.Context, req *pb.SubmitPrintJobRequest) (*pb.SubmitPrintJobResponse, error) { job, err := s.printService.SubmitPrintJob(ctx, req.OrderItemId, req.PrinterId, "", int(req.Copies), req.Color, req.Duplex, req.PageRange) if err != nil { return nil, status.Errorf(codes.Internal, "submit print job failed: %v", err) } return &pb.SubmitPrintJobResponse{ JobNo: job.JobNo, }, nil } func (s *PrintServiceServer) CancelPrintJob(ctx context.Context, req *pb.CancelPrintJobRequest) (*pb.Empty, error) { err := s.printService.CancelPrintJob(ctx, req.JobNo) if err != nil { return nil, status.Errorf(codes.Internal, "cancel print job failed: %v", err) } return &pb.Empty{}, nil } func (s *PrintServiceServer) SubscribeJobs(req *pb.SubscribeJobsRequest, stream pb.PrintService_SubscribeJobsServer) error { ch, err := s.printService.SubscribeJobs(stream.Context(), req.PrinterId, req.Token) if err != nil { return status.Errorf(codes.Internal, "subscribe jobs failed: %v", err) } for job := range ch { if err := stream.Send(&pb.PrintJob{ Id: job.ID, JobNo: job.JobNo, PrinterId: job.PrinterID, OrderItemId: job.OrderItemID, Status: job.Status, Progress: int32(job.Progress), ErrorMsg: job.ErrorMsg, }); err != nil { s.printService.UnsubscribeJobs(req.PrinterId) return err } } return nil } func (s *PrintServiceServer) ReportJobStatus(ctx context.Context, req *pb.ReportJobStatusRequest) (*pb.Empty, error) { err := s.printService.ReportJobStatus(ctx, req.JobNo, req.Status, int(req.Progress), req.ErrorMsg) if err != nil { return nil, status.Errorf(codes.Internal, "report job status failed: %v", err) } return &pb.Empty{}, nil }