I sat down to write a macro for to quit Mail if not opened for >20 minutes. (I want to be able to count how many times I reopen Mail each day.)
Then I realized it was a lot harder than I thought—not the actual assembling of the macro, but the logic behind it. How would you guys do this?
The closet I could think of was two macros:
- Trigger every time Mail deactivates : Set VarX to the current time
- Trigger every minute (or every 5): if VarX + 20m < Current Time (and if Mail isn’t active now), quit Mail
Is it “bad programming” to have something checking every minute or 5? Is there a better way to do this?
1 Like
You could also ask the shell for 'elapsed running time' strings:
(.js)
var a = Application.currentApplication(),
sa = (a.includeStandardAdditions = true && a);
sa.doShellScript(
'ps -ax -o etime,command -c | grep "Mail"'
).split(/[\n\r]+/);
1 check every 5 mins sounds quite cheap ...
(perhaps more specifically, some variant of:
ps -ax -o etime,command -c | grep -w "Mail"
1 Like
Closer reading of bash docs would probably yield a more direct and elegant parse of the elapsed time string, but in q&d .js, perhaps something like:
How many minutes has Mail been running ?.kmmacros (2.3 KB)
(function () {
var a = Application.currentApplication(),
sa = (a.includeStandardAdditions = true && a);
return Math.round(
// ^dd-hh:mm:ss (first 11 chars give elapsed time)
sa.doShellScript(
'ps -ax -o etime,command -c | grep -w "Mail"'
// every 3rd char is a delimiter
).substr(0, 11).match(/.{3}/g).reduce(
function (lst, x, i) {
// Numeric value of first 2 chars,
// multiplied by matching element in the
// [days, hours, mins, secs] array below
lst[i] = Number(x.substr(0, 2)) * lst[i];
return lst;
},
[24 * 60, 60, 1, 1 / 60]
// sum up the [days, hours, mins, secs] as minutes
).reduce(
function (lngTotal, x) {
return lngTotal + x;
}, 0
)
);
})();
Hey Jack,
You mean opened OR activated — yes?
I think Rob's idea of using the system to provide the uptime of the app is a good one.
On my system I have more than one process that has 'mail' in it, but this produces only Mail.app:
ps -ax -o etime,command -c | egrep -o "[0-9:]+ Mail$"
I think you could use a macro in a global group with an application activation trigger.
You could write the date-time and mail-uptime to a log file every time Mail was activated, and that would give you some usage pattern.
An off-the-top-of-my-head run-through of the logic:
Mail Activates
Set/reset timer-variable to ps Mail minutes.
Run `ps` every 5 minutes
Save ps Mail minutes to elapsed-time variable
Subract timer from elapsed-time.
If value > 20 minutes then quit Mail.
There's a whole lot you can do with KM if you're a mind-to, but if you want really comprehensive usage information you might want to consider an app like Time Sink ($5.00 US).
-Chris
1 Like
There is nothing wrong with having a macro that triggers every five minutes. It will use a minuscule amount of CPU/Energy.
Create a group that is active whenever Mail is running (or alternatively, you can have a macro on Mail launch that enables the macro, or you can just have it run all the time) and within that a macro that runs every five minutes thaty basically does:
- If Mail is at the front
- Set variable Mail Count to 0
- Else
- Set Variable Mail Count to calculation Mail Count + 1
- If Calculation Mail Count > 4 Then
6 Likes
Thanks, all! Very helpful.