From 35a1d1225128f57087b2fed6925c6cae3b649027 Mon Sep 17 00:00:00 2001 From: Anton Thomasson Date: Sat, 3 Feb 2024 19:12:03 +0100 Subject: [PATCH] Add IppPrinter info getters --- lib/ippprinter.cpp | 129 ++++++++++++++++++++++++++++++++++++++++++++ lib/ippprinter.h | 33 ++++++++++++ utils/ippclient.cpp | 80 +++++++++++++++++++++++---- 3 files changed, 233 insertions(+), 9 deletions(-) diff --git a/lib/ippprinter.cpp b/lib/ippprinter.cpp index 6d4b54d..b87ae94 100644 --- a/lib/ippprinter.cpp +++ b/lib/ippprinter.cpp @@ -1,5 +1,6 @@ #include "ippprinter.h" #include "curlrequester.h" +#include "stringsplit.h" IppPrinter::IppPrinter(std::string addr) : _addr(addr) { @@ -14,11 +15,139 @@ Error IppPrinter::refresh() return error; } +std::string IppPrinter::name() +{ + return _printerAttrs.get("printer-name"); +} + +std::string IppPrinter::uuid() +{ + return _printerAttrs.get("printer-uuid"); +} + +std::string IppPrinter::makeAndModel() +{ + return _printerAttrs.get("printer-make-and-model"); +} + +std::string IppPrinter::location() +{ + return _printerAttrs.get("printer-location"); +} + +int IppPrinter::state() +{ + return _printerAttrs.get("printer-state"); +} + +std::string IppPrinter::stateMessage() +{ + return _printerAttrs.get("printer-state-message"); +} + +List IppPrinter::stateReasons() +{ + return _printerAttrs.getList("printer-state-reasons"); +} + +List IppPrinter::ippVersionsSupported() +{ + return _printerAttrs.getList("ipp-versions-supported"); +} + +List IppPrinter::ippFeaturesSupported() +{ + return _printerAttrs.getList("ipp-features-supported"); +} + +int IppPrinter::pagesPerMinute() +{ + return _printerAttrs.get("pages-per-minute"); +} + +int IppPrinter::pagesPerMinuteColor() +{ + return _printerAttrs.get("pages-per-minute-color"); +} + bool IppPrinter::identifySupported() { return _printerAttrs.has("identify-actions-supported"); } +List IppPrinter::supplies() +{ + List supplies; + List names = _printerAttrs.getList("marker-names"); + List types = _printerAttrs.getList("marker-types"); + List colors = _printerAttrs.getList("marker-colors"); + List levels = _printerAttrs.getList("marker-levels"); + List lowLevels = _printerAttrs.getList("marker-low-levels"); + List highLevels = _printerAttrs.getList("marker-high-levels"); + + List::iterator name = names.begin(); + List::iterator type = types.begin(); + List::iterator color = colors.begin(); + List::iterator level = levels.begin(); + List::iterator lowLevel = lowLevels.begin(); + List::iterator highLevel = highLevels.begin(); + + for(; + name != names.end() && type != types.end() && color != colors.end() && + level != levels.end() && lowLevel != lowLevels.end() && highLevel != highLevels.end(); + name++, type++, color++, level++, lowLevel++, highLevel++) + { + List colorList; + for(std::string colorString : split_string(*color, "#")) + { + colorList.push_back("#" + colorString); + } + supplies.push_back({*name, *type, colorList, *level, *lowLevel, *highLevel}); + } + return supplies; +} + +List IppPrinter::firmware() +{ + List firmware; + List names = _printerAttrs.getList("printer-firmware-name"); + List versions = _printerAttrs.getList("printer-firmware-string-version"); + + for(List::iterator name = names.begin(), version = versions.begin(); + name != names.end() && version != versions.end(); + name++, version++) + { + firmware.push_back({*name, *version}); + } + return firmware; +} + +int IppPrinter::Supply::getPercent() const +{ + return (level*100.0)/highLevel; +} + +bool IppPrinter::Supply::isLow() const +{ + return level <= lowLevel; +} + +bool IppPrinter::Supply::operator==(const IppPrinter::Supply& other) const +{ + return other.name == name && + other.type == type && + other.colors == colors && + other.level == level && + other.lowLevel == lowLevel && + other.highLevel == highLevel; +} + +bool IppPrinter::Firmware::operator==(const IppPrinter::Firmware& other) const +{ + return other.name == name && + other.version == version; +} + Error IppPrinter::identify() { if(!identifySupported()) diff --git a/lib/ippprinter.h b/lib/ippprinter.h index c4e0975..d5b2d2e 100644 --- a/lib/ippprinter.h +++ b/lib/ippprinter.h @@ -10,6 +10,25 @@ class IppPrinter { public: + struct Supply + { + std::string name; + std::string type; + List colors; + int level = 0; + int lowLevel = 0; + int highLevel = 0; + int getPercent() const; + bool isLow() const; + bool operator==(const Supply& other) const; + }; + struct Firmware + { + std::string name; + std::string version; + bool operator==(const Firmware& other) const; + }; + IppPrinter() = delete; IppPrinter(std::string addr); Error refresh(); @@ -29,6 +48,20 @@ class IppPrinter return IppPrintJob(_printerAttrs); } + std::string name(); + std::string uuid(); + std::string makeAndModel(); + std::string location(); + int state(); + std::string stateMessage(); + List stateReasons(); + List ippVersionsSupported(); + List ippFeaturesSupported(); + int pagesPerMinute(); + int pagesPerMinuteColor(); + List supplies(); + List firmware(); + bool identifySupported(); Error identify(); diff --git a/utils/ippclient.cpp b/utils/ippclient.cpp index 4919b98..cbaf39a 100644 --- a/utils/ippclient.cpp +++ b/utils/ippclient.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include @@ -17,25 +18,60 @@ inline void print_error(std::string hint, std::string argHelp) std::cerr << hint << std::endl << std::endl << argHelp << std::endl << HELPTEXT << std::endl; } -template -std::ostream& operator<<(std::ostream& os, List bl) +std::string print_colors(const List& colors) { - if(bl.size() > 0) + std::stringstream res; + std::smatch match; + const std::regex colorRegex("^#([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$"); + for(const std::string& color : colors) { - os << "[" << bl.takeFront(); - for(T b : bl) + if(std::regex_match(color, match, colorRegex)) { - os << ", " << b; + unsigned long r = std::stoul(match[1], nullptr, 16); + unsigned long g = std::stoul(match[2], nullptr, 16); + unsigned long b = std::stoul(match[3], nullptr, 16); + res << "\x1b[48;2;" << r << ";" << g << ";" << b << "m" << " " << "\x1b[0m"; } - os << "]"; } - else + return res.str(); +} + +std::ostream& operator<<(std::ostream& os, List supplies) +{ + for(List::iterator supply = supplies.begin(); supply != supplies.end(); supply++) { - os << "[]"; + std::string color = print_colors(supply->colors); + os << "* " << supply->name << std::endl + << " " << ((color != "") ? color+" " : "") + << supply->getPercent() << "%" << (supply->isLow() ? "(low)" : "") + << " " << supply->type; + if(std::next(supply) != supplies.end()) + { + os << std::endl; + } + } + return os; +} + +std::ostream& operator<<(std::ostream& os, List firmwares) +{ + for(List::iterator firmware = firmwares.begin(); firmware != firmwares.end(); firmware++) + { + os << firmware->name << ": " << firmware->version; + if(std::next(firmware) != firmwares.end()) + { + os << std::endl; + } } return os; } +std::ostream& operator<<(std::ostream& os, List sl) +{ + os << join_string(sl, ", "); + return os; +} + std::string resolution_list(List l) { bool first = true; @@ -56,6 +92,15 @@ std::string resolution_list(List l) return ss.str(); } +template +void print_if_set(std::string title, T value) +{ + if(value != T()) + { + std::cout << title << std::endl << value << std::endl << std::endl; + } +} + template void set_or_fail(const O& opt, S& setting, V value, bool force) { @@ -168,6 +213,8 @@ int main(int argc, char** argv) SubArgGet args({{"get-attrs", {{&helpOpt, &verboseOpt}, {&addrArg}}}, + {"info", {{&helpOpt, &verboseOpt}, + {&addrArg}}}, {"identify", {{&helpOpt, &verboseOpt}, {&addrArg}}}, {"print", {{&helpOpt, &verboseOpt, &forceOpt, &oneStageOpt, @@ -204,6 +251,21 @@ int main(int argc, char** argv) { std::cout << printer.attributes(); } + else if(args.subCommand() == "info") + { + print_if_set("Name:", printer.name()); + print_if_set("Make and model:", printer.makeAndModel()); + print_if_set("Location:", printer.location()); + print_if_set("UUID:", printer.uuid()); + print_if_set("Printer state message:", printer.stateMessage()); + print_if_set("Printer state reasons:", join_string(printer.stateReasons(), "\n")); + print_if_set("IPP versions supported:", join_string(printer.ippVersionsSupported(), ", ")); + print_if_set("IPP features supported:", join_string(printer.ippFeaturesSupported(), "\n")); + print_if_set("Pages per minute:", printer.pagesPerMinute()); + print_if_set("Pages per minute (color):", printer.pagesPerMinuteColor()); + print_if_set("Supplies:", printer.supplies()); + print_if_set("Firmware:", printer.firmware()); + } else if(args.subCommand() == "identify") { error = printer.identify();