Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question: Can OSXMetaData access Finder Getinfo information? #104

Open
macdeport opened this issue May 26, 2024 · 4 comments
Open

Question: Can OSXMetaData access Finder Getinfo information? #104

macdeport opened this issue May 26, 2024 · 4 comments

Comments

@macdeport
Copy link

macdeport commented May 26, 2024

Thanks for OSXMetaData.
Can OSXMetaData access Finder Getinfo information?

test-enedis jpg-alias-finder-get-info
@RhetTbull
Copy link
Owner

RhetTbull commented May 26, 2024

OSXMetaData can access any metadata that is available to Spotlight and much of this is what shows in the GetInfo panel. This includes tags/keywords, Finder comments, and specific metadata about an item. For example, I did "GetInfo" on a PDF file and Finder displayed Title, authors, version, pages, resolution, content creator, and encoding software in the "More Info". This is all available via OSXMetaData as kMDItemTitle, kMDItemAuthors, kMDItemVersion, kMDItemNumberOfPages, kMDItemPageHeight, kMDItemPageWidth, kMDItemCreator, and kMDItemEncodingApplications.

What specific information are you looking to access?

Edit: when I typed this the photo wasn't loading. It did load after I submitted the comment. The screenshot shows type, size, path, creation date, modified date. This is all file system data and in Python you should be able to get all of this through stat(). Determining if a file is an alias will take a bit more work on macOS via Python. I don't think there's a straightforward way to figure that out.

@macdeport
Copy link
Author

Thanks for your quick detailed answer.

What I need, and don't know how to do in Python, is to determine the source file of an alias (‘Original’ in the screenshot that ended up loading).

I cannot figure out how to get this path through stat()

On the other hand, this code retrieved from the web works, but I don't know how to code the ‘bridge’ version in Python:

use framework "Foundation"
use AppleScript version "2.4" -- Yosemite 10.10 or later
use scripting additions

property NSURL : a reference to current application's NSURL
property NSURLPathKey : a reference to current application's NSURLPathKey

set af to POSIX path of (choose file default location (path to desktop))

set aliasURL to NSURL's fileURLWithPath:af
set bookmarkData to NSURL's bookmarkDataWithContentsOfURL:aliasURL |error|:0
set bmvalue to NSURL's resourceValuesForKeys:[NSURLPathKey] fromBookmarkData:bookmarkData

display dialog ((bmvalue's objectForKey:"_NSURLPathKey")'s stringByAbbreviatingWithTildeInPath()) as text

"Determining if a file is an alias": it seems that you gave the solution yourself, unless I'm mistaken:

from osxmetadata import *

fp='/Users/alain/Documents/Logiciels/Developpement/pdf/test-enedis.jpg alias'
md = OSXMetaData(fp)
print(md.kind)

Alias

@RhetTbull
Copy link
Owner

RhetTbull commented May 27, 2024

"Determining if a file is an alias": it seems that you gave the solution yourself, unless I'm mistaken:

You're right! That appears to work.

What I need, and don't know how to do in Python, is to determine the source file of an alias (‘Original’ in the screenshot that ended up loading).

Ah, this should work:

"""Resolve path to macOS alias file"""

from Foundation import (
    NSURL,
    NSData,
    NSError,
    NSURLBookmarkResolutionWithoutMounting,
    NSURLBookmarkResolutionWithoutUI,
)


def resolve_alias_path(alias_path: str) -> str:
    """Given a path to a macOS alias file, return the resolved path to the original file"""
    options = NSURLBookmarkResolutionWithoutUI | NSURLBookmarkResolutionWithoutMounting
    alias_url = NSURL.fileURLWithPath_(alias_path)
    bookmark, error = NSURL.bookmarkDataWithContentsOfURL_error_(alias_url, None)
    if error:
        raise ValueError(f"Error creating bookmark data: {error}")

    resolved_url, is_stale, error = (
        NSURL.URLByResolvingBookmarkData_options_relativeToURL_bookmarkDataIsStale_error_(
            bookmark, options, None, None, None
        )
    )
    if error:
        raise ValueError(f"Error resolving bookmark data: {error}")

    return str(resolved_url.path())


if __name__ == "__main__":
    import sys

    if len(sys.argv) < 2:
        print("Usage: python alias.py <alias_path>")
        sys.exit(1)

    alias_path = sys.argv[1]
    resolved_path = resolve_alias_path(alias_path)
    print(f"alias: {alias_path}\noriginal: {resolved_path}")

You'll need pyobjc installed but if you've installed OSXMetaData to determine if it's an alias, that will have already installed the pyobjc pre-requisites.

@macdeport
Copy link
Author

Thank you very much for the time and expertise you've devoted to a functional solution.

Regarding alias detection, for your information, here is the functional code I was using before I met OSXMetaData:

# Is fp alias?
# https://github.com/xattr/xattr
# https://pypi.org/project/xattr/
from xattr import getxattr,listxattr,XATTR_NOFOLLOW

l_alias = False; mdx_tag = 'com.apple.FinderInfo'; s = ''
if mdx_tag in listxattr(fp, XATTR_NOFOLLOW):
	s = getxattr(fp, mdx_tag, XATTR_NOFOLLOW)
	# macOS Ventura 13.6.6
	stype = (b'alisMACS\x80', b'fapaMACS\x80', b'fdrpMACS\x80')
	if s and s.startswith(stype):
		l_alias = True

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants