Example #1
0
// 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
}
Example #2
0
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
}