Jump to content

Search Apple/iCloud Notes


Recommended Posts

@sballin You already know how much I love this workflow, so I won't bore you with more praise! Ha

 

If you're still accepting suggestions for tinkering with the workflow, is it possible to add another action modifier that allows users to open the selected note in its own window (i.e., instead of the default that always opens in the app's main window)? There are often times when I need to quickly look at something in a note while I'm working on another one, and I've love to be able to do that a little more quickly. Thanks!

Link to comment
  • 1 month later...

Hi Sean, 

 

I've been a happy user of this workflow for a couple of months, thank you. But last week it mysteriously stopped searching notes and I''m not sure what's going on. I guess this is only me because I haven't heard anyone else on this thread have any issues. What's strange is the folder "fn" search works fine but not the general "n" search. 

 

Is there something I can do to get this workflow up and running again? 

 

Thanks

 

Reg

 

 

#!/usr/bin/python
import sqlite3
import zlib
import re
import os


def extractNoteBody(data):
    try:
        # Strip weird characters, title & weird header artifacts, 
        # and replace line breaks with spaces
        data = zlib.decompress(data, 16+zlib.MAX_WBITS).split('\x1a\x10', 1)[0]

        # Reference: https://github.com/threeplanetssoftware/apple_cloud_notes_parser
        # Find magic hex and remove it
        index = data.index('\x08\x00\x10\x00\x1a')
        index = data.index('\x12', index)

        # Read from the next byte after magic index
        data = data[index+1:]

        data = unicode(data, "utf8", errors="ignore")

        return re.sub('^.*\n|\n', ' ', data)
    except Exception as e:
        return 'Note body could not be extracted: {}'.format(e)
        
        
def readDatabase():
    # Open notes database
    home = os.path.expanduser('~')
    db = home + '/Library/Group Containers/group.com.apple.notes/NoteStore.sqlite'
    conn = sqlite3.connect(db)
    c = conn.cursor()

    # Get uuid string required in full id
    c.execute('SELECT z_uuid FROM z_metadata')
    uuid = str(c.fetchone()[0])

    # Get tuples of note title, folder code, modification date, & id#
    c.execute("""SELECT t1.ztitle1,t1.zfolder,t1.zmodificationdate1,
                        t1.z_pk,t1.znotedata,t2.zdata,t2.z_pk
                 FROM ziccloudsyncingobject AS t1
                 INNER JOIN zicnotedata AS t2
                 ON t1.znotedata = t2.z_pk
                 WHERE t1.ztitle1 IS NOT NULL 
                       AND t1.zmarkedfordeletion IS NOT 1""")
    # Get data and check for d[5] because a New Note with no body can trip us up
    dbItems = [d for d in c.fetchall() if d[5]]
    dbItems = sorted(dbItems, key=lambda d: d[sortId], reverse=sortInReverse)

    # Get ordered lists of folder codes and folder names
    c.execute("""SELECT z_pk,ztitle2 FROM ziccloudsyncingobject
                 WHERE ztitle2 IS NOT NULL 
                       AND zmarkedfordeletion IS NOT 1""")
    folderCodes, folderNames = zip(*c.fetchall())

    conn.close()
    return uuid, dbItems, folderCodes, folderNames


# Sort matches by title or modification date, option to search titles only.
# Edit with Alfred workflow environment variable.
sortId = 2 if os.getenv('sortByDate') == '1' else 0
searchTitlesOnly = (os.getenv('searchTitlesOnly') == '1')
sortInReverse = (sortId == 2)

if __name__ == '__main__':
    # Custom icons to look for in folder names
    icons = [u'\ud83d\udcd3', u'\ud83d\udcd5', u'\ud83d\udcd7', u'\ud83d\udcd8', 
             u'\ud83d\udcd9']

    # Read Notes database and get contents
    try:
        uuid, dbItems, folderCodes, folderNames = readDatabase()
        openedDatabase = True
    except:
        openedDatabase = False
             
    if openedDatabase:
        # Alfred results: title = note title, arg = id to pass on, subtitle = folder name, 
        # match = note contents from gzipped database entries after stripping footers.
        items = [{} for d in dbItems]
        gotOneRealNote = False
        for i, d in enumerate(dbItems):
            try:
                folderName = folderNames[folderCodes.index(d[1])]
                if folderName == 'Recently Deleted':
                    continue
                body = extractNoteBody(d[5])
                subtitle = folderName + '  |' + body[:100]
                match = u'{} {} {}'.format(d[0], folderName, '' if searchTitlesOnly else body)
                
                # Custom icons for folder names that start with corresponding emoji
                if any(x in subtitle[:2] for x in icons):
                    iconText = subtitle[:2].encode('raw_unicode_escape')
                    subtitle = subtitle[3:]
                    icon = {'type': 'image', 'path': 'icons/' + iconText + '.png'}
                else:
                    icon = {'type': 'default'}
                
                items = {'title': d[0],
                            'subtitle': subtitle,
                            'arg': 'x-coredata://' + uuid + '/ICNote/p' + str(d[3]),
                            'match': match,
                            'icon': icon}
                gotOneRealNote = True
            except Exception as e:
                items = {'title': 'Error getting note', 'subtitle': str(e)}
                
    if openedDatabase and gotOneRealNote:
        import json 
        print json.dumps({'items': items})
    else:
        import subprocess 
        print subprocess.check_output(os.path.dirname(__file__) 
                                      + '/searchNoteTitles.applescript')
 

Edited by Regluke
Grammar
Link to comment

Hi all! Opening notes in a new window and supporting folders are on my to-do list. 

 

@Regluke to debug, could you open the workflow in Alfred preferences and click on the bug icon on the top right corner? That will open a little white area for debug info. Then try searching for something with n and send me what shows up in the debug window. 

Link to comment

Hi @sballin

This is the first time I've done this and it shows a lot of data. I copied the first part which shows the error. Does this help?

 

[2019-01-27 20:34:03][ERROR: input.scriptfilter] JSON error: Unexpected end of file during string parse (expected low-surrogate code point but did not find one). in JSON:

{"items": [{"icon": {"type": "default"}, "arg": "x-coredata://6B56A1ED-C957-4AB0-931E-71C6EA9E972C/ICNote/p23847", "subtitle": "Notes  | 

 

 

 

Also I came across this other error when using the 'fn' search which usually works for me.

 

[2019-01-27 20:38:08][ERROR: action.applescript] {

    NSAppleScriptErrorAppName = Notes;

    NSAppleScriptErrorBriefMessage = "Can\U2019t get folder id \"x-coredata://6B56A1ED-C957-4AB0-931E-71C6EA9E972C/ICFolder/p4001\".";

    NSAppleScriptErrorMessage = "Notes got an error: Can\U2019t get folder id \"x-coredata://6B56A1ED-C957-4AB0-931E-71C6EA9E972C/ICFolder/p4001\".";

    NSAppleScriptErrorNumber = "-1728";

    NSAppleScriptErrorRange = "NSRange: {89, 25}";

}

 

 

 

Please let me know if you need any additional information. Thanks a lot.

 

 

Reg

 

 

 

 

Edited by Regluke
Added sballin to message.
Link to comment
  • 3 weeks later...

@Regluke that's very kind of you, you can donate here if you like but don't worry, it didn't take long to fix your issue and I think most people would have run into it at some point, so you've already done a service by reporting it.

 

@Jasondm007 I poked around with AppleScript to open a note in a new window and couldn't figure it out, so I don't think I'll be able to add this feature. I'll be happy to add it if anyone else figures it out.

Link to comment
  • 2 months later...
  • 2 months later...

This workflow isn't working for me, when I type 'n' I see a list of notes and if I type one letter it searches but when I type a 2nd it switches off to contacts instead of sticking with the Notes workflow.

 

I am using Catalina, which may be why, just wanted to report early!

 

Thanks for this fantastic workflow!

Link to comment
13 hours ago, keithah said:

This workflow isn't working for me, when I type 'n' I see a list of notes and if I type one letter it searches but when I type a 2nd it switches off to contacts instead of sticking with the Notes workflow.

 

I am using Catalina, which may be why, just wanted to report early!

 

Thanks for this fantastic workflow!

 

Thanks for the report! I tried it on Catalina just now and it worked for me. I think the issue is that you have contacts included in the default search results, so you could turn that (and the other defaults) off if you really want n[search string] to work for searching. An alternative that I've come to prefer is to map command-space to open Notes, and command-L to do the note search. The workflow includes empty hotkey boxes that you can set this way.

Link to comment
  • 1 month later...

This workflow has stopped working for me. Not sure what Ive done but it used to work as Is by typing "N" but that stopped working. I switched to using the compatible command "an" but now that doesn't populate with any of my recent notes. I'm on Mojave, latest version 

Link to comment
8 hours ago, bzzzl said:

This workflow has stopped working for me. Not sure what Ive done but it used to work as Is by typing "N" but that stopped working. I switched to using the compatible command "an" but now that doesn't populate with any of my recent notes. I'm on Mojave, latest version 

 

Still working for me on 10.14.6 (with the supplemental update from 8/26).

Link to comment
  • 1 month later...

@sballin Since updating to Catalina last evening, I'm still able to search for everything using your fantastic workflow. However, when I select the note that I want to open from Alfred, the workflow won't open it. The workflow looks like it's working as usual, but nothing happens.

 

I noticed that there is a "Note Opener" app in the workflow. Is this the usual "unidentified developer" problem with Catalina? Unlike other workflows that had this issue, I did not receive the usual error indicating that it was trying to run an app from an identified developer.

 

Any ideas what might be causing the problem? Others above seem to be OK since updating to Catalina (or at least one of the betas). Your workflow is one of my favorites on Alfred!!

 

Thanks for your help!

Edited by Jasondm007
typo
Link to comment

Sorry to hear it's not working, I'm still on Mojave for the time being. Could you send me the text in the debug log after you find and open a note? Take care to remove any private note contents if they show up there.

 

The note opener app only runs when you click on a note:// link. The fact that search works but opening doesn't means there's some trouble when Alfred tries to run the applescript that opens a note.

Link to comment

@sballin Just popping my head in quickly (I haven't looked at the workflow at this point) to say that apps have moved in Catalina, so if you've linked to a hardcoded location for the Notes app, that may simply need to be updated to reflect the new path :)

 

I'm not on a Catalina Mac right now, but @Regluke and @Jasondm007 should be able to give you the details you need from Catalina.

 

Thanks for the great workflow :)

 

Cheers,
Vero

Link to comment

@sballin Thanks for your help!

 

Omitting the initial lines from the debug log, here's where the error occurs:

...
...

[14:35:44.266] Notes - Search [Script Filter] Processing complete

[14:35:44.282] Notes - Search [Script Filter] Passing output 'x-coredata://BC2A1C56-125D-4468-A9F8-D42448AC3262/ICNote/p3639' to Run NSAppleScript

[14:35:44.439] ERROR: Notes - Search [Run NSAppleScript] {
    NSAppleScriptErrorAppName = Notes;
    NSAppleScriptErrorBriefMessage = "AppleEvent handler failed.";
    NSAppleScriptErrorMessage = "Notes got an error: AppleEvent handler failed.";
    NSAppleScriptErrorNumber = "-10000";
    NSAppleScriptErrorRange = "NSRange: {67, 20}";
}

 

Thanks again!

Link to comment
5 minutes ago, Vero said:

@sballin Just popping my head in quickly (I haven't looked at the workflow at this point) to say that apps have moved in Catalina, so if you've linked to a hardcoded location for the Notes app, that may simply need to be updated to reflect the new path :)

 

I'm not on a Catalina Mac right now, but @Regluke and @Jasondm007 should be able to give you the details you need from Catalina.

 

Thanks for the great workflow :)

 

Cheers,
Vero

 

@sballin I'm not sure if it's helpful, but here's the path to the Notes app: /System/Applications/Notes.app

Link to comment

I installed Catalina alongside Mojave and I think I've fixed it by modifying the AppleScript slightly—will upload the updated version soon. For people fully on Catalina, is the Notes icon showing up correctly next to results when you use the workflow? The icon depends on the location of the Notes app. In my installation I had both /System/Applications/Notes.app and /Applications/Notes.app.

Edited by sballin
Link to comment
2 hours ago, sballin said:

I installed Catalina alongside Mojave and I think I've fixed it by modifying the AppleScript slightly—will upload the updated version soon. For people fully on Catalina, is the Notes icon showing up correctly next to results when you use the workflow? The icon depends on the location of the Notes app. In my installation I had both /System/Applications/Notes.app and /Applications/Notes.app.

 

@sballin I'm not sure if this is what you're asking, but when I run your workflow and it shows the search results, I see the workflow's icon next to each note (i.e., not the default Notes.app icon or anything else). Hope this helps! 

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...