Working with Scripting Properties
… Or: How I Learned to Stop Worrying and Use Global Properties for Everything
Custom-defined persistent properties, which to save wear and tear on my keyboard will henceforth be referred to as properties, provide a way to create, store, retrieve, and modify variables within both Print Scripts and Device Scripts that will persist across subsequent script executions. In this way, information can be shared across these executions, vital for implementing things like custom rate limits for colour printing or copying (e.g. recording and then limiting the total number of colour pages a user can copy on a given day), and immensely useful towards meeting any number of other weird, wonderful, and scriptable requirements. Properties even work between Print Scripts and Device Scripts, so you can create pairs of scripts that can take both a user’s printing and copying into account.
Properties can be created in four classes; User Properties, Printer Properties, Device Properties, and Global Properties. The first three of these are associated with the user, printer, or device relevant to the current run of the script. For example, using a call like so to retrieve a user property:
inputs.user.getProperty("a-user-property")
… will get the value of a-user-property
specifically associated with the user who has submitted the print job, or who is using the device. Similarly, calls like these:
inputs.device.getProperty("a-device-property") inputs.printer.getProperty("a-printer-property")
… will net you the value of these properties associated with the printer or device the script is applied to.
A problem that a lot of our users run into when creating their scripts is that unlike global, device, and printer properties, there’s no way to view or modify the values of user properties outside of an actual script. For example, let’s say I’ve implemented a daily limit on the number of colour pages a user can copy, and a given user has reached that limit and is now being denied access to colour copying when they login to any of my devices. But then let’s also say that this user is Very Important, and Very Angry, and has Very Important colour copying that needs to be done Right Now or I will be summarily fired and literally thrown out of the building like a lawn dart at a garden party. Unless I modify my Device Script to reset their daily count of colour copy pages counter the next time they login to the device, or create a dummy printer with a Print Script on it that makes the same change, I’m getting tossed out with the day’s garbage. Doable, but I hardly want to be retooling my script whilst the Very Important are Yelling Loudly over my shoulder.
However! Global properties, retrieved within scripts like so:
inputs.utils.getProperty("a-global-property")
… can be viewed and modified from within the Admin web interface, directly via our Advanced Config Editor. Global properties are prefixed with script.user-defined.
within the Config Editor, e.g. script.user-defined.a-global-property
, so searching using that prefix will turn up a list of all global properties you’ve created. The problem is that global properties are relevant to all users, printers, and devices, though, so if you save the value of a-global-property
for one user, an entirely different user’s run of that same script will pickup and then change that same value. This makes storing things like counts of colour pages copied today for individual users difficult… but as it happens, not impossible.
TL;DR
We can create global properties that are specific to each user by suffixing the names of said properties with the name of the relevant user. These global properties will then be visible in the Config Editor, and even be searchable by username. Let’s say I had a user property that counted the number of colour pages per day:
var currentColourCount = inputs.user.getNumberProperty("colour-per-day");
If I tweak this like so, changing user
to utils
, adding user-custom-property.
to the property name, and using + inputs.job.username
to suffix the username of who triggered the script run:
var currentColourCount = inputs.utils.getNumberProperty("user-custom-property.colour-per-day." + inputs.job.username);
… we now have a global property that will only apply for the relevant user! Similarly, we change the way we save the property from this:
actions.user.onCompletionSaveProperty("colour-per-day", currentColourCount);
… to this:
actions.utils.onCompletionSaveProperty("user-custom-property.colour-per-day." + inputs.job.username, currentColourCount);
The end result will be keys available in the Advanced Config Editor for each user who triggers the script, e.g. for username peterf
:
script.user-defined.user-custom-property.colour-per-day.peterf
These will also be adjustable using our Server Command API to boot, much like printer and device properties:
server-command set-config script.user-defined.user-custom-property.colour-per-day.[user] [amount]server-command set-config script.user-defined.user-custom-property.colour-per-day.peterf 50
The only catch? If you have a great many users to whom your script applies, the Config Editor will be pretty busy-looking with all these newly visible keys! Something to keep in mind, if you’re the sort to browse for your advanced configuration keys, rather than search for them.
Categories: How-to Articles , Scripting and APIs
Keywords: script , scripting , properties , persistent , custom , zono
Last updated July 4, 2024
Comments