2024.03.05.

2023.12.24.

2023.12.19.

New Hookmark scripts for Reminders

I updated my Reminders/Hookmark integration script recently to make it faster on Sonoma. I also made sure that I have a “New Item” part too, so I can create reminders directly from Hookmark.

The “Get Address” script uses the backing SQLite database to find the ID of the selected reminder by title.

There are some caveats to keep in mind:

  1. We have to replace the remindersDatabasePath property with the proper database path which is different for everyone.
  2. Reminders are matched by title, so if we have multiple reminders with the same title, the script may fail to link the proper one.

Here are the scripts updated for Sonoma:

Get Address

use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions

-- Replace this with your Reminders database path.
property remindersDatabasePath : "/Users/yourusername/Library/Group Containers/group.com.apple.reminders/Container_v1/Stores/Data-some-UUID.sqlite"

tell application "System Events"
    tell its application process "Reminders"
        tell its window "Reminders"
            tell its splitter group 1
                tell its UI element 3
                    tell its UI element 2
                        tell its UI element 1
                            set reminderOutline to first UI element whose selected of UI element 1 is true
                            set theReminderName to value of UI element 2 of UI element 1 of UI element 1 of reminderOutline
                        end tell
                    end tell
                end tell
            end tell
        end tell
    end tell
end tell

set theSQLCommand to "/usr/bin/sqlite3 \"" & remindersDatabasePath & "\" \"SELECT ZCKIDENTIFIER from ZREMCDREMINDER WHERE ZTITLE = '" & theReminderName & "'\""
set theReminderIdentifier to do shell script theSQLCommand
set theURL to "x-apple-reminderkit://REMCDReminder/" & theReminderIdentifier
return "[" & theReminderName & "](" & theURL & ")"

New Item (this one can be a bit slow unfortunately)

tell application "Reminders"
    set theName to "$title"
    set theBody to "$user_link"
    set theReminder to make new reminder with properties {name:theName, body:theBody}
    set theReminderURL to the id of theReminder
    set theReminderURL to do shell script "echo \"" & theReminderURL & "\"|sed 's/x-apple-reminder:\\/\\//x-apple-reminderkit:\\/\\/REMCDReminder\\//g'"
    activate
end tell

theReminderURL

I haven’t tested these on earlier systems.

2023.12.05.

2023.11.27.

2023.11.23.

Publish bookmarks from DEVONthink

  • I’m messing with my bookmarks today.

  • I keep a lot of cool articles in DEVONthink as my central repository, but I also want to share some of these links here.

  • I’m testing a simple workflow for this using a DEVONthink smart group, which shows me all my bookmarks from my Decoding database that aren’t published yet.

  • This workflow desperately needs automation, but I want to start as simple as possible and see how it works in practice.

  • Here’s a demo video.

2023.09.18.

Download iOS icons for Safari web apps using Shortcuts

I love how you can save web apps into separate apps via Safari in Sonoma like you can with Fluid.

Safari tries to fetch the default icon, but sometimes it’s not that pretty or it’s even in a wrong aspect ratio. Finding proper app icons is hard, but a lot of web apps have iOS versions, so why not use their icons?

I created a shortcut, which lets you search the App Store and download the raw app icon. Now you can also use the proper iOS style icon for the web app.

You can download the shortcut from here.

Here’s a video on how you can use it.

2023.04.06.

Fantastical adds broader Shortcuts support

Flexibits just released Fantastical 3.7.9, which adds a bunch of new Shortcuts actions, including the ability to filter events from a given Calendar Set in a given date range, and the ability to generate a simple schedule for a given day.

Nice! I have a shortcut which syncs up calendar events with agenda items in Things. Now, I can automatically do the following in one shortcut:

  1. Get all my meetings for today from Fantastical.
  2. Create or find existing agenda items about them in Things.
  3. Link the Things agenda item and Fantastical event using Hookmark.
  4. Start a new session from Things when the meeting is due.
    • I’ll write about how I manage deep sessions with Things one day.

2023.03.05.

The first demo of RubyGPT integrated into macOS

As an AI language model, ChatGPT has gained a lot of attention lately. It is widely known for being quite powerful and having impressive natural language processing capability (especially for programming). This is why I decided to create a Ruby gem, RubyGPT, built on top of the newly released ChatGPT API which will enable me to chat with ChatGPT from the command line.

I recorded a demo of how RubyGPT works. I encourage you to watch it to understand better how this tool can make interacting with ChatGPT more efficient. It can be used directly from the command line or integrated into almost any editor and used like an interactive REPL.

I also created a corresponding AppleScript that passes the currently edited file from BBEdit into the `rubygpt` gem, parses the request then updates the file, making it feel like an editable conversation.

RubyGPT can be helpful in programming sessions, brainstorming, or general inquiry. It feels like you’re editing a Markdown text with an AI pair.

I may release this tool if there is a demand for it.

2023.01.30.

The Open in Kaleidoscope Service

The Services menu is getting a well deserved love from the Kaleidoscope blog:

The Services menu, originally part of NeXTSTEP, was introduced to the Mac with the advent of OS X in 2001. Throughout the entire history of OS X (now called macOS), Services never received a lot of love or major updates. Luckily, Services continues to work to this day and can be remarkably helpful.

One of the things I like about LaunchBar is its integration with the Services menu. There is no need to install a bunch of LaunchBar plugins; you can simply reuse already provided system services and share extensions from installed apps.

Add to Kaleidoscope

2022.12.29.

Getting the URL of the selected note in Apple Notes

I figured out how to get the built-in Apple Notes URL for the selected note in Hookmark (or in any app that can run Apple Scripts), so I can replace the default Hookmark script, which is a bit cumbersome.

I have a detailed write-up about the script’s inner workings in the Hookmark forums. It can be helpful even if you don’t use Hookmark. You can modify the script to copy the URL to the clipboard.

2022.02.23.

Archive Hook bookmarks with DEVONthink

I was in a Tinderbox Meetup last week, which was more about Hook than Tinderbox. I’m not a Tinderbox user, but I’m interested in how other people use their tools.

In the middle of the call, somebody had a question about Hook bookmarks. More specifically, can Hook archive its bookmarks as archive.org does with websites in general? Well there is no feature like that in Hook, and to be honest, doesn’t even need to be, because Hook has great Apple Script integration, so we can query bookmarks from its database.

In conjunction with DEVONthink, we can archive our bookmarks from Hook and save them as Pinboard does. I made a script for this a while back and it’s really helpful. It runs once a week, archives all websites from my Hook database into DEVONthink.

Setting up the script

First, download the script from here.

The scripts collect everything into one group in DEVONthink, so you have to create one where the archive can be stored. I would advise a new database even if you don’t have something similar already.

Open the script you downloaded. You’ll see two lines at the top of the file.

set webArchiveDatabaseUUID to "databaseUUID"
set hookedWebsitesGroupUUID to "groupdUUID"

You have to replace the databaseUUID and the groupdUUID part with the UUID of the database and group from DEVONthink. To do this, open DEVONthink, ⌃click on the database in the sidebar, and pick “Copy Item Link”.

Now, replace databaseUUID, with the link you copied. You’ll see something like this.

set webArchiveDatabaseUUID to "x-devonthink-item://CA3A9072-0650-4AF3-A608-1786F9D1A98D"
set hookedWebsitesGroupUUID to "groupdUUID"

Now, remove the x-devonthink-item:// part, so the top of the script should look like this.

set webArchiveDatabaseUUID to "CA3A9072-0650-4AF3-A608-1786F9D1A98D"
set hookedWebsitesGroupUUID to "groupdUUID"

Go back to DEVONthink and copy the group’s link from the same database (it is important to keep the group in the same database) by ⌃clicking on it and picking “Copy Item Link” again.

Replace groupdUUID with the copied link in the script again.

set webArchiveDatabaseUUID to "CA3A9072-0650-4AF3-A608-1786F9D1A98D"
set hookedWebsitesGroupUUID to "x-devonthink-item://B6C2C659-5682-45B5-8D59-107A641F8C2D"

Remove the x-devonthink-item:// part and then save your changes. The top of the script should look something like this now.

set webArchiveDatabaseUUID to "CA3A9072-0650-4AF3-A608-1786F9D1A98D"
set hookedWebsitesGroupUUID to "B6C2C659-5682-45B5-8D59-107A641F8C2D"

Now comes the fun part. You can run the script and DEVONthink will start downloading your Hook bookmarks into the group you choose.

The first run can take a while depending on the size of your Hook database. Subsequent runs should be faster since the script downloads only newly added bookmarks.

It is important to know that the script doesn’t sync Hook and DEVONthink, deleted bookmarks from Hook will still be present in DEVONthink.

Also good to know, if you want to archive sites behind a login, you have to sign-in in DEVONthink before you run the script.

Triggers

I keep this script in the ~/Libary/Scripts/Applications/DEVONthink 3 folder, so it’s available from the script menu in macOS – or in my case, from FastScripts. This way, you can run the script manually from DEVONthink.

You can even make it run automatically. If you use FastScripts, you can create a new DEVONthink reminder on the group you created to store Hook’s bookmarks and set it to run an Apple Script like this every week.

on performReminder(theRecord)
	tell application "FastScripts"
		set scriptItem to first script item whose name is "Archive Hook Bookmarks"
		tell scriptItem to invoke
	end tell
end performReminder

If you want to run it outside of DEVONthink, you can use for example Lingon, which makes it possible to run any Apple Script in the background daily, weekly, monthly, or whatever interval you want.

2021.12.22.

Using an old MacBook Air for a home server

I just assembled this temporary home server “rack” with my 2018 MacBook Air on top.

MacBook Air server on a self

It does the following things:

I plan to get a proper Mac mini after we moved into our new house, but for now, this is more than sufficient.

2021.10.28.

Using Shortcuts to remind me to charge my iPhone

I ran into the issue a couple of times where my iPhone ran out of battery, and I forgot to charge it. In the morning, it was completely dead when I needed it.

To avoid this problem, I created two Shortcuts automation, which makes sure that I won’t forget to charge my iPhone.

When my iPhone battery is below 15%, Shortcuts creates a new reminder 5 minutes into the future to remind me to charge my phone.

When I’m sitting at my Mac, Reminders will ping me to charge my iPhone. I can grab my phone and plug it in.

The other automation runs when I plug my phone in. It finds all reminders created by the previous automation and marks them as completed.

This automated reminder requires no work from my side, but it saved my bacon a couple of times.

2020.07.29.