Keyboard Maestro Editor ⇢ Paste Dated Attribution Action v5.00 Macro


EDITED 2021/01/06 08:50 CDT

Please see Post #11 to find version 5.00 of this macro.


Hey Folks,

I finally got around to automating the date-stamps in my paste attribution macro.

Currently the pasted attribution looks like this:

But you can edit the XML to suite yourself – OR you can create a new attribution comment – export it as an action – open it in a text editor like TextWrangler – and copy the new XML into the set attributionAction variable action.

The action will be imported into the macro you're currently editing in the Keyboard Maestro Editor.

-Chris

[Edit: updated 2016/05/22 09:38 CST to v1.0.1]

[Edit: updated 2018/03/13 00:18 CST to v4.00 -- see post 11 below.]


Paste Dated Attribution Action v1.01.kmmacros (25 KB)

3 Likes

Thank you Christopher for this interesting KM internal mechanic macro.

You can even avoid swapping between “attributionAction”/“importAction” variables :wink:

What about:

  • called macros (Execute Macro Action)
  • automated update of comment when editing occurs
  • etc

kind of living comment…

BTW you have given a track for some kind of auto-signed macro if encryption (à la PGP) is used :wink:

Never enough :smile:

–Alain

He gave you a starting point… Go ahead and implement the rest yourself! :stuck_out_tongue:

Useful.

As a JavaScript for Automation footnote (in case anyone wants to explore further) I wondered if we could create the plist by writing something like:

function run() {

    // ISOLocal :: Date -> String
    function ISOLocal(dte) {
        var xs = ['FullYear', 'Month', 'Date',
                'Hours', 'Minutes', 'Seconds'
            ]
            .map(function (k, i) {
                var n = dte['get' + k](),
                    s = (n + (i === 1 ? 1 : 0)).toString();
                return (s.length === 1 ? '0' : '') + s;
            });
        return xs.slice(0, 3).join('-') + ' ' + xs.slice(3).join(':')
    }
    var strNow = ISOLocal(new Date());

    $.NSDictionary

        .dictionaryWithDictionary({
            ActionColor: 'Aqua',
            ActionName: 'A Macro by Your Name <Your EmailAddress>',
            MacroActionType: 'Comment',
            Text: 'Authored by Your Name <Your Email Address>\n' +
                strNow + ' : Created\n' +
                strNow + ' : Modified'
        })

        .writeToFileAtomically(
            $('~/Library/Caches/TemporaryItems/kmImportAction.kmactions')
            .stringByStandardizingPath, true
        );
}

Only gave myself 25 mins and now the time is running out the verdict is ‘close but no cigar’. The code above creates a single <dict> group (not wrapped in an <array>), so KM can’t read it.

If anyone else has 25 mins and a curiosity about plists in JSA, it might be worth looking more closely at NSDictionary

So far I have only got:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>ActionColor</key>
    <string>Aqua</string>
    <key>ActionName</key>
    <string>A Macro by Your Name &lt;Your EmailAddress&gt;</string>
    <key>MacroActionType</key>
    <string>Comment</string>
    <key>Text</key>
    <string>Authored by Your Name &lt;Your Email Address&gt;
2016-5-21 18:23:19 : Created
2016-5-21 18:23:19 : Modified</string>
</dict>
</plist>

UPDATE

Had another look – here is one route through JavaScript for Automation. A bit circuitous – writes out the plist and then modifies it.

FWIW a JS variant on Chris's theme:

Paste Dated Attribution Action (with JS).kmmacros (5.3 KB)

function run() {

    // ISOLocal :: Date -> String
    function ISOLocal(dte) {
        var xs = ['FullYear', 'Month', 'Date',
                'Hours', 'Minutes', 'Seconds'
            ]
            .map(function (k, i) {
                var n = dte['get' + k](),
                    s = (n + (i === 1 ? 1 : 0))
                    .toString();
                return (s.length === 1 ? '0' : '') + s;
            });
        return xs.slice(0, 3)
            .join('-') + ' ' + xs.slice(3)
            .join(':')
    }

    // readFile :: FilePath -> maybe String
    function readFile(strPath) {
        var error = $(),
            str = ObjC.unwrap(
                $.NSString.stringWithContentsOfFileEncodingError(
                    $(strPath)
                    .stringByStandardizingPath,
                    $.NSUTF8StringEncoding,
                    error
                )
            );
        return error.code || str;
    }

    var strNow = ISOLocal(new Date()),
        strPath = '~/Library/Caches/TemporaryItems/kmImportAction.kmactions',

        dctAction = {
            ActionColor: 'Aqua',
            ActionName: 'A Macro by Your Name <Your EmailAddress>',
            MacroActionType: 'Comment',
            Text: 'Authored by Your Name <Your Email Address>\n' +
                strNow + ' : Created\n' +
                strNow + ' : Modified'
        },

        // GENERATE THE DEFAULT PLIST XML
        strXML = (
            $.NSDictionary
            .dictionaryWithDictionary(dctAction)
            .writeToFileAtomically(
                $(strPath)
                .stringByStandardizingPath, true
            ),
            readFile(strPath)
        ),
        // ADJUST THE XML (wrap <dict> in <array>) FOR KM

        // Read back into an NSXMLDOCUMENT
        docXML = $.NSXMLDocument.alloc.initWithXMLStringOptionsError(
            strXML, 0, null
        ),
        xmlRoot = docXML.rootElement,
        // Add a top level <array> element
        xmlArray = (
            xmlRoot.insertChildAtIndex(
                $.NSXMLElement.alloc.initWithName('array'), 0
            ),
            xmlRoot.childAtIndex(0)
        );
    // Place a copy of the <dict> inside the <array>
    xmlArray.addChild(
        xmlRoot.childAtIndex(1)
        .copy
    );
    // and remove the original copy of the <dict>
    xmlRoot.removeChildAtIndex(1);
    // Then write the file back out again
    return docXML.XMLData
        .writeToFileAtomically(
            $(strPath)
            .stringByStandardizingPath, true
        );
}

1 Like

Hey Folks,

The macro in post 1 has been updated to v1.0.1.

Changes:

  • Added an Execute a Shell Script action at the beginning to make certain the temp directory exists.
  • I did this, because the macro failed after a reboot (when the temp dir was deleted).
  • Added a Click on Found Image action to dismiss the notification center banner.
  • The last 2 actions may need adjusting for your system depending upon how you have Notifications set up. (I have them set to Alerts for Keyboard Maestro.)

-Chris

Just wrapt it in an NSArray, something like:

    $.NSArray

        .arrayWithObject(

            $.NSDictionary

                .dictionaryWithDictionary({
                    …
                })

        )

        .writeToFileAtomically(
            …
        );
1 Like

Perfect. Thank you !

Regarding the settings for Notifications, I have them set up as Alerts for the Engine, but Banners for the editor. This has worked well for me so far - you might want to try that? And if you already have, in what way didn’t it work for you (just curious)?

(I’m not saying you shouldn’t put the Click on Found Image action in your macro - I’m just talking about using Notifications in general.)

Hey Dan,

I’m not certain why I set things up that way (the reverse of what you did).

I think I’ll switch it around and see if I like that better.

-Chris

Hey Folks,

I've redone my “Paste Dated Attribution Action” macro using features from Keyboard Maestro 8.1.1. It's now up to version 5.00.

The macro has been tested with KM 8.1.1 – 9.2d1 on macOS 10.12.6.

The zip file includes the bare Keyboard Maestro macro, a compiled AppleScript, and a read me.

The inserted action looks like this:

image

Dates, KM version, and macOS version are auto-generated.

There's properties at the top of the script for User Name and Default Tags to make those easier for the user to change.

I want to add:

  • The ability to change the Font and Size of the text.
  • Automagically insert the Forum URL as a clickable link if it's available.

But these are quite complicated and I've not yet gotten the help I need to figure them out.

-Chris


[EDITED 2021/01/06 08:38 CDT   -ccs]


Insert Customized Attribution Action v5.00.zip (20.4 KB)

Hi @ccstone, this looks interesting! When I run it, though, nothing happens and looking in the KME log I see this:

Doing a little more digging with UI Browser, I see that the reference to the KM scroll area is this:

scroll area 3 of splitter group 1 of group 1 of window "Keyboard Maestro Editor — Untitled Macro" 

but in your AppleScript code you reference it as this:

KM 1 2021-01-05_14-12-32

which is presumably where the error is coming from (the window name).

Can you provide a fix for this please?

Hey @tiffle,

See post #11 – I've made the fix (hopefully) and added a few bits.

Please give it a test drive, and let me know if it works alright for you.

-Chris

1 Like

Just tried it out Chris (@ccstone) and it works a treat now. Many thanks.

1 Like