// Register calls google.com/cloudprint/register to register a GCP printer. // // Sets the GCPID field in the printer arg. func (gcp *GoogleCloudPrint) Register(printer *lib.Printer) error { capabilities, err := marshalCapabilities(printer.Description) if err != nil { return err } semanticState, err := json.Marshal(cdd.CloudDeviceState{Printer: printer.State}) if err != nil { return err } form := url.Values{} form.Set("name", printer.Name) form.Set("default_display_name", printer.DefaultDisplayName) form.Set("proxy", gcp.proxyName) form.Set("uuid", printer.UUID) form.Set("manufacturer", printer.Manufacturer) form.Set("model", printer.Model) form.Set("gcp_version", printer.GCPVersion) form.Set("setup_url", lib.ConnectorHomeURL) form.Set("support_url", lib.ConnectorHomeURL) form.Set("update_url", lib.ConnectorHomeURL) form.Set("firmware", printer.ConnectorVersion) form.Set("semantic_state", string(semanticState)) form.Set("use_cdd", "true") form.Set("capabilities", capabilities) form.Set("capsHash", printer.CapsHash) sortedKeys := make([]string, 0, len(printer.Tags)) for key := range printer.Tags { sortedKeys = append(sortedKeys, key) } sort.Strings(sortedKeys) for _, key := range sortedKeys { form.Add("tag", fmt.Sprintf("%s%s=%s", gcpTagPrefix, key, printer.Tags[key])) } responseBody, _, _, err := postWithRetry(gcp.robotClient, gcp.baseURL+"register", form) if err != nil { return err } var registerData struct { Printers []struct { ID string } } if err = json.Unmarshal(responseBody, ®isterData); err != nil { return err } printer.GCPID = registerData.Printers[0].ID return nil }
func TestTranslateTicket(t *testing.T) { printer := lib.Printer{} expected := map[string]string{} o, err := translateTicket(&printer, nil) if err != nil { t.Logf("did not expect error %s", err) t.Fail() } if !reflect.DeepEqual(o, expected) { t.Logf("expected %+v, got %+v", expected, o) t.Fail() } ticket := cdd.CloudJobTicket{} o, err = translateTicket(&printer, &ticket) if err != nil { t.Logf("did not expect error %s", err) t.Fail() } if !reflect.DeepEqual(o, expected) { t.Logf("expected %+v, got %+v", expected, o) t.Fail() } printer = lib.Printer{ Description: &cdd.PrinterDescriptionSection{ Color: &cdd.Color{ Option: []cdd.ColorOption{ cdd.ColorOption{ VendorID: "zebra-stripes", Type: cdd.ColorTypeCustomMonochrome, }, }, VendorKey: "ColorModel", }, Duplex: &cdd.Duplex{ Option: []cdd.DuplexOption{ cdd.DuplexOption{ Type: cdd.DuplexNoDuplex, VendorID: "None", }, }, VendorKey: "Duplex", }, PageOrientation: &cdd.PageOrientation{}, Copies: &cdd.Copies{}, Margins: &cdd.Margins{}, DPI: &cdd.DPI{ Option: []cdd.DPIOption{ cdd.DPIOption{ HorizontalDPI: 100, VerticalDPI: 100, VendorID: "q", }, }, }, FitToPage: &cdd.FitToPage{}, MediaSize: &cdd.MediaSize{}, Collate: &cdd.Collate{}, ReverseOrder: &cdd.ReverseOrder{}, }, } ticket.Print = cdd.PrintTicketSection{ VendorTicketItem: []cdd.VendorTicketItem{ cdd.VendorTicketItem{"number-up", "a"}, cdd.VendorTicketItem{"a:b/c:d/e", "f"}, }, Color: &cdd.ColorTicketItem{VendorID: "zebra-stripes", Type: cdd.ColorTypeCustomMonochrome}, Duplex: &cdd.DuplexTicketItem{Type: cdd.DuplexNoDuplex}, PageOrientation: &cdd.PageOrientationTicketItem{Type: cdd.PageOrientationAuto}, Copies: &cdd.CopiesTicketItem{Copies: 2}, Margins: &cdd.MarginsTicketItem{100000, 100000, 100000, 100000}, DPI: &cdd.DPITicketItem{100, 100, "q"}, FitToPage: &cdd.FitToPageTicketItem{cdd.FitToPageNoFitting}, MediaSize: &cdd.MediaSizeTicketItem{100000, 100000, false, "r"}, Collate: &cdd.CollateTicketItem{false}, ReverseOrder: &cdd.ReverseOrderTicketItem{false}, } expected = map[string]string{ "number-up": "a", "a": "b", "c": "d", "e": "f", "ColorModel": "zebra-stripes", "Duplex": "None", "copies": "2", "media-left-margin": micronsToPoints(100000), "media-right-margin": micronsToPoints(100000), "media-top-margin": micronsToPoints(100000), "media-bottom-margin": micronsToPoints(100000), "Resolution": "q", "fit-to-page": "false", "PageSize": "r", "collate": "false", "outputorder": "normal", } o, err = translateTicket(&printer, &ticket) if err != nil { t.Logf("did not expect error %s", err) t.Fail() } if !reflect.DeepEqual(o, expected) { eSorted := make([]string, 0, len(expected)) for k := range expected { eSorted = append(eSorted, fmt.Sprintf("%s:%s", k, expected[k])) } sort.Strings(eSorted) oSorted := make([]string, 0, len(o)) for k := range o { oSorted = append(oSorted, fmt.Sprintf("%s:%s", k, o[k])) } sort.Strings(oSorted) t.Logf("expected\n %+v\ngot\n %+v", strings.Join(eSorted, ","), strings.Join(oSorted, ",")) t.Fail() } printer.Description = &cdd.PrinterDescriptionSection{ Color: &cdd.Color{ Option: []cdd.ColorOption{ cdd.ColorOption{ VendorID: "color", Type: cdd.ColorTypeStandardColor, }, }, VendorKey: "print-color-mode", }, Duplex: &cdd.Duplex{ Option: []cdd.DuplexOption{ cdd.DuplexOption{ Type: cdd.DuplexLongEdge, VendorID: "Single", }, }, VendorKey: "KMDuplex", }, PageOrientation: &cdd.PageOrientation{}, DPI: &cdd.DPI{ Option: []cdd.DPIOption{ cdd.DPIOption{ HorizontalDPI: 100, VerticalDPI: 100, VendorID: "q", }, }, }, MediaSize: &cdd.MediaSize{}, } ticket.Print = cdd.PrintTicketSection{ Color: &cdd.ColorTicketItem{VendorID: "color", Type: cdd.ColorTypeStandardColor}, Duplex: &cdd.DuplexTicketItem{Type: cdd.DuplexLongEdge}, PageOrientation: &cdd.PageOrientationTicketItem{Type: cdd.PageOrientationLandscape}, DPI: &cdd.DPITicketItem{100, 100, ""}, MediaSize: &cdd.MediaSizeTicketItem{100000, 100000, false, ""}, } expected = map[string]string{ "print-color-mode": "color", "KMDuplex": "Single", "orientation-requested": "4", "Resolution": "q", "PageSize": "Custom.283x283", } o, err = translateTicket(&printer, &ticket) if err != nil { t.Logf("did not expect error %s", err) t.Fail() } if !reflect.DeepEqual(o, expected) { t.Logf("expected\n %+v\ngot\n %+v", expected, o) t.Fail() } printer.Description.Color = &cdd.Color{ Option: []cdd.ColorOption{ cdd.ColorOption{ VendorID: "Gray600x600dpi", Type: cdd.ColorTypeStandardColor, }, }, VendorKey: "CMAndResolution", } ticket.Print = cdd.PrintTicketSection{ Color: &cdd.ColorTicketItem{VendorID: "Gray600x600dpi", Type: cdd.ColorTypeStandardColor}, } expected = map[string]string{ "CMAndResolution": "Gray600x600dpi", } o, err = translateTicket(&printer, &ticket) if err != nil { t.Logf("did not expect error %s", err) t.Fail() } if !reflect.DeepEqual(o, expected) { t.Logf("expected\n %+v\ngot\n %+v", expected, o) t.Fail() } printer.Description.Color = &cdd.Color{ Option: []cdd.ColorOption{ cdd.ColorOption{ VendorID: "Color", Type: cdd.ColorTypeStandardColor, }, }, VendorKey: "SelectColor", } ticket.Print = cdd.PrintTicketSection{ Color: &cdd.ColorTicketItem{VendorID: "Color"}, } expected = map[string]string{ "SelectColor": "Color", } o, err = translateTicket(&printer, &ticket) if err != nil { t.Logf("did not expect error %s", err) t.Fail() } if !reflect.DeepEqual(o, expected) { t.Logf("expected\n %+v\ngot\n %+v", expected, o) t.Fail() } ticket.Print = cdd.PrintTicketSection{ Color: &cdd.ColorTicketItem{Type: cdd.ColorTypeStandardColor}, } o, err = translateTicket(&printer, &ticket) if err != nil { t.Logf("did not expect error %s", err) t.Fail() } if !reflect.DeepEqual(o, expected) { t.Logf("expected\n %+v\ngot\n %+v", expected, o) t.Fail() } }
// 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 }