How to get the path to the archive
Hi, I am still seeking a clean way to get the path to my note, as requested here https://forum.zettelkasten.de/discussion/1401/request-some-way-of-getting-note-file-path#latest
To repeat my ask: apart from the current menu entry "Edit > Copy Link To Note", I request a "Edit > Copy Path to Note", which will give me enough information, and which will hopefully will be trivial for you to write.
Or, if the path to the archive is stored, perhaps somewhere in ~/Library, I can read from there...
Also, much less critical so feel free to ignore, is there yet a way to programmatically change the current folder?
Many thanks,
Abhijit
Howdy, Stranger!
Comments
I see a path in "Group\ Containers/FRMDA3XRGC.de.zettelkasten.TheArchive.prefs/Library/Preferences/FRMDA3XRGC.de.zettelkasten.TheArchive.prefs.plist"
Is that the right location
Abhijit, I use a two-step method when I want the full path of a note.
/Users/will/Dropbox/zettelkasten/Cosmic Pastoral 202305170541.mdI uploaded a gif showing how I do it. I'm not sure this is what you are asking. Do you want a note's full path or just the path to The Archive directory? I have a Python function for determining the full path to the active archive directory, but it doesn't return a specific path to a particular note.
Right-click on the note in the note list, selecting "Reveal in finder," or use the shortcut. Then in Finder, "Copy the Pathname," which is available by pressing down the Option Key while right-clicking on the target file.
The full pathname will be in the system clipboard.
If you use Keyboard Maestro or Alfred, you set up a keyboard macro for this if you find yourself doing it a lot.
The GIF turned out big and will take a minute to fully load, then it will run smoothly.

Will Simpson
My peak cognition is behind me. One day soon, I will read my last book, write my last note, eat my last meal, and kiss my sweetie for the last time.
My Internet Home — My Now Page
Thanks, Will.
I do want both, and I figured it out now. The crucial thing is that this should happen via a program and fast (okay to use both Keyboard Maestro and Alfred). Now I get the Archive path by reading from that file (which is a plist), and I get the path from there to the note using Edit > Copy Link To Note.
--Abhijit
@amahabal "Programmatic" inspection and modification is on my to-do list (via AppleScript) but not yet implemented.
There's an undocumented trick, though
Paste this into Script Editor:
This uses global system events to report the full path to the current note. That makes time tracking with Timing very accurate.
Author at Zettelkasten.de • https://christiantietze.de/
Thanks, @ctietze! That is good to know. Do you have a document with other such "undocumented" tricks? That would be worth bookmarking...
If I had, that would be documenting them
Some tips are on the help pages:
https://zettelkasten.de/the-archive/help/
Maybe I could add this one in case someone else looks for a way to ask The Archive for the currently open path (until AppleScript introspection works)
Author at Zettelkasten.de • https://christiantietze.de/
In consultation with my ZK, I found a method/function that programmatically works with Python to find the currently active folder path to The Archive, using the plist. Special shout-out to @pryley for the insight. This may give you ideas for adaptation to the language you use.
--- UUID: ›[[202208021213]] cdate: 08-02-2022 12:13 PM tags: #code-snippet #python --- # Get a Path from a Plist - Python [[202110091918]] from @pryley and works great in older versions of Python for finding the directory of The Archive. #!/usr/bin/env python3 #encoding: utf-8 from __future__ import absolute_import from Foundation import NSData from Foundation import NSPropertyListMutableContainers from Foundation import NSPropertyListSerialization import os import sys from urllib.parse import unquote class FoundationPlistException(Exception): """Basic exception for plist errors""" pass class NSPropertyListSerializationException(FoundationPlistException): """Read/parse error for plists""" pass class TheArchive: @staticmethod def path(): archive_url = TheArchive.setting('archiveURL') path = unquote(archive_url[len("file://"):]) return path @staticmethod def plist(): bundle_id = "de.zettelkasten.TheArchive" team_id = "FRMDA3XRGC" filepath = os.path.expanduser( "~/Library/Group Containers/{0}.{1}.prefs/Library/Preferences/{0}.{1}.prefs.plist".format(team_id, bundle_id)) if os.path.exists(filepath): plistData = NSData.dataWithContentsOfFile_(filepath) data, dummy_plistFormat, error = ( NSPropertyListSerialization.propertyListFromData_mutabilityOption_format_errorDescription_( plistData, NSPropertyListMutableContainers, None, None ) ) if data is None: if error: error = error.encode('ascii', 'ignore') else: error = "Unknown error" raise NSPropertyListSerializationException( "{0} in file {1}".format(error, filepath)) else: return data else: raise Exception("Error: Cannot find The Archive plist.") @staticmethod def setting(key): data = TheArchive.plist() try: return data[key] except KeyError: raise Exception( u"Warning: Cannot get The Archive setting: {0}".format(key)) path = TheArchive.path() sys.stdout.write(path)These are my modifications, and this is the function I currently use.
#### # Function for finding the path to The Archive ##### def TheArchivePath(): # Variables that ultimately revel The Archive's plist file. bundle_id = "de.zettelkasten.TheArchive" team_id = "FRMDA3XRGC" fileName = os.path.expanduser( "~/Library/Group Containers/{0}.{1}.prefs/Library/Preferences/{0}.{1}.prefs.plist".format(team_id, bundle_id)) with open(fileName, 'rb') as fp: pl = load(fp) # load is a special function for use with a plist path = urlparse(pl['archiveURL']) # 'archiveURL' is the key that pairs with the zk path return (path.path) # path is the part of the path that is formatted for use as a path. if __name__ == "__main__": zettelkasten = pathlib.Path(TheArchivePath()) print(f'The Current ZK Directory. {zettelkasten}') print(f'## {len(os.listdir(zettelkasten))} notes in the archive.') subfolders = [ f.path for f in os.scandir(zettelkasten) if f.is_dir() ] for i in subfolders: print(f'## {len(os.listdir(i))} files in {i}.') print(f'## {sizeof_fmt(getFolderSize(i))} in {i}.') print('-'*40)Output
Will Simpson
My peak cognition is behind me. One day soon, I will read my last book, write my last note, eat my last meal, and kiss my sweetie for the last time.
My Internet Home — My Now Page
Hi @Will,
I notice that in that code you are processing the plist with the NSData business. However, there is a standard plistlib module you could instead use. My code:
import os import plistlib import sys def get_archive_directory(): filenname = os.path.expanduser( "~/Library/Group Containers/FRMDA3XRGC.de.zettelkasten.TheArchive.prefs/" "Library/Preferences/FRMDA3XRGC.de.zettelkasten.TheArchive.prefs.plist") with open(filenname, 'rb') as fp: pl = plistlib.load(fp) return pl['archiveURL']Hi @amahabal, the NSData business is from the Python 2.7 days. The function currently used is below. Mine returns the path as a path rather than a dictionary. I practiced adding some error handling in another version.
Thanks for a look into your code, your function is a bit crisper.
My code:
from urllib.parse import urlparse import os, pathlib from plistlib import load def TheArchivePath(): # Variables that ultimately revel The Archive's plist file. bundle_id = "de.zettelkasten.TheArchive" team_id = "FRMDA3XRGC" #`fileName` is the path to the plist file that contains the path to the ZK. fileName = os.path.expanduser( "~/Library/Group Containers/{0}.{1}.prefs/Library/Preferences/{0}.{1}.prefs.plist".format(team_id, bundle_id)) with open(fileName, 'rb') as fp: # load is a special function for use with a plist pl = load(fp) # 'archiveURL' is the key that pairs with the zk path path = urlparse(pl['archiveURL']) # path is the part of the path that is formatted for use as a path. return (path.path) if __name__ == "__main__": zettelkasten = pathlib.Path(TheArchivePath()) print(f'The Current ZK Directory. {zettelkasten}')Will Simpson
My peak cognition is behind me. One day soon, I will read my last book, write my last note, eat my last meal, and kiss my sweetie for the last time.
My Internet Home — My Now Page