Tag: macOS

  • Parchment Unifies Calendar, Reminders, and Journal

    Parchment Unifies Calendar, Reminders, and Journal

    Parchment is a new macOS productivity app by Christopher Lawley. If Lawley’s name rings a bell, you’ve almost certainly come across his YouTube channel.

    Parchment is available for macOS, iPadOS and iOS; it brings your calendar, journal and reminders together within one umbrella. Think of Parchment as a conduit that funnels your calendar agenda and tasks into one convenient location, while adding journaling / note-taking capabilities into the mix. Calendar items and tasks can be created within Parchment and synched back to Calendar and Reminders. Its function is something that seems so obvious in hindsight, I couldn’t believe the idea wasn’t already in existence. 

    Parchment is a new app, so expect some rough edges. I encountered cross device syncing issues in v1.0.1, but those issues have since been remedied in v1.0.4. Parchment has a one-time payment of $5US, making it a bargain for what it does.

    Even though Parchment is an app I didn’t know I needed, I’m glad it finally exists.

    -Krishna

  • FrugalMac: Apple Music Broke Me. Here’s How I Fixed It.

    FrugalMac: Apple Music Broke Me. Here’s How I Fixed It.

    I haven’t enjoyed Apple Music in years. Its user interface is a mess. The Music app has become increasingly intertwined with Apple’s streaming service. As a result, my own music collection—albums I’ve purchased and CDs I’ve ripped—has become mixed together with music that belongs to Apple Music. Adding insult to injury, Apple Music’s menus and dialogs are confusing

    In short, I hate what Apple Music has become.

    This week, I made the decision to divorce my music library from Apple Music’s streaming service. Henceforth, my Apple Music library will only contain music I have purchased or ripped from my sizeable CD collection. Since I can’t easily separate MY music from Apple’s, I’m starting from scratch with a new Music library. It will live on an external storage device.

    To keep this project from overwhelming me, I’ve put three guidelines in place for myself:

    1) I will only rip albums I really like. 

    2) I will rip no more then 10 albums per week.

    3) If I can’t find suitable (or high quality) album art for an album, I will replace it with artwork that fits the album.

    Part 1: Prepping the Landscape

    If you have Apple Music Sync checked in Apple Music > Settings > General, uncheck it. This prevents Apple Music from merging your local library with your streaming library. My General tab looks like this.

    The location of your Apple Music library is found under Apple Music > Settings > Files. Note this down. Quit the Apple Music app if it’s already open. Next, find your existing Apple Music media folder and rename it.  I’ve called mine Apple Music Archive. Apple Music has both a library database (Music Library) and the media folder.

    AppleMusic and MusicLibrary.

    Launch the Apple Music app, while holding down the Option key. Choose Create Library…

    Next, make a new folder where you want your media folder to live. I recommend making this folder on the root level of an external drive. Open Apple Music > Settings > Files and change the media location to your new folder. Keep the other options as is.

    Under Apple Music > Settings > Advanced, I’ve elected to have Apple Music automatically update album art. Be prepared to replace it, especially if the album is niche (i.e. import, bootleg recording, etc.).

    If you have purchased music from the iTunes Store, those purchases will automatically appear in your music library once you sign in with your Apple ID. (This is normal.) Before importing your CDs, make sure to choose Apple Lossless Encoder from Apple Music > Settings > Files > Import Settings. I also recommend checking Use Error Correction when reading Audio CDs.

    Part 2: Rip your CDs

    You’ll need a CD player with a USB interface connected to your Mac. Pop in an album. Apple Music will read the tracks from your disc. Import the entire album. (It’s faster, and you can always go back and remove tracks after the import if you need to.) Before importing, verify that the album title, artist name, and track names are correct. It’s much easier to fix metadata before importing than afterward.

    Music FileStructure.

    Part 3: Organizing your Music Library

    One of the unexpected benefits of starting over is that you can build a cleaner library than the one you had before. Remove duplicate albums, fix inconsistent artist names, update album artwork, and create playlists that reflect how you actually listen to music today.

    Streaming is wonderful for discovering new music, but I’ve realized I don’t want my permanent music collection tied to a monthly subscription. Rebuilding my library will take time, but when it’s finished, every album in it will be mine. That’s worth the effort.

    -Krishna

  • FrugalMac: Package Tracking and Keyboard Klack

    FrugalMac: Package Tracking and Keyboard Klack

    Two applications have been added to my FrugalMac bespoke build.

    Parcel screenshot.

    First up is Parcel ($4.99US / year), which tracks package shipments and status changes. Parcel works with all major carriers, including Amazon. The subscription covers both the Mac app and the iOS app. I’ve posted my full review of Parcel on the OWC RocketYard blog.

    Klack prefs.

    Next is an app some users would consider frivolous, but one that I find very useful. That app is Klack ($4.99US one time purchase), which provides users audible feedback as they type, mimicking the sounds of popular key switches found in mechanical keyboards. Klack not only plays sounds to register mouse clicks, it can even play a “ding” sound whenever the return key is pressed. Really nice additions if that’s your bag, but I tend to keep those custom options OFF.)

    Both Parcel and Klack are “Mac-assed” Mac apps.

    -Krishna

  • My Favorite Alfred Workflows

    My Favorite Alfred Workflows

    Alfred is my go-to application launcher. It goes well beyond launching applications, particularly if you have the Alfred PowerPack.

    Below are four of my most used Alfred Workflows. All are free, with the ability to install each automatically within the application:

    Unit Converter

    Alfred UnitConverter.

    Quickly convert units (inches to km, degrees to radians, etc.) from Alfred. Use the keyword conv followed by a number, and Alfred shows you a list of common conversions.

    Currency Converter

    Alfred currency converter.

    Ever want to know what $15.72US converts to in English pounds? Currency Converter makes currency conversions like this one instantaneously.

    Coffee Coffee

    Alfred coffee coffee.

    There’s no real need for a dedicated “keep Mac awake” app with Coffee Coffee. Type coffee to keep your Mac awake indefinitely. Type coffee 15 and your Mac will stay awake for 15 minutes, and so on. Super useful.

    About Mac

    This Workflow displays your Mac’s specs right from within Alfred. With it, I no longer need to visit System Settings. Quickly identify macOS version number, memory, storage, resolution, uptime and more by simply typing about within Alfred’s text field.

    -Krishna

  • FrugalMac: Dipping My Toes into Making Bespoke Automation Tools

    FrugalMac: Dipping My Toes into Making Bespoke Automation Tools

    In spite of my engineering background, I’ve never considered myself to be a coder. In college, I took a few required programming courses in both Assembler and C++. Those two classes, while informative, were never my cup of tea. (I also took a Fortran class as a freshman, and let’s just say – my very first introduction to the subject of programming was a nightmare.)

    I preferred solving Karnaugh maps and building analog amplifiers.

    Although my engineering days are long behind me, I still carry the engineer’s mindset: fixing problems and using tools to improve my productivity. Automation scratches that engineering itch.

    Up until recently, my instant go-to has been to purchase software tools to solve specific problems. There’s nothing wrong with that. It’s often easier and more efficient to buy a working solution than to make one from scratch.

    With my new MacBook Pro (aka FrugalMac), and some time on my hands, I wanted to try my own hand at solving some productivity problems before resorting to a purchase. In other words, I wanted to make my own bespoke tools. 

    My first challenge was to create an automation that would automatically delete files in a specific folder after a specific interval of time. Whether I’m writing or teaching, I take a lot of screenshots. As such, these files accumulate inside my Screenshots folder. The same holds true for the resultant resized images that I use for posting content online.

    To summarize, I wanted a script that would allow my Mac to:

    1) Automatically delete images from the Screenshots folder after 3 days.

    2) Delete images from the resized images folder after 7 days.

    As a bonus, I wanted the script to be reusable, should I wish to perform similar tasks on other folders on my Mac. I wasn’t exactly sure how to go about this task, so I consulted with ChatGPT. It suggested I start by creating a shell script.

    Part 1: Evaluating Files for Deletion

    The shell script’s job is to examine the files within a specific folder and delete those that meet the specified condition. For reuse, the script would require three input parameters:

    1) TARGET: The folder path. (i.e. where to evaluate files for deletion) 

    2) RETENTION_DAYS: The number of days to hold the file before deletion.

    3) DRYRUN: a TRUE / FALSE toggle for testing the specified condition without deleting any files.

    Because these values are passed into the script rather than hard-coded, the same script can be reused for any folder simply by supplying different parameters.

    After iteration and testing, below is the resultant shell script (called cleanup-folder.sh):

    #!/bin/zsh
    
    # ============================================================
    # cleanup-folder.sh
    #
    # Deletes files older than a specified number of days from
    # one target folder.
    #
    # Subfolders are not scanned.
    #
    # Usage:
    #
    #   cleanup-folder.sh "/path/to/folder" retention_days dryrun
    #
    # Examples:
    #
    #   cleanup-folder.sh "$HOME/Screenshots" 3 false
    #   cleanup-folder.sh "$HOME/Screenshots/resized images" 7 true
    #
    # Arguments:
    #
    #   $1  TARGET folder
    #   $2  RETENTION_DAYS
    #   $3  DRYRUN: true or false
    #
    # Important:
    #
    #   Files are permanently deleted. They are not moved to Trash.
    # ============================================================
    
    TARGET="$1"
    RETENTION_DAYS="$2"
    DRYRUN="${3:-false}"
    
    ############################################################
    # Validate Inputs
    ############################################################
    
    if [[ -z "$TARGET" ]]; then
        echo "Error: No target folder provided."
        exit 1
    fi
    
    if [[ -z "$RETENTION_DAYS" ]]; then
        echo "Error: No retention period provided."
        exit 1
    fi
    
    if [[ ! "$RETENTION_DAYS" =~ '^[0-9]+$' ]]; then
        echo "Error: Retention period must be a whole number."
        exit 1
    fi
    
    if [[ "$DRYRUN" != "true" && "$DRYRUN" != "false" ]]; then
        echo "Error: Dry-run setting must be true or false."
        exit 1
    fi
    
    if [[ ! -d "$TARGET" ]]; then
        echo "Error: Target folder does not exist:"
        echo "$TARGET"
        exit 1
    fi
    
    ############################################################
    # Convert Days to Minutes
    #
    # Using minutes avoids the unintuitive behavior of find's
    # -mtime test, which counts completed 24-hour periods.
    ############################################################
    
    RETENTION_MINUTES=$((RETENTION_DAYS * 24 * 60))
    
    ############################################################
    # Process Files
    #
    # -mindepth 1 prevents find from evaluating the target folder.
    # -maxdepth 1 prevents it from entering subfolders.
    ############################################################
    
    if [[ "$DRYRUN" == "true" ]]; then
        echo "DRY RUN: Files older than $RETENTION_DAYS day(s) in:"
        echo "$TARGET"
    
        find "$TARGET" \
            -mindepth 1 \
            -maxdepth 1 \
            -type f \
            -mmin +"$RETENTION_MINUTES" \
            -print
    else
        echo "Deleting files older than $RETENTION_DAYS day(s) in:"
        echo "$TARGET"
    
        find "$TARGET" \
            -mindepth 1 \
            -maxdepth 1 \
            -type f \
            -mmin +"$RETENTION_MINUTES" \
            -delete
    fi
    
     
     

    The script can be run from the Terminal:

    ~/Scripts/cleanup-folder.sh ~/Screenshots 3 false

    In the example above, I’m telling the script to:

    • examine the Screenshots folder,
    • delete files older than 3 days, and
    • actually perform the deletion (false)

    For testing purposes, I can substitute true for the final argument, causing the script to simply list the files that would be deleted.

    One interesting lesson I learned during development involved the find command. My original version relied on -mtime, which groups files into completed 24-hour periods. That produced some unintuitive results where files lingered longer than expected. I eventually switched to -mmin, converting days into minutes, which made the retention period much more precise.

    I also modified the script so that it only processes files in the specified folder rather than descending into subfolders. That allowed me to assign different retention periods to my Screenshots folder and its resized images subfolder without the two interfering with each other.

    One important note: the script permanently deletes matching files rather than moving them to the Trash. Since these folders only contain temporary working files, I was comfortable with that tradeoff.

    Part 2: Scheduling the Task

    After getting the script working properly with manual intervention, I was ready to automate it. Automating the script required two things: supplying the input parameters and telling macOS when to execute it. The shell script knows how to perform the cleanup, but it doesn’t know when to run. That’s where a LaunchAgent comes in. A LaunchAgent is defined by a small property list (.plist) file that tells macOS:

    • what program to run
    • what arguments to supply
    • when to run it.

    Using the Terminal, I created a file called com.krishna.cleanup-screenshots.plist and placed it into my $HOME/Library/LaunchAgents folder. Inside this file are the Program Arguments (containing the three inputs) and Calendar Interval (I want the script to run at 3AM every day).

    <?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>Label</key>
        <string>com.krishna.cleanup-screenshots</string>
    
    <key>ProgramArguments</key>
    <array>
        <string>/bin/zsh</string>
        <string>/Users/kms/Scripts/cleanup-folder.sh</string>
        <string>/Users/kms/Screenshots</string>
        <string>3</string>
        <string>false</string>
    </array>
    
    
    <!-- Run once whenever the LaunchAgent is loaded -->
        <key>RunAtLoad</key>
        <true/>
    
        <!-- Run every six hours -->
        <key>StartInterval</key>
        <integer>21600</integer>
    </dict>
    </plist>
    
     
     

    Originally, I scheduled the LaunchAgent to run every morning at 3:00 AM using StartCalendarInterval. During testing, however, I discovered that relying on a fixed time wasn’t ideal for my workflow. Instead, I updated the LaunchAgent to run whenever I log into my Mac (RunAtLoad) and then every six hours thereafter (StartInterval).

    That change makes the automation far more resilient. Rather than depending on a specific time of day, the cleanup simply runs periodically in the background while I use my Mac.

    Part 3: Letting the Mac Run the Task

    The Mac manages its tasks through launchd. As I understand it, here’s what happens:

    At 3:00 AM each day, launchd loads the LaunchAgent defined by com.krishna.cleanup-screenshots.plist. The LaunchAgent then starts /bin/zsh, which executes cleanup-folder.sh using the arguments supplied in the plist.  Or, put another way:

    Login


    launchd


    LaunchAgent (.plist)

    passes folder path
    passes retention period
    passes dry-run setting


    cleanup-folder.sh

    examines files


    Deletes files older than
    the specified retention period
    
    
    
    
    

    I applied the same approach for my resized images folder. All I needed to do was create a separate .plist file (called com.krishna.cleanup-resized-images.plist) with its own custom arguments.

    Screenshots -> retain for 3 days

    resized images -> retain for 7 days

    Both LaunchAgents use the exact same shell script.

    Summary:

    What I like most about this solution isn’t that it automatically deletes screenshots. It’s that the automation is modular. The shell script performs one job well, while each LaunchAgent provides the configuration for a specific task. If I later decide to automate cleanup for another folder, I don’t need to write another script. I simply create another LaunchAgent with a different folder path and retention period.

    FrugalMac tip: This entire solution uses tools already included with macOS:

    • zsh (shell)
    • find
    • launchd
    • LaunchAgents (.plist files)

    No third-party utilities are required.

    Wouldn’t using a program like Hazel be easier? Yes. But would it be as satisfying for me? Definitely not. 

    -Krishna

    I updated this article on 7/12 to reflect the fixes I incorporated, as well as improve overall clarity.

  • FrugalMac: Do I Need to Install Standalone Microsoft apps?

    FrugalMac: Do I Need to Install Standalone Microsoft apps?

    At work, our college uses Microsoft products, such as Word, Teams, and OneDrive. In the past, I have begrudgingly installed these items as stand alone apps on my Mac.

    Why the begrudgement?

    Simply put: These apps are big, bloated and stacked with performance inefficiencies

    With my FrugalMac build, I asked myself one question: “Do I really need to install stand-alone apps from Microsoft, or could I get by with using the web versions?”

    MS web apps.

    So I took it upon myself to set up Word, OneDrive, and Teams as web applications on my Mac. Conveniently, Safari includes an option to turn any web page into a dock-able app, so that’s exactly what I did. Incidentally, these “apps” reside within the Applications folder located within my Users folder.

    The verdict is still out. All three apps seem to launch quickly enough in my brief testing. I have no idea if this approach will suffice for my needs, but if I can keep extra software (particularly from Microsoft) from encroaching itself on my new Mac laptop, it’s worth giving it a go.

    -Krishna

  • FrugalMac: Text Expansion

    FrugalMac: Text Expansion

    Text expansion is my most frequently used Mac automation. Instead of typing in the same phrases over and over again, I can distill them into text expansion macros. 

    For example, if I were to type a small snippet, such as:

    ;wel

    it will expand to:

    Welcome to the course! Please make sure to review the syllabus and purchase the text we will be using this term. I look forward to seeing you in class.
    
    Best, 
    
    
    Prof. Krishna

    In a nutshell, I simply type in a few characters, and out comes some boilerplate text. Pretty nifty, right?

    Prior to setting up my new M5 Pro MacBook Pro (aka FrugalMac), I used a commercially available Mac text expansion app called Typinator. I’ve used Typinator for almost a decade at this point. It’s excellent at what it does, but it’s mostly overkill for my needs.

    Instead of blindly installing Typinator onto my new Mac, I dug in a little deeper to investigate whether text expansion capabilities were already present within the software currently available on my laptop. 

    Lo and behold, they were!

    Alfred’s PowerPack includes text expansion capabilities. They’re located inside Alfred’s Preferences panel, within Features > Snippets. Snippets can be organized into Collections. In my case, my Signatures Collection includes custom e-mail signoffs. I have different sign-offs depending upon whether I’m replying to a student or a colleague. I have set up an Academics Collection which includes commonly used phrases that I frequently use when responding to common inquries from my students. 

    Alfred Snippets.

    Within each collection are related snippets. Below is a screenshot showing one of my custom snippets. The keyword, in this case, is the trigger. Typing it will cause Alfred to optionally auto-expand with the boilerplate text I’ve provided. One nice convenience with Alfred is the ability to place the cursor where you want, after an expansion. This is done by way of the {cursor} argument. Once the expansion is complete, the cursor automatically moves to where the {cursor} argument is located. I can quickly type in the student’s first name, without having to skip a beat.

    Alfred individual Snippet.

    Alfred does 90% of what I want in terms of its text expansion capabilities. It would be terrific if I could add dynamic input during a text expansion, as Typinator already provides, but it’s not a deal breaker. I have to admit that there’s a certain sense of satisfaction in making the most out of what I already have.

    -Krishna

  • FrugalMac: Three Productivity Apps That Made the Cut

    FrugalMac: Three Productivity Apps That Made the Cut

    My FrugalMac build continues with the installation of three macOS productivity applications that I use regularly.

    First up is Fantastical, my calendaring tool of choice for both personal and work related scheduling. I’ve used Fantastical for nearly a decade; it offers many conveniences over Apple’s included Calendar.app. Chief among them is natural language parsing. I can easily add items to my calendar, by typing (or dictating) phrases like:

    Meet Bob next Wednesday at 1PM at Panera Bread.

    Set up Office Hours every Monday from 2 – 3PM from August 17th to December 19th.

    Fantastical also links with my Reminders.app, allowing me to track and complete upcoming tasks directly within my calendar. It’s extremely convenient. 

    Fantastical includes built-in scheduling, which allows me to share openings to let colleagues or students book time directly on my calendar. I plan to take full advantage of this new feature during the upcoming academic term.

    Fantastical includes a convenient menu bar item, where I can add an upcoming meeting or check my upcoming schedule at a glance.

    Fantastical menubar item.

    I do pay an annual subscription for Fantastical. In my view, it’s worth it, as useful features are added to the program throughout the year.

    I also use Notion Calendar, for the sole purpose of tracking project / assignment due dates

    Next up is Zoom. There’s no escape from this one, as we use it at work. Compared to its web counterpart, the dedicated Zoom app offers better performance and reliability when it comes microphones, web-cams and screen sharing

    Helium in action.

    Finally, to round things out, I’ve installed a Chrome-compatible browser called Helium. My browser of choice has always been Safari, but there are times where I find myself needing a Chrome-based browser. Helium is open-source, privacy focused and includes ad-blocking by default. I like Helium because it’s clean and fast. It does not come with a password manager or cloud-based sync, which is fine for my occasional use.

    -Krishna

  • I’ve Waited 25 Years for Apple to Fix This.

    I’ve Waited 25 Years for Apple to Fix This.

    I’ve had a long-standing beef with macOS, going all the way back to the very first version of Mac OS X. It may be minor to some; to others, it may even be a non-issue. But for me, it’s pretty big.

    In a nutshell, here’s my issue:

    The text that accompanies each icon on the Mac Desktop is very difficult to read when placed atop a light-hued background wallpaper. The text, rendered in white, is accompanied by a subtle drop shadow. On a medium or dark background wallpaper, this drop shadow creates the illusion of depth. But when this style is paired with a light-hued wallpaper, the text becomes much more difficult to read.

    Exhibit A: a mid-value wallpaper in macOS Tahoe:

    MacOS Tahoe mediumBG.

    Exhibit B: a light-value wallpaper in macOS Tahoe:

    MacOS Tahoe lightBG.

    It wasn’t always this way.

    In classic Mac OS, each icon had accompanying black text with a white background strip behind it. This approach ensured clear readability, independent of whatever wallpaper was chosen.

    Exhibit C: The Mac Desktop (macOS 7.5):

    Exhibit D: The Mac Desktop (macOS 9):

    Every version of macOS (including the forthcoming macOS Golden Gate) still provides no option to change the color of the text accompanying Desktop icons. It would be nice if Apple Intelligence could be employed to detect the value of the wallpaper background and automatically adjust the text color. In this setup, light backgrounds would automatically shift the icon text to black, and vice versa.

    I’ve filed a feedback form on this issue before macOS Tahoe shipped last year, but have yet to receive a response from Apple.

    -Krishna

  • Where to Find Indie Open Source Mac Apps

    Where to Find Indie Open Source Mac Apps

    There are many open source macOS applications available, but finding them online has been a bit hit or miss for me. Occasionally, I’ll discover an app from a Mac focused YouTube channel. Other times, I’ll run across a recommendation via my Mastodon feed. And, from time to time, I’ll come across something useful on one of the many independently run Mac blogs.

    Stumbling in the dark to find an open source Mac app is an option, but a better way is perusing IndieGoodies. Apps are categorized by tag, making it easy to find what you’re looking for. IndieGoodies is by no means a comprehensive list, but it’s a good start, and I like how it’s organized. 

    For native, open source macOS apps developed in Swift, check out Wang Ghujiang’s curated list. Apps are neatly organized by category, but what I really appreciate are the tags which identify when each app was last updated. This useful metric allows me to determine whether or not an app is actively being maintained. Be sure to check out the author’s apps while you’re at it.

    Another solid place to find open source Mac apps is Awesome Native MacOSX Apps on Git. The Mac apps in this list meet a specific criteria: they must be native and lightweight (no electron bloat). This list includes both free and paid software offerings. 

    Part of my FrugalMac experience is discovering high quality open source Mac apps that provide similar or improved features compared to their paid counterparts.

    It’s not that I object to paying for an app (I often do!), but there are some fantastic open source Mac apps that often fly under the radar. I want to make sure that these apps are given full consideration before opening my wallet.

    -Krishna