Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I add OS X "tags" to files programmatically?

Since Mavericks, OS X has had the ability to tag & colour files in Finder.

finder tags

Is there any way to add tags to files through Cocoa APIs or via a shell command?

like image 221
nacross Avatar asked Nov 01 '13 03:11

nacross


1 Answers

Sorry for adding another answer, but the one related to setting Label colors was pretty long already. Here is an excerpt from a python script that I use to set the User Tags. It seems to work to make things searchable, but not sure if the tags will show up correctly. Usage is basically:

tagfile.py "Tag Name" FileOrFolderName 

Code below.

#! /usr/bin/env python # -*- coding: utf-8 -*-  """ Write tags to file Usage:     tagfile.py "TagName" FileName1 FileName2       You can use wildcards for the file name. Use quotes if spaces in tags.     To check if it worked, use xattr -l FileName  """  import sys import subprocess  def writexattrs(F,TagList):     """ writexattrs(F,TagList):     writes the list of tags to three xattr fields on a file-by file basis:     "kMDItemFinderComment","_kMDItemUserTags","kMDItemOMUserTags     Uses subprocess instead of xattr module. Slower but no dependencies"""      Result = ""      plistFront = '<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"><plist version="1.0"><array>'     plistEnd = '</array></plist>'     plistTagString = ''     for Tag in TagList:         plistTagString = plistTagString + '<string>{}</string>'.format(Tag.replace("'","-"))     TagText = plistFront + plistTagString + plistEnd      OptionalTag = "com.apple.metadata:"     XattrList = ["kMDItemFinderComment","_kMDItemUserTags","kMDItemOMUserTags"]     for Field in XattrList:             XattrCommand = 'xattr -w {0} \'{1}\' "{2}"'.format(OptionalTag + Field,TagText.encode("utf8"),F)         if DEBUG:             sys.stderr.write("XATTR: {}\n".format(XattrCommand))         ProcString = subprocess.check_output(XattrCommand, stderr=subprocess.STDOUT,shell=True)          Result += ProcString     return Result  DEBUG = False   if __name__ == "__main__":     if len(sys.argv) < 3:         print __doc__     else:         TagList = [ sys.argv[1] ]         # print TagList         # Or you can hardwire your tags here         # TagList = ['Orange','Green']         FileList = sys.argv[2:]          for FileName in FileList:             writexattrs(FileName, TagList) 
like image 154
beroe Avatar answered Sep 19 '22 07:09

beroe