macosautomator

Use Automator to get content of text files in finder


I'm trying to create an automator-app which I can drop a finder-folder in it. It needs to filter all (thousands off) txt files and pass the contents to "Text to Audio File"

But the only available action is Get Contents of TextEdit document, and this is the currently open TextEdit document.

Is there no way to just get the content of an selected document? I think that's quite a common usage?


Solution

  • I feel this particular problem is more well suited to bash scripting than AppleScripting overall, given the sheer number of files you'll be dealing with, and the need to convert their contents to spoken audio.

    Here's a screenshot of the Automator workflow I came up with, which I believe addresses all of your needs and wants:

    Automator workflow on macOS High Sierra

    The two scripts (shell script and AppleScript) are reproduced at the bottom of this answer for simple copy-n-pasting, but the content of each is fully visible in the screenshot.

    Overview

    This workflow is designed to operate as a service in Finder, which will let you select a folder, right-click, and run the workflow from the pop-up context menu. You can also assign a keyboard shortcut to it.

    The folder is passed into the workflow. Its contents is retrieved, which provides the workflow with a list of files inside the folder. These are sent into the shell script.

    The shell script navigates into the supplied folder and creates a subfolder called "Audio", in which the audio files will be saved. Then it loops through every file in the supplied folder. If the file is not a .txt file, it is passed over. Otherwise, the command line tool say is used to convert the contents of each file to a spoken audio track. I selected a voice for it that speaks Mandarin ("Sin-ji"). The data format used for the audio files is aac, which avoids having to do a second conversion in iTunes later. The file format uses the file extension .m4b, which may seem unfamiliar, but is essentially an aac file encapsulated in an mp4 wrapper, with the file extension altered in line with Apple's recommendations. The .m4b extension tells macOS that the audio file is an iTunes audiobook (other ones Apple uses are .m4a for regular audio, and .m4r for ringtones). The cool thing about using the .m4b file extension is that, when it's imported into iTunes, it's instantly recognised as being an audiobook, and placed in the audiobooks section.

    The shell script returns the path to the "Audio" directory, now populated with audiobook files. The workflow retrieves the contents of this directory, i.e. the audiobook files, and imports them into iTunes without doing any further conversions. They get sent straight to the library, and end up in the audiobooks section.

    Here's the annoying bit: it seems that when iTunes imports new files into its library, it temporarily places a lock on the files, presumably as the files are copied across, the files scanned, and the metadata are written. During this time, setting any properties of the new imported tracks is not possible, and results in a "File permissions error".

    The duration will vary from system to system, and probably on the number of files imported as well.

    Inserting a pause into the workflow of 5 seconds gave the files sufficient time to be unlocked on my system, before proceeding to the final AppleScript.

    As per your request, this AppleScript's only job is to use the part of the filename that comes before the underscore ("_") to name the album, and that's what it does. If the file tracks are all unlocked by this point, it'll do it beautifully. If any one of the tracks are still locked, it'll cause the script—and the workflow—to throw an error.

    (Oddly, putting in an error handler to catch the errors and prevent it from halting the script also seemed to prevent the properties from being set. There's something buggy happening in iTunes AppleScript, but this doesn't surprise me.)


    Scripts

    Shell (bash)

        cd "$(dirname "$1")"      # Go into supplied folder
        mkdir -p "Audio"        # Create a folder for the audio files
        cd "Audio"
    
        shopt -s nocasematch    # For case-insensitive regex matching
    
        for f in "$@"; do        # Loop thru files; txt → m4b (audiobook)
            fn=$(basename "$f")
            [[ "${f##*.}" =~ txt ]] && \
            say --voice=Sin-ji \
                --output-file="${fn%.*}.m4b" \
                --input-file="$f" \
                --file-format=m4bf \
                --data-format=aac
        done
    
        pwd                     # Return the present working directory
                                # i.e. the "Audio" folder
    

    AppleScript

        use application "iTunes"
        property text item delimiters : "_"
    
        on run {input, parameters}
    
            repeat with m4b in the input
                set m4b's album to text item 1 of (m4b's name as text)
            end repeat
    
        end run
    

    Download the workflow

    Finally, I've uploaded the Automator service workflow for you to download, saving you having to recreate it all from scratch. It should be available for the next 30 days.