Hi,
I have an Applescript that I execute in KM, is it possible to set strPrinterName to the last used printer? if so, which wording will I need to use?
set strPrinterName to “HP Officejet Pro X551dw Printer”
tell application strPrinterName
print strPosixPath
end tell
Thank you
To get the default and most recent printers in JavaScript for Automation, I might write something like this:
(function() {
'use strict';
ObjC.import('AppKit')
var a = Application.currentApplication(),
sa = (a.includeStandardAdditions = true, a);
return {
default: $.NSPrintInfo.defaultPrinter.name.js,
latest: sa.doShellScript('lpstat -W completed | head -n 1')
.split(/\s+/)[0]
};
})();
In AppleScript (others will have a clearer idea) I think you may be able to write something like this for the latter:
set {dlm, my text item delimiters} to {my text item delimiters, " "}
set strPrinter to text item 1 of (do shell script "lpstat -W completed | head -n 1")
set my text item delimiters to dlm
strPrinter
1 Like
Thanks for this it works, but how do i get the name of the printer as it is shown on the Mac?
Much appreciated.
Different repositories of name strings – I’m not aware of a simple way of mapping them.
The best you can do may be to replace the underscores with spaces and drop the final number.
Hey Ali,
Give this a try from an Execute a Shell Script action.
It grabs the last used printer with lpstat
and then tries to match it in the printers directory.
cd ~/Library/Printers/;
lastUsedPrinter=$(lpstat -W completed \
| head -n 1 \
| sed -E '
s!_[0-9]+-[0-9]+ .+!!
s!_!*!g
')'*';
echo $lastUsedPrinter;
It works on my system, but the only printer I have installed is a Brother HL-2170W series.
-Chris
1 Like
On the system here that's giving:
AdobePDF8-133 houthakker 18432 Tue Jun 7 10:28:42 2016*
Not sure if that is what @demirtas1 is after.
One other approach, which yields
Adobe PDF 8.0
Might be something like this:
MRU printer.kmmacros (19.7 KB)
JavaScript source:
(function () {
'use strict';
// directoryContents :: FilePath -> [FileName]
function directoryContents(strPath) {
return ObjC.deepUnwrap(
$.NSFileManager.defaultManager
.contentsOfDirectoryAtPathError(
$(strPath)
.stringByStandardizingPath, null
)
);
}
// commonPrefix :: String -> String -> String
function commonPrefix(s, s1) {
// cpfx :: [Char] -> [Char] -> [Char]
function cpfx(xs, ys) {
return (xs.length && ys.length) ? (
xs[0] === ys[0] ? (
[xs[0]]
.concat(
cpfx(xs.slice(1), ys.slice(1))
)
) : []
) : [];
}
return cpfx(s.split(''), s1.split(''))
.join('');
}
var a = Application.currentApplication(),
strLatest = (a.includeStandardAdditions = true, a)
.doShellScript('lpstat -W completed | head -n 1')
.split(' ')[0]
.replace(/_/g, ' '),
lstPrinters = directoryContents('~/Library/Printers')
.map(function (x) {
return x.slice(0, -4); // '.app' dropped
});
return lstPrinters[
lstPrinters
.reduce(function (a, x, i) {
var lngMatch = commonPrefix(strLatest, x.replace(/\s+/g, ''))
.length;
return (lngMatch > a.length ? { // longer than previous matches ?
index: i,
length: lngMatch
} : a);
}, {
index: 0,
length: 0
})
.index
]; // harvesting just the index from the .reduce() accumulator
})();
Hey @ComplexPoint
That works nicely here for my Brother printer.
See if this works for you on your system.
cd ~/Library/Printers/;
lastUsedPrinter=$(lpstat -W completed \
| head -n 1 \
| sed -E '
s! *'"$USER"'.+!!
s!_! !g
s![[:punct:][:digit:]-]+$!!g
s!([a-z])([A-Z]{2,})!\1 \2!g
s!([A-Z]{2,}([a-z]))!\1 \2!g
s! !*!g
s!$!*!
')
echo $lastUsedPrinter;
-Chris
[ Edited 2016/06/08 04:09 CST – minor fix. ]
ccstone:
cd ~/Library/Printers/;
lastUsedPrinter=$(lpstat -W completed
| head -n 1
| sed -E '
s! '"$USER"'.+!!
s!_! !g
s![[:punct:][:digit:]-]+$!!g
s!([a-z])([A-Z]{2,})!\1 \2!g
s!([A-Z]{2,}([a-z]))!\1 \2!g
s! !!g
s!$! !
')
echo $lastUsedPrinter;
Well, here that is returning:
Adobe*PDF8-133***********
Where the JSA script above returns:
Adobe PDF 8.0
PS we might have to ask the original poster to unpack a little more of the requirements expressed in:
how do i get the name of the printer as it is shown on the Mac
but it doesn't look to me as if there is necessarily a regex-definable relationship between the lpstat naming conventions and those used for the app files in ~/Library/Printers
perhaps deriving an index into a list of the latter from a search for longest shared prefix is about all that can be done ?
Hm... That's weird. I'm basing the new script on my own printer and the string you provided earlier:
AdobePDF8-133 houthakker 18432 Tue Jun 7 10:28:42 2016*
When I plug your lpstat
string into my script here it works (of course I have to change the user-name).
Evidently there's something different at your end.
What's the bare result of lpstat -W completed | head -n 1
on your system?
-Chris
Whitespace composition ? Or the forum display subtly obscuring part of your regex from view or copy/paste ?
The raw lpstat output here is:
AdobePDF8-133 houthakker 18432 Tue 7 Jun 10:28:42 2016
(The string I posted above, with trailing *, was of course, the output rather than the input – perhaps also a source of mismatch ?)
ComplexPoint:
(The string I posted above, with trailing *, was of course, the output rather than the input – perhaps also a source of mismatch ?)
Yep. Try the edited version in post #7 .
I had to allow for more whitespace before the user name.
-Chris
ccstone:
cd ~/Library/Printers/;
lastUsedPrinter=$(lpstat -W completed
| head -n 1
| sed -E '
s! '"$USER"'.+!!
s!_! !g
s![[:punct:][:digit:]-]+$!!g
s!([a-z])([A-Z]{2,})!\1 \2!g
s!([A-Z]{2,}([a-z]))!\1 \2!g
s! ! !g
s!$!*!
')
echo $lastUsedPrinter;
Good ! Now yields:
Adobe PDF 8.0.app
Perhaps worth dropping the .app
affix ?
Since it's pulling the driver app name directly from the ~/Library/Printers/
folder I'm leaving it be for now.
On the other hand it's a trifling exercise to remove the .app
string from the whole.
One can use a Keyboard Maestro Search and Replace Variable action or replace that last line of the shell script with:
# To remove “.app” from the end of the printer name.
Replace:
echo $lastUsedPrinter;
With:
sed 's!\.app$!!' <<< $(echo $lastUsedPrinter);
-Chris