from xattr import xattr
colornames = {
0: 'none',
1: 'gray',
2: 'green',
3: 'purple',
4: 'blue',
5: 'yellow',
6: 'red',
7: 'orange',
}
attrs = xattr('./test.cpp')
try:
finder_attrs = attrs['com.apple.FinderInfo']
color = finder_attrs[9] >> 1 & 7
except KeyError:
color = 0
print colornames[color]
'red'
。你可以使用xattr模块将一个新的标签写回磁盘。如果你按照favoretti提供的链接往下滚动一点,会看到一个指向https://github.com/danthedeckie/display_colors 的链接,它使用 xattr
来实现此功能,但没有进行二进制操作。我对他的代码进行了一些修改:
from xattr import xattr
def set_label(filename, color_name):
colors = ['none', 'gray', 'green', 'purple', 'blue', 'yellow', 'red', 'orange']
key = u'com.apple.FinderInfo'
attrs = xattr(filename)
current = attrs.copy().get(key, chr(0)*32)
changed = current[:9] + chr(colors.index(color_name)*2) + current[10:]
attrs.set(key, changed)
set_label('/Users/chbrown/Desktop', 'green')
我不知道这个问题是否仍然与任何人有关,但有一个名为“mac-tag”的新包可以解决此问题。
pip install mac-tag
然后你还有像这样的函数:
function __doc__
mac_tag.add(tags, path) # add tags to path(s)
mac_tag.find(tags, path=None) # return a list of all paths with tags, limited to path(s) if present
mac_tag.get(path) # return dict where keys are paths, values are lists of tags. equivalent of tag -l
mac_tag.match(tags, path) # return a list of paths with with matching tags
mac_tag.parse_list_output(out) # parse tag -l output and return dict
mac_tag.remove(tags, path) # remove tags from path(s)
mac_tag.update(tags, path) # set path(s) tags. equivalent of `tag -s
Work
。首先,使用xattr
从键'com.apple.metadata:_kMDItemUserTags'
生成扩展属性的二进制plist
,然后使用plistlib将其转换为列表:
import xattr
import plistlib
def get_tags_xattr(fn):
try:
bpl=xattr.getxattr(fn, 'com.apple.metadata:_kMDItemUserTags')
rtr=[e.partition('\n')[0]
for e in plistlib.loads(bpl, fmt=plistlib.FMT_BINARY)]
return rtr if rtr else None
except OSError:
return None
brew
安装的程序tag:from subprocess import run, PIPE
def get_tags_tag(fn):
if 'com.apple.metadata:_kMDItemUserTags' in xattr.listxattr(fn):
rtr=run(['tag', '-g', '--no-name', fn],
stdout=PIPE).stdout.decode('utf-8').splitlines()
return rtr if rtr else None
return None
import osxmetadata
def get_tags_osxmeta(fn):
tags=[t.name for t in osxmetadata.OSXMetaData(fn).tags]
if tags:
return tags
return None
以下是三个示例的演示:
from pathlib import Path
p=Path('/tmp/test')
for fn in (fn for fn in p.glob('*') if fn.is_file()):
print(fn, get_tags_osxmeta(fn),
get_tags_tag(fn),
get_tags_xattr(fn))
打印在该示例文件夹上:
/tmp/test/DSC_2930-m.jpg ['Red', 'Green'] ['Green', 'Red'] ['Red', 'Green']
/tmp/test/DSC_2929.JPG None None None
/tmp/test/DSC_2939.JPG None None None
/tmp/test/DSC_2938.JPG ['Red'] ['Red'] ['Red']
/tmp/test/DSC_2937.JPG None None None
/tmp/test/DSC_2942-m.jpg ['Red', 'Orange', 'Gray', 'Work'] ['Gray', 'Orange', 'Red', 'Work'] ['Red', 'Orange', 'Gray', 'Work']
/tmp/test/DSC_2934.JPG ['Red'] ['Red'] ['Red']
/tmp/test/DSC_2930.JPG None None None
/tmp/test/DSC_2931.JPG None None None
/tmp/test/DSC_2933.JPG None None None
/tmp/test/DSC_2932.JPG ['Red'] ['Red'] ['Red']
/tmp/test/DSC_2941.JPG None None None
/tmp/test/DSC_2942.JPG None None None
其中最好的(我经常使用的)是osxmetadata模块。它快速而且非常灵活。如果你只需要标签,其他方法也可以很好地工作。第一个可能是最快的。
macfile
模块是 appscript
模块的一部分,自 "2006-11-20 -- 0.2.0" 起更名为 mactypes
。
使用此模块,以下是两个用于获取和设置 appscript 版本 1.0 中查找器标签的函数:
from appscript import app
from mactypes import File as MacFile
# Note these label names could be changed in the Finder preferences,
# but the colours are fixed
FINDER_LABEL_NAMES = {
0: 'none',
1: 'orange',
2: 'red',
3: 'yellow',
4: 'blue',
5: 'purple',
6: 'green',
7: 'gray',
}
def finder_label(path):
"""Get the Finder label colour for the given path
>>> finder_label("/tmp/example.txt")
'green'
"""
idx = app('Finder').items[MacFile(path)].label_index.get()
return FINDER_LABEL_NAMES[idx]
def set_finder_label(path, label):
"""Set the Finder label by colour
>>> set_finder_label("/tmp/example.txt", "blue")
"""
label_rev = {v:k for k, v in FINDER_LABEL_NAMES.items()}
available = label_rev.keys()
if label not in available:
raise ValueError(
"%r not in available labels of %s" % (
label,
", ".join(available)))
app('Finder').items[MacFile(path)].label_index.set(label_rev[label])
if __name__ == "__main__":
# Touch file
path = "blah"
open(path, "w").close()
# Toggle label colour
if finder_label(path) == "green":
set_finder_label(path, "red")
else:
set_finder_label(path, "green")