func convertPagesPerSheet(printerTags map[string][]string) *cdd.VendorCapability { numberUpSupported, exists := printerTags[attrNumberUpSupported] if !exists { return nil } c := cdd.VendorCapability{ ID: attrNumberUp, Type: cdd.VendorCapabilitySelect, SelectCap: &cdd.SelectCapability{}, DisplayNameLocalized: cdd.NewLocalizedString("Pages per sheet"), } def, exists := printerTags[attrNumberUpDefault] if !exists { def = []string{"1"} } for _, number := range numberUpSupported { option := cdd.SelectCapabilityOption{ Value: number, IsDefault: reflect.DeepEqual(number, def[0]), DisplayNameLocalized: cdd.NewLocalizedString(number), } c.SelectCap.Option = append(c.SelectCap.Option, option) } return &c }
func TestGetVendorState(t *testing.T) { vs := getVendorState(nil) if nil != vs { t.Logf("expected nil") t.Fail() } pt := map[string][]string{} vs = getVendorState(pt) if nil != vs { t.Logf("expected nil") t.Fail() } pt = map[string][]string{ attrPrinterStateReasons: []string{"broken-arrow", "peanut-butter-jam-warning"}, } expected := &cdd.VendorState{ Item: []cdd.VendorStateItem{ cdd.VendorStateItem{ DescriptionLocalized: cdd.NewLocalizedString("broken-arrow"), State: cdd.VendorStateError, }, cdd.VendorStateItem{ DescriptionLocalized: cdd.NewLocalizedString("peanut-butter-jam-warning"), State: cdd.VendorStateWarning, }, }, } vs = getVendorState(pt) if !reflect.DeepEqual(expected, vs) { t.Logf("expected\n %+v\ngot\n %+v", expected, vs) t.Fail() } }
func TestTrInputSlot(t *testing.T) { ppd := `*PPD-Adobe: "4.3" *OpenUI *OutputBin/Destination: PickOne *OrderDependency: 210 AnySetup *OutputBin *DefaultOutputBin: FinProof *OutputBin Standard/Internal Tray 1: "" *OutputBin Bin1/Internal Tray 2: "" *OutputBin External/External Tray: "" *CloseUI: *OutputBin` expected := &cdd.PrinterDescriptionSection{ VendorCapability: &[]cdd.VendorCapability{ cdd.VendorCapability{ ID: "OutputBin", Type: cdd.VendorCapabilitySelect, DisplayNameLocalized: cdd.NewLocalizedString("Destination"), SelectCap: &cdd.SelectCapability{ Option: []cdd.SelectCapabilityOption{ cdd.SelectCapabilityOption{"Standard", "", true, cdd.NewLocalizedString("Internal Tray 1")}, cdd.SelectCapabilityOption{"Bin1", "", false, cdd.NewLocalizedString("Internal Tray 2")}, cdd.SelectCapabilityOption{"External", "", false, cdd.NewLocalizedString("External Tray")}, }, }, }, }, } translationTest(t, ppd, expected) }
func TestConvertColorAttrs(t *testing.T) { c := convertColorAttrs(nil) if c != nil { t.Logf("expected nil") t.Fail() } pt := map[string][]string{} c = convertColorAttrs(pt) if c != nil { t.Logf("expected nil") t.Fail() } pt = map[string][]string{ "print-color-mode-default": []string{"auto"}, "print-color-mode-supported": []string{"color", "monochrome", "auto", "zebra"}, } expected := &cdd.Color{ Option: []cdd.ColorOption{ cdd.ColorOption{"print-color-mode:color", cdd.ColorTypeStandardColor, "", false, cdd.NewLocalizedString("Color")}, cdd.ColorOption{"print-color-mode:monochrome", cdd.ColorTypeStandardMonochrome, "", false, cdd.NewLocalizedString("Monochrome")}, cdd.ColorOption{"print-color-mode:auto", cdd.ColorTypeAuto, "", true, cdd.NewLocalizedString("Auto")}, cdd.ColorOption{"print-color-mode:zebra", cdd.ColorTypeCustomColor, "", false, cdd.NewLocalizedString("zebra")}, }, } c = convertColorAttrs(pt) if !reflect.DeepEqual(expected, c) { t.Logf("expected %+v, got %+v", expected, c) t.Fail() } }
func TestTrPrintQuality(t *testing.T) { ppd := `*PPD-Adobe: "4.3" *OpenUI *HPPrintQuality/Print Quality: PickOne *DefaultHPPrintQuality: FastRes1200 *HPPrintQuality FastRes1200/FastRes 1200: "" *HPPrintQuality 600dpi/600 dpi: "" *HPPrintQuality ProRes1200/ProRes 1200: "" *CloseUI: *HPPrintQuality` expected := &cdd.PrinterDescriptionSection{ VendorCapability: &[]cdd.VendorCapability{ cdd.VendorCapability{ ID: "HPPrintQuality", Type: cdd.VendorCapabilitySelect, DisplayNameLocalized: cdd.NewLocalizedString("Print Quality"), SelectCap: &cdd.SelectCapability{ Option: []cdd.SelectCapabilityOption{ cdd.SelectCapabilityOption{"FastRes1200", "", true, cdd.NewLocalizedString("FastRes 1200")}, cdd.SelectCapabilityOption{"600dpi", "", false, cdd.NewLocalizedString("600 dpi")}, cdd.SelectCapabilityOption{"ProRes1200", "", false, cdd.NewLocalizedString("ProRes 1200")}, }, }, }, }, } translationTest(t, ppd, expected) }
func TestTrColor(t *testing.T) { ppd := `*PPD-Adobe: "4.3" *OpenUI *ColorModel/Color Mode: PickOne *DefaultColorModel: Gray *ColorModel CMYK/Color: "(cmyk) RCsetdevicecolor" *ColorModel Gray/Black and White: "(gray) RCsetdevicecolor" *CloseUI: *ColorModel` expected := &cdd.PrinterDescriptionSection{ Color: &cdd.Color{ Option: []cdd.ColorOption{ cdd.ColorOption{"ColorModel:CMYK", cdd.ColorTypeStandardColor, "", false, cdd.NewLocalizedString("Color")}, cdd.ColorOption{"ColorModel:Gray", cdd.ColorTypeStandardMonochrome, "", true, cdd.NewLocalizedString("Black and White")}, }, }, } translationTest(t, ppd, expected) ppd = `*PPD-Adobe: "4.3" *OpenUI *CMAndResolution/Print Color as Gray: PickOne *OrderDependency: 20 AnySetup *CMAndResolution *DefaultCMAndResolution: CMYKImageRET3600 *CMAndResolution CMYKImageRET3600/Off: " <</ProcessColorModel /DeviceCMYK /HWResolution [600 600] /PreRenderingEnhance false >> setpagedevice" *End *CMAndResolution Gray600x600dpi/On: " <</ProcessColorModel /DeviceGray /HWResolution [600 600] >> setpagedevice" *End *CloseUI: *CMAndResolution ` expected = &cdd.PrinterDescriptionSection{ Color: &cdd.Color{ Option: []cdd.ColorOption{ cdd.ColorOption{"CMAndResolution:CMYKImageRET3600", cdd.ColorTypeStandardColor, "", true, cdd.NewLocalizedString("Color")}, cdd.ColorOption{"CMAndResolution:Gray600x600dpi", cdd.ColorTypeStandardMonochrome, "", false, cdd.NewLocalizedString("Gray")}, }, }, } translationTest(t, ppd, expected) ppd = `*PPD-Adobe: "4.3" *OpenUI *CMAndResolution/Print Color as Gray: PickOne *OrderDependency: 20 AnySetup *CMAndResolution *DefaultCMAndResolution: CMYKImageRET2400 *CMAndResolution CMYKImageRET2400/Off - ImageRET 2400: "<< /ProcessColorModel /DeviceCMYK /HWResolution [600 600] >> setpagedevice" *CMAndResolution Gray1200x1200dpi/On - ProRes 1200: "<</ProcessColorModel /DeviceGray /HWResolution [1200 1200] /PreRenderingEnhance false>> setpagedevice" *CMAndResolution Gray600x600dpi/On - 600 dpi: "<</ProcessColorModel /DeviceGray /HWResolution [600 600] /PreRenderingEnhance false>> setpagedevice" *CloseUI: *CMAndResolution ` expected = &cdd.PrinterDescriptionSection{ Color: &cdd.Color{ Option: []cdd.ColorOption{ cdd.ColorOption{"CMAndResolution:CMYKImageRET2400", cdd.ColorTypeStandardColor, "", true, cdd.NewLocalizedString("Color, ImageRET 2400")}, cdd.ColorOption{"CMAndResolution:Gray1200x1200dpi", cdd.ColorTypeCustomMonochrome, "", false, cdd.NewLocalizedString("Gray, ProRes 1200")}, cdd.ColorOption{"CMAndResolution:Gray600x600dpi", cdd.ColorTypeCustomMonochrome, "", false, cdd.NewLocalizedString("Gray, 600 dpi")}, }, }, } translationTest(t, ppd, expected) }
func TestConvertPagesPerSheet(t *testing.T) { vc := convertPagesPerSheet(nil) if vc != nil { t.Logf("expected nil") t.Fail() } pt := map[string][]string{} vc = convertPagesPerSheet(pt) if vc != nil { t.Logf("expected nil") t.Fail() } pt = map[string][]string{ "number-up-default": []string{"4"}, "number-up-supported": []string{"1", "2", "4"}, } expected := &cdd.VendorCapability{ ID: "number-up", Type: cdd.VendorCapabilitySelect, SelectCap: &cdd.SelectCapability{ Option: []cdd.SelectCapabilityOption{ cdd.SelectCapabilityOption{ Value: "1", IsDefault: false, DisplayNameLocalized: cdd.NewLocalizedString("1"), }, cdd.SelectCapabilityOption{ Value: "2", IsDefault: false, DisplayNameLocalized: cdd.NewLocalizedString("2"), }, cdd.SelectCapabilityOption{ Value: "4", IsDefault: true, DisplayNameLocalized: cdd.NewLocalizedString("4"), }, }, }, DisplayNameLocalized: cdd.NewLocalizedString("Pages per sheet"), } vc = convertPagesPerSheet(pt) if !reflect.DeepEqual(expected, vc) { e, _ := json.Marshal(expected) f, _ := json.Marshal(vc) t.Logf("expected\n %s\ngot\n %s", e, f) t.Fail() } }
func convertColorAttrs(printerTags map[string][]string) *cdd.Color { colorSupported, exists := printerTags[attrPrintColorModeSupported] if !exists { return nil } colorDefault, exists := printerTags[attrPrintColorModeDefault] if !exists || len(colorDefault) != 1 { colorDefault = colorSupported[:1] } var c cdd.Color for _, color := range colorSupported { var co cdd.ColorOption var exists bool if co, exists = colorByKeyword[color]; !exists { co = cdd.ColorOption{ VendorID: fmt.Sprintf("%s%s%s", attrPrintColorMode, internalKeySeparator, color), Type: cdd.ColorTypeCustomColor, CustomDisplayNameLocalized: cdd.NewLocalizedString(color), } } if color == colorDefault[0] { co.IsDefault = true } c.Option = append(c.Option, co) } return &c }
func TestTrColor(t *testing.T) { ppd := `*PPD-Adobe: "4.3" *OpenUI *ColorModel/Color Mode: PickOne *DefaultColorModel: Gray *ColorModel CMYK/Color: "(cmyk) RCsetdevicecolor" *ColorModel Gray/Black and White: "(gray) RCsetdevicecolor" *CloseUI: *ColorModel` expected := &cdd.PrinterDescriptionSection{ Color: &cdd.Color{ Option: []cdd.ColorOption{ cdd.ColorOption{"ColorModelCMYK", cdd.ColorTypeStandardColor, "", false, cdd.NewLocalizedString("Color")}, cdd.ColorOption{"ColorModelGray", cdd.ColorTypeStandardMonochrome, "", true, cdd.NewLocalizedString("Black and White")}, }, }, } translationTest(t, ppd, expected) }
func TestTrDPI(t *testing.T) { ppd := `*PPD-Adobe: "4.3" *OpenUI *Resolution/Resolution: PickOne *DefaultResolution: 600dpi *Resolution 600dpi/600 dpi: "" *Resolution 1200x600dpi/1200x600 dpi: "" *Resolution 1200x1200dpi/1200 dpi: "" *CloseUI: *Resolution` expected := &cdd.PrinterDescriptionSection{ DPI: &cdd.DPI{ Option: []cdd.DPIOption{ cdd.DPIOption{600, 600, true, "", "600dpi", cdd.NewLocalizedString("600 dpi")}, cdd.DPIOption{1200, 600, false, "", "1200x600dpi", cdd.NewLocalizedString("1200x600 dpi")}, cdd.DPIOption{1200, 1200, false, "", "1200x1200dpi", cdd.NewLocalizedString("1200 dpi")}, }, }, } translationTest(t, ppd, expected) }
func (vs *VariableSet) GetCovers() (*[]cdd.Cover, *cdd.CoverState, bool) { descriptions := vs.GetSubtree(PrinterCoverDescription).Variables() statuses := vs.GetSubtree(PrinterCoverStatus).Variables() if len(descriptions) < 1 || len(descriptions) != len(statuses) { return nil, nil, false } covers := make([]cdd.Cover, 0, len(descriptions)) coverState := cdd.CoverState{make([]cdd.CoverStateItem, 0, len(statuses))} for i := 0; i < len(descriptions); i++ { index := cdd.NewSchizophrenicInt64(descriptions[i].Name[len(descriptions[i].Name)-1]) description := descriptions[i].Value state := PrinterCoverStatusToGCP[statuses[i].Value] cover := cdd.Cover{ VendorID: index.String(), Index: index, } switch strings.ToLower(description) { case "cover": cover.Type = cdd.CoverTypeCover case "door": cover.Type = cdd.CoverTypeDoor default: cover.Type = cdd.CoverTypeCustom cover.CustomDisplayNameLocalized = cdd.NewLocalizedString(description) } covers = append(covers, cover) coverStateItem := cdd.CoverStateItem{ VendorID: index.String(), State: state, } if state == cdd.CoverStateFailure { coverStateItem.VendorMessage = PrinterCoverStatusTC[statuses[i].Value] } coverState.Item = append(coverState.Item, coverStateItem) } return &covers, &coverState, true }
func TestRicohLockedPrint(t *testing.T) { ppd := `*PPD-Adobe: "4.3" *OpenUI *JobType/JobType: PickOne *FoomaticRIPOption JobType: enum CmdLine B *OrderDependency: 255 AnySetup *JobType *DefaultJobType: Normal *JobType Normal/Normal: "%% FoomaticRIPOptionSetting: JobType=Normal" *JobType SamplePrint/Sample Print: "%% FoomaticRIPOptionSetting: JobType=SamplePrint" *JobType LockedPrint/Locked Print: "" *JobType DocServer/Document Server: "" *CloseUI: *JobType *OpenUI *LockedPrintPassword/Locked Print Password (4-8 digits): PickOne *FoomaticRIPOption LockedPrintPassword: password CmdLine C *FoomaticRIPOptionMaxLength LockedPrintPassword:8 *FoomaticRIPOptionAllowedChars LockedPrintPassword: "******" *OrderDependency: 255 AnySetup *LockedPrintPassword *DefaultLockedPrintPassword: None *LockedPrintPassword None/None: "" *LockedPrintPassword 4001/4001: "%% FoomaticRIPOptionSetting: LockedPrintPassword=4001" *LockedPrintPassword 4002/4002: "%% FoomaticRIPOptionSetting: LockedPrintPassword=4002" *LockedPrintPassword 4003/4003: "%% FoomaticRIPOptionSetting: LockedPrintPassword=4003" *CloseUI: *LockedPrintPassword *CustomLockedPrintPassword True/Custom Password: "" *ParamCustomLockedPrintPassword Password: 1 passcode 4 8 ` expected := &cdd.PrinterDescriptionSection{ VendorCapability: &[]cdd.VendorCapability{ cdd.VendorCapability{ ID: "JobType:LockedPrint/LockedPrintPassword", Type: cdd.VendorCapabilityTypedValue, DisplayNameLocalized: cdd.NewLocalizedString("Password (4 numbers)"), TypedValueCap: &cdd.TypedValueCapability{ ValueType: cdd.TypedValueCapabilityTypeString, }, }, }, } translationTest(t, ppd, expected) }
func convertColorAttrs(printerTags map[string][]string) *cdd.Color { colorSupported, exists := printerTags[attrPrintColorModeSupported] if !exists { return nil } colorDefault, exists := printerTags[attrPrintColorModeDefault] if !exists || len(colorDefault) != 1 { colorDefault = colorSupported[:1] } var c cdd.Color for _, color := range colorSupported { var co cdd.ColorOption var exists bool if co, exists = colorByKeyword[color]; !exists { co = cdd.ColorOption{ VendorID: color, Type: cdd.ColorTypeCustomColor, CustomDisplayNameLocalized: cdd.NewLocalizedString(color), } } if color == colorDefault[0] { co.IsDefault = true } c.Option = append(c.Option, co) } for i := range c.Option { // Color can be specified by either attribute or PPD. // Therefore, prepend "ColorModel" to these ColorOptions. c.Option[i].VendorID = attrPrintColorMode + c.Option[i].VendorID } return &c }
func getVendorState(printerTags map[string][]string) *cdd.VendorState { reasons, exists := printerTags[attrPrinterStateReasons] if !exists || len(reasons) < 1 { return nil } sort.Strings(reasons) vendorState := &cdd.VendorState{Item: make([]cdd.VendorStateItem, len(reasons))} for i, reason := range reasons { vs := cdd.VendorStateItem{DescriptionLocalized: cdd.NewLocalizedString(reason)} if strings.HasSuffix(reason, "-error") { vs.State = cdd.VendorStateError } else if strings.HasSuffix(reason, "-warning") { vs.State = cdd.VendorStateWarning } else if strings.HasSuffix(reason, "-report") { vs.State = cdd.VendorStateInfo } else { vs.State = cdd.VendorStateError } vendorState.Item[i] = vs } return vendorState }
func convertPrinterState(wsStatus uint32) *cdd.PrinterStateSection { state := cdd.PrinterStateSection{ State: cdd.CloudDeviceStateIdle, VendorState: &cdd.VendorState{}, } if wsStatus&(PRINTER_STATUS_PRINTING|PRINTER_STATUS_PROCESSING) != 0 { state.State = cdd.CloudDeviceStateProcessing } if wsStatus&PRINTER_STATUS_PAUSED != 0 { state.State = cdd.CloudDeviceStateStopped vs := cdd.VendorStateItem{ State: cdd.VendorStateWarning, DescriptionLocalized: cdd.NewLocalizedString("printer paused"), } state.VendorState.Item = append(state.VendorState.Item, vs) } if wsStatus&PRINTER_STATUS_ERROR != 0 { state.State = cdd.CloudDeviceStateStopped vs := cdd.VendorStateItem{ State: cdd.VendorStateError, DescriptionLocalized: cdd.NewLocalizedString("printer error"), } state.VendorState.Item = append(state.VendorState.Item, vs) } if wsStatus&PRINTER_STATUS_PENDING_DELETION != 0 { state.State = cdd.CloudDeviceStateStopped vs := cdd.VendorStateItem{ State: cdd.VendorStateError, DescriptionLocalized: cdd.NewLocalizedString("printer is being deleted"), } state.VendorState.Item = append(state.VendorState.Item, vs) } if wsStatus&PRINTER_STATUS_PAPER_JAM != 0 { state.State = cdd.CloudDeviceStateStopped vs := cdd.VendorStateItem{ State: cdd.VendorStateError, DescriptionLocalized: cdd.NewLocalizedString("paper jam"), } state.VendorState.Item = append(state.VendorState.Item, vs) } if wsStatus&PRINTER_STATUS_PAPER_OUT != 0 { state.State = cdd.CloudDeviceStateStopped vs := cdd.VendorStateItem{ State: cdd.VendorStateError, DescriptionLocalized: cdd.NewLocalizedString("paper out"), } state.VendorState.Item = append(state.VendorState.Item, vs) } if wsStatus&PRINTER_STATUS_MANUAL_FEED != 0 { vs := cdd.VendorStateItem{ State: cdd.VendorStateInfo, DescriptionLocalized: cdd.NewLocalizedString("manual feed mode"), } state.VendorState.Item = append(state.VendorState.Item, vs) } if wsStatus&PRINTER_STATUS_PAPER_PROBLEM != 0 { state.State = cdd.CloudDeviceStateStopped vs := cdd.VendorStateItem{ State: cdd.VendorStateError, DescriptionLocalized: cdd.NewLocalizedString("paper problem"), } state.VendorState.Item = append(state.VendorState.Item, vs) } if wsStatus&PRINTER_STATUS_OFFLINE != 0 { state.State = cdd.CloudDeviceStateStopped vs := cdd.VendorStateItem{ State: cdd.VendorStateError, DescriptionLocalized: cdd.NewLocalizedString("printer is offline"), } state.VendorState.Item = append(state.VendorState.Item, vs) } if wsStatus&PRINTER_STATUS_IO_ACTIVE != 0 { vs := cdd.VendorStateItem{ State: cdd.VendorStateInfo, DescriptionLocalized: cdd.NewLocalizedString("active I/O state"), } state.VendorState.Item = append(state.VendorState.Item, vs) } if wsStatus&PRINTER_STATUS_BUSY != 0 { vs := cdd.VendorStateItem{ State: cdd.VendorStateInfo, DescriptionLocalized: cdd.NewLocalizedString("busy"), } state.VendorState.Item = append(state.VendorState.Item, vs) } if wsStatus&PRINTER_STATUS_OUTPUT_BIN_FULL != 0 { state.State = cdd.CloudDeviceStateStopped vs := cdd.VendorStateItem{ State: cdd.VendorStateError, DescriptionLocalized: cdd.NewLocalizedString("output bin is full"), } state.VendorState.Item = append(state.VendorState.Item, vs) } if wsStatus&PRINTER_STATUS_NOT_AVAILABLE != 0 { state.State = cdd.CloudDeviceStateStopped vs := cdd.VendorStateItem{ State: cdd.VendorStateError, DescriptionLocalized: cdd.NewLocalizedString("printer not available"), } state.VendorState.Item = append(state.VendorState.Item, vs) } if wsStatus&PRINTER_STATUS_WAITING != 0 { vs := cdd.VendorStateItem{ State: cdd.VendorStateError, DescriptionLocalized: cdd.NewLocalizedString("waiting"), } state.VendorState.Item = append(state.VendorState.Item, vs) } if wsStatus&PRINTER_STATUS_INITIALIZING != 0 { vs := cdd.VendorStateItem{ State: cdd.VendorStateInfo, DescriptionLocalized: cdd.NewLocalizedString("intitializing"), } state.VendorState.Item = append(state.VendorState.Item, vs) } if wsStatus&PRINTER_STATUS_WARMING_UP != 0 { vs := cdd.VendorStateItem{ State: cdd.VendorStateInfo, DescriptionLocalized: cdd.NewLocalizedString("warming up"), } state.VendorState.Item = append(state.VendorState.Item, vs) } if wsStatus&PRINTER_STATUS_TONER_LOW != 0 { vs := cdd.VendorStateItem{ State: cdd.VendorStateWarning, DescriptionLocalized: cdd.NewLocalizedString("toner low"), } state.VendorState.Item = append(state.VendorState.Item, vs) } if wsStatus&PRINTER_STATUS_NO_TONER != 0 { state.State = cdd.CloudDeviceStateStopped vs := cdd.VendorStateItem{ State: cdd.VendorStateError, DescriptionLocalized: cdd.NewLocalizedString("no toner"), } state.VendorState.Item = append(state.VendorState.Item, vs) } if wsStatus&PRINTER_STATUS_PAGE_PUNT != 0 { state.State = cdd.CloudDeviceStateStopped vs := cdd.VendorStateItem{ State: cdd.VendorStateError, DescriptionLocalized: cdd.NewLocalizedString("cannot print the current page"), } state.VendorState.Item = append(state.VendorState.Item, vs) } if wsStatus&PRINTER_STATUS_USER_INTERVENTION != 0 { state.State = cdd.CloudDeviceStateStopped vs := cdd.VendorStateItem{ State: cdd.VendorStateError, DescriptionLocalized: cdd.NewLocalizedString("user intervention required"), } state.VendorState.Item = append(state.VendorState.Item, vs) } if wsStatus&PRINTER_STATUS_OUT_OF_MEMORY != 0 { state.State = cdd.CloudDeviceStateStopped vs := cdd.VendorStateItem{ State: cdd.VendorStateError, DescriptionLocalized: cdd.NewLocalizedString("out of memory"), } state.VendorState.Item = append(state.VendorState.Item, vs) } if wsStatus&PRINTER_STATUS_DOOR_OPEN != 0 { state.State = cdd.CloudDeviceStateStopped vs := cdd.VendorStateItem{ State: cdd.VendorStateError, DescriptionLocalized: cdd.NewLocalizedString("door open"), } state.VendorState.Item = append(state.VendorState.Item, vs) } if wsStatus&PRINTER_STATUS_SERVER_UNKNOWN != 0 { vs := cdd.VendorStateItem{ State: cdd.VendorStateError, DescriptionLocalized: cdd.NewLocalizedString("printer status unknown"), } state.VendorState.Item = append(state.VendorState.Item, vs) } if wsStatus&PRINTER_STATUS_POWER_SAVE != 0 { vs := cdd.VendorStateItem{ State: cdd.VendorStateInfo, DescriptionLocalized: cdd.NewLocalizedString("power save mode"), } state.VendorState.Item = append(state.VendorState.Item, vs) } if len(state.VendorState.Item) == 0 { state.VendorState = nil } return &state }
func (vs *VariableSet) GetOutputBins() (*[]cdd.OutputBinUnit, *cdd.OutputBinState, bool) { capacitiesMax := vs.GetSubtree(PrinterOutputMaxCapacity).Variables() capacitiesRemaining := vs.GetSubtree(PrinterOutputRemainingCapacity).Variables() statuses := vs.GetSubtree(PrinterOutputStatus).Variables() names := vs.GetSubtree(PrinterOutputName).Variables() if len(names) < 1 || len(names) != len(capacitiesMax) || len(names) != len(capacitiesRemaining) || len(names) != len(statuses) { return nil, nil, false } outputBinUnits := make([]cdd.OutputBinUnit, 0, len(names)) outputBinState := cdd.OutputBinState{make([]cdd.OutputBinStateItem, 0, len(names))} for i := 0; i < len(names); i++ { index := cdd.NewSchizophrenicInt64(statuses[i].Name[len(statuses[i].Name)-1]) status, err := strconv.ParseUint(statuses[i].Value, 10, 8) if err != nil { return nil, nil, false } state := cdd.OutputBinStateOK stateMessage := []string{} if (status & PrinterSubUnitUnavailable) != 0 { stateMessage = append(stateMessage, "unavailable") switch status & 7 { case PrinterSubUnitUnavailableAndOnRequest: stateMessage = append(stateMessage, "on request") case PrinterSubUnitUnavailableBecauseBroken: state = cdd.OutputBinStateFailure stateMessage = append(stateMessage, "broken") case PrinterSubUnitUnknown: state = cdd.OutputBinStateFailure stateMessage = append(stateMessage, "reason unknown") } } if (status & PrinterSubUnitNonCritical) != 0 { stateMessage = append(stateMessage, "non-critical") } if (status & PrinterSubUnitCritical) != 0 { state = cdd.OutputBinStateFailure stateMessage = append(stateMessage, "critical") } if (status & PrinterSubUnitOffline) != 0 { state = cdd.OutputBinStateOff stateMessage = append(stateMessage, "offline") } outputState := cdd.OutputBinStateItem{ VendorID: index.String(), State: state, VendorMessage: strings.Join(stateMessage, ","), } capacityMax, err := strconv.ParseInt(capacitiesMax[i].Value, 10, 32) if err != nil { return nil, nil, false } capacityRemaining, err := strconv.ParseInt(capacitiesRemaining[i].Value, 10, 32) if err != nil { return nil, nil, false } if capacityMax >= 0 && capacityRemaining >= 0 { if capacityRemaining == 0 && state == cdd.OutputBinStateOK { outputState.State = cdd.OutputBinStateFull } levelPercent := 100 - int32(100*capacityRemaining/capacityMax) outputState.LevelPercent = &levelPercent } outputBinState.Item = append(outputBinState.Item, outputState) outputBinUnits = append(outputBinUnits, cdd.OutputBinUnit{ VendorID: index.String(), Type: cdd.OutputBinUnitCustom, Index: index, CustomDisplayNameLocalized: cdd.NewLocalizedString(names[i].Value), }) } return &outputBinUnits, &outputBinState, true }
func (vs *VariableSet) GetInputTrays() (*[]cdd.InputTrayUnit, *cdd.InputTrayState, bool) { levelsMax := vs.GetSubtree(PrinterInputMaxCapacity).Variables() levelsCurrent := vs.GetSubtree(PrinterInputCurrentLevel).Variables() statuses := vs.GetSubtree(PrinterInputStatus).Variables() names := vs.GetSubtree(PrinterInputName).Variables() if len(levelsMax) < 1 || len(levelsMax) != len(levelsCurrent) || len(levelsMax) != len(statuses) || len(levelsMax) != len(names) { return nil, nil, false } inputTrayUnits := make([]cdd.InputTrayUnit, 0, len(statuses)) inputTrayState := cdd.InputTrayState{make([]cdd.InputTrayStateItem, 0, len(statuses))} for i := 0; i < len(statuses); i++ { index := cdd.NewSchizophrenicInt64(statuses[i].Name[len(statuses[i].Name)-1]) status, err := strconv.ParseUint(statuses[i].Value, 10, 8) if err != nil { return nil, nil, false } state := cdd.InputTrayStateOK stateMessage := []string{} if (status & PrinterSubUnitUnavailable) != 0 { stateMessage = append(stateMessage, "unavailable") switch status & 7 { case PrinterSubUnitUnavailableAndOnRequest: stateMessage = append(stateMessage, "on request") case PrinterSubUnitUnavailableBecauseBroken: state = cdd.InputTrayStateFailure stateMessage = append(stateMessage, "broken") case PrinterSubUnitUnknown: state = cdd.InputTrayStateFailure stateMessage = append(stateMessage, "reason unknown") } } if (status & PrinterSubUnitNonCritical) != 0 { stateMessage = append(stateMessage, "non-critical") } if (status & PrinterSubUnitCritical) != 0 { state = cdd.InputTrayStateFailure stateMessage = append(stateMessage, "critical") } if (status & PrinterSubUnitOffline) != 0 { state = cdd.InputTrayStateOff stateMessage = append(stateMessage, "offline") } inputState := cdd.InputTrayStateItem{ VendorID: index.String(), State: state, VendorMessage: strings.Join(stateMessage, ", "), } levelMax, err := strconv.ParseInt(levelsMax[i].Value, 10, 32) if err != nil { return nil, nil, false } levelCurrent, err := strconv.ParseInt(levelsCurrent[i].Value, 10, 32) if err != nil { return nil, nil, false } if levelMax >= 0 && levelCurrent >= 0 { if levelCurrent == 0 && state == cdd.InputTrayStateOK { inputState.State = cdd.InputTrayStateEmpty } var levelPercent int32 if levelMax > 0 { levelPercent = int32(100 * levelCurrent / levelMax) } inputState.LevelPercent = &levelPercent } if inputState.State == cdd.InputTrayStateOK || inputState.State == cdd.InputTrayStateEmpty { // No message necessary when state says everything. inputState.VendorMessage = "" } inputTrayState.Item = append(inputTrayState.Item, inputState) inputTrayUnits = append(inputTrayUnits, cdd.InputTrayUnit{ VendorID: index.String(), Type: cdd.InputTrayUnitCustom, Index: index, CustomDisplayNameLocalized: cdd.NewLocalizedString(names[i].Value), }) } return &inputTrayUnits, &inputTrayState, true }
func TestConvertMarkers(t *testing.T) { log.SetLevel(log.ERROR) m, ms := convertMarkers(nil) if m != nil { t.Logf("expected nil") t.Fail() } if ms != nil { t.Logf("expected nil") t.Fail() } pt := map[string][]string{} m, ms = convertMarkers(pt) if m != nil { t.Logf("expected nil") t.Fail() } if ms != nil { t.Logf("expected nil") t.Fail() } pt = map[string][]string{ attrMarkerNames: []string{"black", "black", "black"}, attrMarkerTypes: []string{"toner", "toner", "ink"}, attrMarkerLevels: []string{"10", "11", "12"}, } m, ms = convertMarkers(pt) if m != nil { t.Logf("expected nil") t.Fail() } if ms != nil { t.Logf("expected nil") t.Fail() } pt = map[string][]string{ attrMarkerNames: []string{"black", "color"}, attrMarkerTypes: []string{"toner", "toner", "ink"}, attrMarkerLevels: []string{"10", "11", "12"}, } m, ms = convertMarkers(pt) if m != nil { t.Logf("expected nil") t.Fail() } if ms != nil { t.Logf("expected nil") t.Fail() } pt = map[string][]string{ attrMarkerNames: []string{"black", "color", "rainbow"}, attrMarkerTypes: []string{"toner", "toner"}, attrMarkerLevels: []string{"10", "11", "12"}, } m, ms = convertMarkers(pt) if m != nil { t.Logf("expected nil") t.Fail() } if ms != nil { t.Logf("expected nil") t.Fail() } pt = map[string][]string{ attrMarkerNames: []string{"black", " Reorder Part #12345", "color", "rainbow", "zebra", "pony"}, attrMarkerTypes: []string{"toner", "toner", "ink", "staples", "water", " Reorder H2O"}, attrMarkerLevels: []string{"10", "11", "12", "208", "13"}, } mExpected := &[]cdd.Marker{ cdd.Marker{ VendorID: "black, Reorder Part #12345", Type: cdd.MarkerToner, Color: &cdd.MarkerColor{Type: cdd.MarkerColorBlack}, }, cdd.Marker{ VendorID: "color", Type: cdd.MarkerToner, Color: &cdd.MarkerColor{Type: cdd.MarkerColorColor}, }, cdd.Marker{ VendorID: "rainbow", Type: cdd.MarkerInk, Color: &cdd.MarkerColor{ Type: cdd.MarkerColorCustom, CustomDisplayNameLocalized: cdd.NewLocalizedString("rainbow"), }, }, cdd.Marker{ VendorID: "zebra", Type: cdd.MarkerStaples, }, } ten, eleven, twelve, eighty := int32(10), int32(11), int32(12), int32(80) msExpected := &cdd.MarkerState{ Item: []cdd.MarkerStateItem{ cdd.MarkerStateItem{ VendorID: "black, Reorder Part #12345", State: cdd.MarkerStateExhausted, LevelPercent: &ten, }, cdd.MarkerStateItem{ VendorID: "color", State: cdd.MarkerStateOK, LevelPercent: &eleven, }, cdd.MarkerStateItem{ VendorID: "rainbow", State: cdd.MarkerStateOK, LevelPercent: &twelve, }, cdd.MarkerStateItem{ VendorID: "zebra", State: cdd.MarkerStateOK, LevelPercent: &eighty, }, }, } m, ms = convertMarkers(pt) if !reflect.DeepEqual(mExpected, m) { e, _ := json.Marshal(mExpected) f, _ := json.Marshal(m) t.Logf("expected\n %s\ngot\n %s", e, f) t.Fail() } if !reflect.DeepEqual(msExpected, ms) { e, _ := json.Marshal(msExpected) f, _ := json.Marshal(ms) t.Logf("expected\n %s\ngot\n %s", e, f) t.Fail() } pt = map[string][]string{ attrMarkerNames: []string{"black", "color", "rainbow", "zebra", "pony"}, attrMarkerTypes: []string{"toner", "toner", "ink", "staples", "water"}, attrMarkerLevels: []string{"10", "11", "12", "208", "13"}, } mExpected = &[]cdd.Marker{ cdd.Marker{ VendorID: "black", Type: cdd.MarkerToner, Color: &cdd.MarkerColor{Type: cdd.MarkerColorBlack}, }, cdd.Marker{ VendorID: "color", Type: cdd.MarkerToner, Color: &cdd.MarkerColor{Type: cdd.MarkerColorColor}, }, cdd.Marker{ VendorID: "rainbow", Type: cdd.MarkerInk, Color: &cdd.MarkerColor{ Type: cdd.MarkerColorCustom, CustomDisplayNameLocalized: cdd.NewLocalizedString("rainbow"), }, }, cdd.Marker{ VendorID: "zebra", Type: cdd.MarkerStaples, }, } msExpected = &cdd.MarkerState{ Item: []cdd.MarkerStateItem{ cdd.MarkerStateItem{ VendorID: "black", State: cdd.MarkerStateExhausted, LevelPercent: &ten, }, cdd.MarkerStateItem{ VendorID: "color", State: cdd.MarkerStateOK, LevelPercent: &eleven, }, cdd.MarkerStateItem{ VendorID: "rainbow", State: cdd.MarkerStateOK, LevelPercent: &twelve, }, cdd.MarkerStateItem{ VendorID: "zebra", State: cdd.MarkerStateOK, LevelPercent: &eighty, }, }, } m, ms = convertMarkers(pt) if !reflect.DeepEqual(mExpected, m) { e, _ := json.Marshal(mExpected) f, _ := json.Marshal(m) t.Logf("expected\n %s\ngot\n %s", e, f) t.Fail() } if !reflect.DeepEqual(msExpected, ms) { e, _ := json.Marshal(msExpected) f, _ := json.Marshal(ms) t.Logf("expected\n %s\ngot\n %s", e, f) t.Fail() } }
func (vs *VariableSet) GetMarkers() (*[]cdd.Marker, *cdd.MarkerState, *cdd.VendorState, bool) { classes := vs.GetSubtree(PrinterMarkerSuppliesClass).Variables() types := vs.GetSubtree(PrinterMarkerSuppliesType).Variables() descriptions := vs.GetSubtree(PrinterMarkerSuppliesDescription).Variables() units := vs.GetSubtree(PrinterMarkerSuppliesSupplyUnit).Variables() levelsMax := vs.GetSubtree(PrinterMarkerSuppliesMaxCapacity).Variables() levelsCurrent := vs.GetSubtree(PrinterMarkerSuppliesLevel).Variables() colors := vs.GetSubtree(PrinterMarkerColorantValue).Variables() if len(classes) < 1 || len(classes) != len(types) || len(classes) != len(descriptions) || len(classes) != len(units) || len(classes) != len(levelsMax) || len(classes) != len(levelsCurrent) || len(classes) != len(colors) { return nil, nil, nil, false } markers := []cdd.Marker{} markerState := cdd.MarkerState{} vendorState := cdd.VendorState{} for i := 0; i < len(classes); i++ { index := int64(classes[i].Name[len(classes[i].Name)-1]) levelMax, err := strconv.ParseInt(levelsMax[i].Value, 10, 32) if err != nil { return nil, nil, nil, false } levelCurrent, err := strconv.ParseInt(levelsCurrent[i].Value, 10, 32) if err != nil { return nil, nil, nil, false } var levelPercent int32 if levelMax > 0 { levelPercent = int32(100 * levelCurrent / levelMax) } if markerType, exists := PrinterMarkerSuppliesTypeToGCP[types[i].Value]; exists && markerType != "" { // GCP calls this a Marker. state := cdd.MarkerStateOK markerStateItem := cdd.MarkerStateItem{ VendorID: strconv.FormatInt(index, 10), State: state, } if levelMax >= 0 && levelCurrent >= 0 { if levelPercent <= 10 { markerStateItem.State = cdd.MarkerStateExhausted } markerStateItem.LevelPercent = &levelPercent if unit, exists := PrinterMarkerSuppliesSupplyUnitTC[units[i].Value]; exists && unit == "sheets" { levelPages := int32(levelCurrent) markerStateItem.LevelPages = &levelPages } } rawColor := strings.Replace(strings.Replace(strings.ToLower(colors[i].Value), " ", "", -1), "-", "", -1) colorType := cdd.MarkerColorCustom for k, v := range snmpMarkerColorToGCP { if strings.HasPrefix(rawColor, k) { colorType = v break } } markerColor := cdd.MarkerColor{Type: colorType} if colorType == cdd.MarkerColorCustom { name := colors[i].Value name = strings.TrimSuffix(name, " Cartridge") name = strings.TrimSuffix(name, " cartridge") name = strings.TrimSuffix(name, " Ribbon") name = strings.TrimSuffix(name, " ribbon") name = strings.TrimSuffix(name, " Toner") name = strings.TrimSuffix(name, " toner") name = strings.TrimSuffix(name, " Ink") name = strings.TrimSuffix(name, " ink") name = strings.Replace(name, "-", " ", -1) markerColor.CustomDisplayNameLocalized = cdd.NewLocalizedString(name) } marker := cdd.Marker{ VendorID: strconv.FormatInt(index, 10), Type: markerType, Color: &markerColor, } markerState.Item = append(markerState.Item, markerStateItem) markers = append(markers, marker) } else { var state cdd.VendorStateType if levelPercent <= 1 { state = cdd.VendorStateError } else if levelPercent <= 10 { state = cdd.VendorStateWarning } else { state = cdd.VendorStateInfo } // GCP doesn't call this a Marker, so treat it like a VendorState. class := PrinterMarkerSuppliesClassTC(classes[i].Value) var description string if class == PrinterMarkerSuppliesClassFilled { levelPercent = 100 - levelPercent description = fmt.Sprintf("%s at %d%%", descriptions[i].Value, levelPercent) if levelPercent == 100 { description = fmt.Sprintf("%s full", descriptions[i].Value) } } else { // class == PrinterMarkerSuppliesClassConsumed description = fmt.Sprintf("%s at %d%%", descriptions[i].Value, levelPercent) if levelPercent == 0 { description = fmt.Sprintf("%s empty", descriptions[i].Value) } } vendorState.Item = append(vendorState.Item, cdd.VendorStateItem{ State: state, DescriptionLocalized: cdd.NewLocalizedString(description), }) } } return &markers, &markerState, &vendorState, true }
"os" "sync" "unsafe" "github.com/google/cups-connector/cdd" ) var numberUpCapability = cdd.VendorCapability{ ID: "number-up", Type: cdd.VendorCapabilitySelect, SelectCap: &cdd.SelectCapability{ Option: []cdd.SelectCapabilityOption{ cdd.SelectCapabilityOption{ Value: "1", IsDefault: true, DisplayNameLocalized: cdd.NewLocalizedString("1"), }, cdd.SelectCapabilityOption{ Value: "2", IsDefault: false, DisplayNameLocalized: cdd.NewLocalizedString("2"), }, cdd.SelectCapabilityOption{ Value: "4", IsDefault: false, DisplayNameLocalized: cdd.NewLocalizedString("4"), }, cdd.SelectCapabilityOption{ Value: "6", IsDefault: false, DisplayNameLocalized: cdd.NewLocalizedString("6"),
if err != nil { return nil } } return &cdd.Copies{ Default: int32(def), Max: int32(max), } } var colorByKeyword = map[string]cdd.ColorOption{ "auto": cdd.ColorOption{ VendorID: "auto", Type: cdd.ColorTypeAuto, CustomDisplayNameLocalized: cdd.NewLocalizedString("Auto"), }, "color": cdd.ColorOption{ VendorID: "color", Type: cdd.ColorTypeStandardColor, CustomDisplayNameLocalized: cdd.NewLocalizedString("Color"), }, "monochrome": cdd.ColorOption{ VendorID: "monochrome", Type: cdd.ColorTypeStandardMonochrome, CustomDisplayNameLocalized: cdd.NewLocalizedString("Monochrome"), }, } func convertColorAttrs(printerTags map[string][]string) *cdd.Color { colorSupported, exists := printerTags[attrPrintColorModeSupported]
// convertMarkers converts CUPS marker-(names|types|levels) to *[]cdd.Marker and *cdd.MarkerState. // // Normalizes marker type: toner(Cartridge|-cartridge) => toner, // ink(Cartridge|-cartridge|Ribbon|-ribbon) => ink func convertMarkers(names, types, levels []string) (*[]cdd.Marker, *cdd.MarkerState) { if len(names) == 0 || len(types) == 0 || len(levels) == 0 { return nil, nil } if len(names) != len(types) || len(types) != len(levels) { glog.Warningf("Received badly-formatted markers from CUPS: %s, %s, %s", strings.Join(names, ";"), strings.Join(types, ";"), strings.Join(levels, ";")) return nil, nil } markers := make([]cdd.Marker, 0, len(names)) states := cdd.MarkerState{make([]cdd.MarkerStateItem, 0, len(names))} for i := 0; i < len(names); i++ { if len(names[i]) == 0 { return nil, nil } var markerType cdd.MarkerType switch strings.ToLower(types[i]) { case "toner", "tonercartridge", "toner-cartridge": markerType = cdd.MarkerToner case "ink", "inkcartridge", "ink-cartridge", "ink-ribbon", "inkribbon": markerType = cdd.MarkerInk case "staples": markerType = cdd.MarkerStaples default: continue } nameStripped := strings.Replace(strings.Replace(strings.ToLower(names[i]), " ", "", -1), "-", "", -1) colorType := cdd.MarkerColorCustom for k, v := range cupsMarkerNameToGCP { if strings.HasPrefix(nameStripped, k) { colorType = v break } } color := cdd.MarkerColor{Type: colorType} if colorType == cdd.MarkerColorCustom { name := names[i] name = strings.TrimSuffix(name, " Cartridge") name = strings.TrimSuffix(name, " cartridge") name = strings.TrimSuffix(name, " Ribbon") name = strings.TrimSuffix(name, " ribbon") name = strings.TrimSuffix(name, " Toner") name = strings.TrimSuffix(name, " toner") name = strings.TrimSuffix(name, " Ink") name = strings.TrimSuffix(name, " ink") name = strings.Replace(name, "-", " ", -1) color.CustomDisplayNameLocalized = cdd.NewLocalizedString(name) } marker := cdd.Marker{ VendorID: names[i], Type: markerType, Color: &color, } level, err := strconv.ParseInt(levels[i], 10, 32) if err != nil { glog.Warningf("Failed to parse CUPS marker state %s=%s: %s", names[i], levels[i], err) return nil, nil } if level > 100 { // Lop off extra (proprietary?) bits. level = level & 0x7f } if level < 0 || level > 100 { return nil, nil } var state cdd.MarkerStateType if level > 10 { state = cdd.MarkerStateOK } else { state = cdd.MarkerStateExhausted } level32 := int32(level) markerState := cdd.MarkerStateItem{ VendorID: names[i], State: state, LevelPercent: &level32, } markers = append(markers, marker) states.Item = append(states.Item, markerState) } return &markers, &states }
// tagsToPrinter converts a map of tags to a Printer. func tagsToPrinter(printerTags map[string][]string, systemTags map[string]string, infoToDisplayName bool) lib.Printer { tags := make(map[string]string) for k, v := range printerTags { tags[k] = strings.Join(v, ",") } for k, v := range systemTags { tags[k] = v } var name string if n, ok := printerTags[attrPrinterName]; ok { name = n[0] } var uuid string if u, ok := printerTags[attrPrinterUUID]; ok { uuid = u[0] } state := cdd.PrinterStateSection{} if s, ok := printerTags[attrPrinterState]; ok { switch s[0] { case "3": state.State = cdd.CloudDeviceStateIdle case "4": state.State = cdd.CloudDeviceStateProcessing case "5": state.State = cdd.CloudDeviceStateStopped default: state.State = cdd.CloudDeviceStateIdle } } if reasons, ok := printerTags[attrPrinterStateReasons]; ok && len(reasons) > 0 { sort.Strings(reasons) state.VendorState = &cdd.VendorState{Item: make([]cdd.VendorStateItem, len(reasons))} for i, reason := range reasons { vendorState := cdd.VendorStateItem{DescriptionLocalized: cdd.NewLocalizedString(reason)} if strings.HasSuffix(reason, "-error") { vendorState.State = cdd.VendorStateError } else if strings.HasSuffix(reason, "-warning") { vendorState.State = cdd.VendorStateWarning } else if strings.HasSuffix(reason, "-report") { vendorState.State = cdd.VendorStateInfo } else { vendorState.State = cdd.VendorStateInfo } state.VendorState.Item[i] = vendorState } } markers, markerState := convertMarkers(printerTags[attrMarkerNames], printerTags[attrMarkerTypes], printerTags[attrMarkerLevels]) state.MarkerState = markerState description := cdd.PrinterDescriptionSection{Marker: markers} p := lib.Printer{ Name: name, UUID: uuid, State: &state, Description: &description, Tags: tags, } p.SetTagshash() if pi, ok := printerTags[attrPrinterInfo]; ok && infoToDisplayName { p.DefaultDisplayName = pi[0] } return p }
func convertMediaSize(printerName, portName string, devMode *DevMode) (*cdd.MediaSize, error) { defSize, defSizeOK := devMode.GetPaperSize() defLength, defLengthOK := devMode.GetPaperLength() defWidth, defWidthOK := devMode.GetPaperWidth() names, err := DeviceCapabilitiesStrings(printerName, portName, DC_PAPERNAMES, 64*2) if err != nil { return nil, err } papers, err := DeviceCapabilitiesUint16Array(printerName, portName, DC_PAPERS) if err != nil { return nil, err } sizes, err := DeviceCapabilitiesInt32Pairs(printerName, portName, DC_PAPERSIZE) if err != nil { return nil, err } if len(names) != len(papers) || len(names) != len(sizes)/2 { return nil, nil } ms := cdd.MediaSize{ Option: make([]cdd.MediaSizeOption, 0, len(names)), } var foundDef bool for i := range names { if names[i] == "" { continue } // Convert from tenths-of-mm to micrometers width, length := sizes[2*i]*100, sizes[2*i+1]*100 var def bool if !foundDef { if defSizeOK { if uint16(defSize) == papers[i] { def = true foundDef = true } } else if defLengthOK && int32(defLength) == length && defWidthOK && int32(defWidth) == width { def = true foundDef = true } } o := cdd.MediaSizeOption{ Name: cdd.MediaSizeCustom, WidthMicrons: width, HeightMicrons: length, IsDefault: def, VendorID: strconv.FormatUint(uint64(papers[i]), 10), CustomDisplayNameLocalized: cdd.NewLocalizedString(names[i]), } ms.Option = append(ms.Option, o) } if !foundDef && len(ms.Option) > 0 { ms.Option[0].IsDefault = true } return &ms, nil }
func TestTrMediaSize(t *testing.T) { ppd := `*PPD-Adobe: "4.3" *OpenUI *PageSize: PickOne *DefaultPageSize: Letter *PageSize A3/A3: "" *PageSize ISOB5/B5 - ISO: "" *PageSize B5/B5 - JIS: "" *PageSize Letter/Letter: "" *PageSize HalfLetter/5.5x8.5: "" *CloseUI: *PageSize` expected := &cdd.PrinterDescriptionSection{ MediaSize: &cdd.MediaSize{ Option: []cdd.MediaSizeOption{ cdd.MediaSizeOption{cdd.MediaSizeISOA3, mmToMicrons(297), mmToMicrons(420), false, false, "", "A3", cdd.NewLocalizedString("A3")}, cdd.MediaSizeOption{cdd.MediaSizeISOB5, mmToMicrons(176), mmToMicrons(250), false, false, "", "ISOB5", cdd.NewLocalizedString("B5 (ISO)")}, cdd.MediaSizeOption{cdd.MediaSizeJISB5, mmToMicrons(182), mmToMicrons(257), false, false, "", "B5", cdd.NewLocalizedString("B5 (JIS)")}, cdd.MediaSizeOption{cdd.MediaSizeNALetter, inchesToMicrons(8.5), inchesToMicrons(11), false, true, "", "Letter", cdd.NewLocalizedString("Letter")}, cdd.MediaSizeOption{cdd.MediaSizeCustom, inchesToMicrons(5.5), inchesToMicrons(8.5), false, false, "", "HalfLetter", cdd.NewLocalizedString("5.5x8.5")}, }, }, } translationTest(t, ppd, expected) }
// GetPrinters gets all Windows printers found on this computer. func (ws *WinSpool) GetPrinters() ([]lib.Printer, error) { pi2s, err := EnumPrinters2() if err != nil { return nil, err } printers := make([]lib.Printer, 0, len(pi2s)) for _, pi2 := range pi2s { printerName := pi2.GetPrinterName() portName := pi2.GetPortName() devMode := pi2.GetDevMode() manufacturer, model := getManModel(pi2.GetDriverName()) printer := lib.Printer{ Name: printerName, DefaultDisplayName: ws.displayNamePrefix + printerName, UUID: printerName, // TODO: Add something unique from host. Manufacturer: manufacturer, Model: model, State: convertPrinterState(pi2.GetStatus()), Description: &cdd.PrinterDescriptionSection{}, Tags: map[string]string{ "printer-location": pi2.GetLocation(), }, } // Advertise color based on default value, which should be a solid indicator // of color-ness, because the source of this devMode object is EnumPrinters. if def, ok := devMode.GetColor(); ok { if def == DMCOLOR_COLOR { printer.Description.Color = &cdd.Color{ Option: []cdd.ColorOption{ cdd.ColorOption{ VendorID: strconv.FormatInt(int64(DMCOLOR_COLOR), 10), Type: cdd.ColorTypeStandardColor, IsDefault: true, CustomDisplayNameLocalized: cdd.NewLocalizedString("Color"), }, cdd.ColorOption{ VendorID: strconv.FormatInt(int64(DMCOLOR_MONOCHROME), 10), Type: cdd.ColorTypeStandardMonochrome, IsDefault: false, CustomDisplayNameLocalized: cdd.NewLocalizedString("Monochrome"), }, }, } } else if def == DMCOLOR_MONOCHROME { printer.Description.Color = &cdd.Color{ Option: []cdd.ColorOption{ cdd.ColorOption{ VendorID: strconv.FormatInt(int64(DMCOLOR_MONOCHROME), 10), Type: cdd.ColorTypeStandardMonochrome, IsDefault: true, CustomDisplayNameLocalized: cdd.NewLocalizedString("Monochrome"), }, }, } } } if def, ok := devMode.GetDuplex(); ok { duplex, err := DeviceCapabilitiesInt32(printerName, portName, DC_DUPLEX) if err != nil { return nil, err } if duplex == 1 { printer.Description.Duplex = &cdd.Duplex{ Option: []cdd.DuplexOption{ cdd.DuplexOption{ Type: cdd.DuplexNoDuplex, IsDefault: def == DMDUP_SIMPLEX, }, cdd.DuplexOption{ Type: cdd.DuplexLongEdge, IsDefault: def == DMDUP_VERTICAL, }, cdd.DuplexOption{ Type: cdd.DuplexShortEdge, IsDefault: def == DMDUP_HORIZONTAL, }, }, } } } if def, ok := devMode.GetOrientation(); ok { orientation, err := DeviceCapabilitiesInt32(printerName, portName, DC_ORIENTATION) if err != nil { return nil, err } if orientation == 90 || orientation == 270 { printer.Description.PageOrientation = &cdd.PageOrientation{ Option: []cdd.PageOrientationOption{ cdd.PageOrientationOption{ Type: cdd.PageOrientationPortrait, IsDefault: def == DMORIENT_PORTRAIT, }, cdd.PageOrientationOption{ Type: cdd.PageOrientationLandscape, IsDefault: def == DMORIENT_LANDSCAPE, }, }, } } } if def, ok := devMode.GetCopies(); ok { copies, err := DeviceCapabilitiesInt32(printerName, portName, DC_COPIES) if err != nil { return nil, err } if copies > 1 { printer.Description.Copies = &cdd.Copies{ Default: int32(def), Max: copies, } } } printer.Description.MediaSize, err = convertMediaSize(printerName, portName, devMode) if err != nil { return nil, err } if def, ok := devMode.GetCollate(); ok { collate, err := DeviceCapabilitiesInt32(printerName, portName, DC_COLLATE) if err != nil { return nil, err } if collate == 1 { printer.Description.Collate = &cdd.Collate{ Default: def == DMCOLLATE_TRUE, } } } printers = append(printers, printer) } printers = ws.filterBlacklistPrinters(printers) printers = addStaticDescriptionToPrinters(printers) printers = ws.addSystemTagsToPrinters(printers) return printers, nil }