Comment puis-je ajouter OS X "tags" aux fichiers par programmation?

depuis Mavericks, OS X a eu la possibilité d'étiqueter et de colorer des fichiers dans Finder.

finder tags

y a-t-il un moyen d'ajouter des tags à des fichiers via les API de Cocoa ou via une commande shell?

27
demandé sur Terry N 2013-11-01 07:36:14

10 réponses

Désolé d'ajouter une autre réponse, mais celle liée à la définition des couleurs des étiquettes était déjà assez longue. Voici un extrait d'un script python que j'utilise pour définir les Balises. Il semble fonctionner pour rendre les choses searchable, mais pas sûr si les étiquettes vont apparaître correctement. L'Usage est essentiellement:

tagfile.py "Tag Name" FileOrFolderName
Code

ci-dessous.

#! /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)
11
répondu beroe 2013-11-06 06:29:30

Check out tag,"un outil en ligne de commande pour manipuler les tags sur Mac OS X 10.9 Mavericks fichiers, et pour demander des fichiers avec ces tags". le dépôt GitHub a des instructions d'installation (il y a des paquets Homebrew et MacPorts).

9
répondu sillygwailo 2013-11-27 05:56:12

j'ajoute cette réponse, parce que OP a demandé un script shell et l'a étiqueté bash . J'ai écrit Ce service D'automate, qui identifie le fichier sélectionné avec les étiquettes d'un autre fichier. J'ai ajouté des commentaires pour souligner l'utilisation de l'interaction de bash avec les tags et les couleurs en utilisant l'écriture de bash.

de base

dans les scripts les tags OpenMeta et Mavericks sont accessibles avec la commande xattr . L'utiliser sans modifier, $ xattr [file] , donne une liste d'attributs. $ xattr -h donne un bon guide d'utilisation.

les étiquettes de Mavericks sont dans com.Apple.métadonnées: _kMDItemUserTags, tandis que les tags OpenMeta peuvent être dans une variété d'attributs. Entre autres com.apple.metadata:kOMUserTags , org.openmetainfo:kMDItemOMUserTags et org.openmetainfo:kOMUserTags .

Mavericks gère les couleurs et les étiquettes dans différents attributs, en plaçant les étiquettes dans _kMDItemUserTags et les couleurs dans FinderInfo pour chaque fichier. C'est un choix bizarre, et c'est l'une des raisons pour lesquelles Finder lutte sous la pression du marquage. Si vous avez 800 fichiers marqués kapow , chacun dans un dossier différent, et que vous choisissez ensuite la couleur bleue pour kapow , Finder doit trouver et modifier les attributs pour chaque fichier.

vous pouvez jouer avec l'étrangeté en enlevant le com.Apple.Attribut FinderInfo à partir d'un fichier coloré: $ xattr -d com.apple.FinderInfo [file] . La couleur disparaîtra dans les listes de Finder, mais l'étiquette (et sa couleur) reste associée au fichier.

script Bash pour importer des balises à partir d'un autre fichier

dans le script, le(S) fichier (s) sélectionné (s) dans Finder est/sont enregistrés à la variable $tagless , et le fournisseur choisi de tags est $tagfull .

TAGFULID=${#@}
TAGFUL=${!TAGFULID}

## Use xattr to read all existing tags:
ATTRS=$(xattr "$TAGFUL")

for f in "$@" ## For every selected file in Finder, do:
do
    if("$TAGFUL"="$f") ## Is the supplier of tags is amongst the selected files?
    then
        break
    fi

    if [[ "$ATTRS" == *kMDItemUserTags* ]] ## Are there tags?
        then
        ## Load tags:
        TAGS=$(xattr -px com.apple.metadata:_kMDItemUserTags "$TAGFUL")
        ## Write tags:
        xattr -wx com.apple.metadata:_kMDItemUserTags "$TAGS" "$f"
    fi
    if [[ "$ATTRS" == *FinderInfo* ]] ## Are there colours?
    then
        ## Load colour:
        FINDERINFO=$(xattr -px com.apple.FinderInfo "$TAGFUL")
        ## Write colour:
        xattr -wx com.apple.FinderInfo "$FINDERINFO" "$f"
    fi
done

The Automator service

5
répondu Rasmus 2013-12-16 18:27:30

Apple Ce qui est Nouveau dans OS X il affirme que NSURL poignées de balises, et le Système de Fichiers Commun Resource_Keys donne la clé requise NSURLTagNamesKey et les membres de sa valeur est un tableau de chaînes de caractères.

4
répondu CRD 2013-11-01 16:29:06

le OpenMeta framework est une norme de tiers pour ajouter des métadonnées aux fichiers OS X en utilisant des attributs étendus. Il est utilisé par un certain nombre d'applications tierces.

ou vous pouvez utiliser la commande XATTR pour manipuler les attributs étendus via la ligne de commande.

2
répondu Imran S. 2013-11-01 03:41:24

Vous pourriez donner ce un coup:

xattr -w com.apple.metadata:_kMDItemUserTags '<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"><plist version="1.0"><array><string>Orange</string><string>Red</string></array></plist>' $currentFile

vous voulez remplacer $currentFile par le fichier auquel vous voulez ajouter des balises, et changer

<string>Orange</string><string>Red</string>

à une liste de toutes les étiquettes que vous voulez ajouter.

2
répondu Sperr 2013-11-01 03:55:45

cela ne couvre pas les étiquettes, mais pour changer les couleurs des étiquettes, une façon de le faire est par une commande comme celle-ci:

xattr -wx com.apple.FinderInfo \
0000000000000000000400000000000000000000000000000000000000000000 myfile.txt

le 04 enfoui au milieu définit la couleur du fichier.

voici un script python qui enveloppe cette commande vous permet de définir la couleur de la balise sur un fichier ou une série de fichiers:

import sys
import subprocess

def colorizeFile(ColorName,FileName):
    ReverseTable = {
         "clear"  :  "01",
         "gray"   :  "03",
         "green"  :  "04",
         "purple" :  "06",
         "blue"   :  "09",
         "yellow" :  "0A",
         "red"    :  "0C",
         "orange" :  "0E",
         "c"      :  "01",
         "a"      :  "03",
         "g"      :  "04",
         "p"      :  "06",
         "b"      :  "09",
         "y"      :  "0A",
         "r"      :  "0C",
         "o"      :  "0E",
    }

    HexString = 18*"0" + ReverseTable.get(ColorName) + 44*"0"
    Xcommand = 'xattr -wx com.apple.FinderInfo {0} {1}'.format(HexString,FileName)
    ProcString = subprocess.check_call(Xcommand, stderr=subprocess.STDOUT,shell=True) 

if __name__ == "__main__":
    if len(sys.argv)<3:
        sys.stderr.write(__doc__.format(sys.argv[0]))
    else:
        Cname = sys.argv[1]
        Flist = sys.argv[2:]
        for File in Flist:
            colorizeFile(Cname.lower(),File)
        sys.stderr.write("## Colorized {0} file(s) as {1}\n".format(len(Flist),Cname)) 

Usage:

  labelcolor.py [color] *.jpg

où [couleur] est un nom ou l'abréviation défini ci-après:

    clear (c), grAy (a), green (g), purple (p), 
    blue (b), yellow (y), red (r), orange (o)
1
répondu beroe 2013-11-01 07:02:25

À Poser Des Différents

avec plusieurs réponses, dont l'une est acceptée :


ici, dans Stack Overflow la question a été soulevée un peu plus tôt (2013-11-01) donc je vais ajouter ma réponse ici.

openmeta

Open source à https://code.google.com/p/openmeta/source/browse/trunk/trunk/openmeta

la commande openmeta semble adopter une approche à double attribut, en travaillant avec les deux:

  • com.apple.metadata:kMDItemOMUserTags
  • com.apple.metadata:_kMDItemUserTags

exemple d'usage

sh-3.2$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.9.5
BuildVersion:   13F1096
sh-3.2$ uname -a
Darwin gpes3e-gjp4.local 13.4.0 Darwin Kernel Version 13.4.0: Wed Mar 18 16:20:14 PDT 2015; root:xnu-2422.115.14~1/RELEASE_X86_64 x86_64
sh-3.2$ date
Sun 26 Jul 2015 08:00:23 BST
sh-3.2$ rm ~/Desktop/test.txt 
sh-3.2$ touch ~/Desktop/test.txt 
sh-3.2$ xattr -l ~/Desktop/test.txt 
sh-3.2$ ./openmeta
openmeta version 0.1 by Tom Andersen code.google.com/p/openmeta/ 

Usage: openmeta [options] -p PATH[s] 

Note that commas are to be used nowhere - tag lists use quotes for two word tags in output

example (list tags and ratings):  openmeta -p PATH
example (list tags and ratings multiple):  openmeta -p PATH PATH
example (list tags): openmeta -t -p PATH[s]
example (add tags): openmeta -a foo bar -p PATH[s]
example (add tags with spaces): openmeta -a "three word tag" "foo bar" -p PATH[s]
example (set tags):  openmeta -s foo bar -p PATH[s]
example (clear all tags):  openmeta -s -p PATH[s]
example (set managed):  openmeta -m Y -p PATH[s]
example (set rating 0 - 5 stars):  openmeta -r 3.5 -p PATH[s]
example (print rating):  openmeta -r -p PATH[s]
example (clear rating):  openmeta -r 0.0 -p PATH[s]
example (lousy rating):  openmeta -r 0.1 -p PATH[s]
sh-3.2$ ./openmeta -a kerfuffle -p ~/Desktop/test.txt 
kerfuffle /Users/gjp22/Desktop/test.txt
sh-3.2$ ./openmeta -p ~/Desktop/test.txt 
/Users/gjp22/Desktop/test.txt
tags: kerfuffle
rating: none found

sh-3.2$ xattr -l ~/Desktop/test.txt 
com.apple.metadata:kMDItemOMUserTagTime:
00000000  62 70 6C 69 73 74 30 30 33 41 BB 64 BD 3C D4 95  |bplist003A.d.<..|
00000010  F2 08 00 00 00 00 00 00 01 01 00 00 00 00 00 00  |................|
00000020  00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00  |................|
00000030  00 11                                            |..|
00000032
com.apple.metadata:kMDItemOMUserTags:
00000000  62 70 6C 69 73 74 30 30 A1 01 59 6B 65 72 66 75  |bplist00..Ykerfu|
00000010  66 66 6C 65 08 0A 00 00 00 00 00 00 01 01 00 00  |ffle............|
00000020  00 00 00 00 00 02 00 00 00 00 00 00 00 00 00 00  |................|
00000030  00 00 00 00 00 14                                |......|
00000036
com.apple.metadata:_kMDItemUserTags:
00000000  62 70 6C 69 73 74 30 30 A1 01 5B 6B 65 72 66 75  |bplist00..[kerfu|
00000010  66 66 6C 65 0A 30 08 0A 00 00 00 00 00 00 01 01  |ffle.0..........|
00000020  00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 00  |................|
00000030  00 00 00 00 00 00 00 16                          |........|
00000038
kOM109SyncDone:
00000000  62 70 6C 69 73 74 30 30 09 08 00 00 00 00 00 00  |bplist00........|
00000010  01 01 00 00 00 00 00 00 00 01 00 00 00 00 00 00  |................|
00000020  00 00 00 00 00 00 00 00 00 09                    |..........|
0000002a
sh-3.2$ 

Limitations des autres services publics

Apple Finder, par exemple.

après avoir utilisé Finder pour supprimer le kerfuffle étiquette, kerfuffle reste comme une étiquette OpenMeta:

sh-3.2$ date ; xattr -l ~/Desktop/test.txt 
Sun 26 Jul 2015 08:02:13 BST
com.apple.metadata:kMDItemOMUserTagTime:
00000000  62 70 6C 69 73 74 30 30 33 41 BB 64 BD 3C D4 95  |bplist003A.d.<..|
00000010  F2 08 00 00 00 00 00 00 01 01 00 00 00 00 00 00  |................|
00000020  00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00  |................|
00000030  00 11                                            |..|
00000032
com.apple.metadata:kMDItemOMUserTags:
00000000  62 70 6C 69 73 74 30 30 A1 01 59 6B 65 72 66 75  |bplist00..Ykerfu|
00000010  66 66 6C 65 08 0A 00 00 00 00 00 00 01 01 00 00  |ffle............|
00000020  00 00 00 00 00 02 00 00 00 00 00 00 00 00 00 00  |................|
00000030  00 00 00 00 00 14                                |......|
00000036
com.apple.metadata:_kMDItemUserTags:
00000000  62 70 6C 69 73 74 30 30 A0 08 00 00 00 00 00 00  |bplist00........|
00000010  01 01 00 00 00 00 00 00 00 01 00 00 00 00 00 00  |................|
00000020  00 00 00 00 00 00 00 00 00 09                    |..........|
0000002a
kOM109SyncDone:
00000000  62 70 6C 69 73 74 30 30 09 08 00 00 00 00 00 00  |bplist00........|
00000010  01 01 00 00 00 00 00 00 00 01 00 00 00 00 00 00  |................|
00000020  00 00 00 00 00 00 00 00 00 09                    |..........|
0000002a
sh-3.2$ 

la Compréhension de ces limitations

avec attention aux domaines et aux conventions de nommage: réflexions des développeurs sur L'adoption du logiciel OpenMeta – Ironic (2009-03, et maintenant dans les archives Internet Wayback Machine) nous rappelle que com.apple.metadata était destiné à Apple quand OpenMeta (un projet pas dans le domaine apple.com ) a commencé l'approche com.apple.metadata:kMDItemOMUserTags orientée Apple.

donc je ne devrais pas m'attendre à ce que le logiciel Apple gagne ou maintienne la compatibilité avec les deux approches de marquage.


cas limites

dans certains cas, il peut être souhaitable de supprimer Pomme orientée com.apple.metadata:_kMDItemUserTags tags sans enlever OpenMeta orientée com.apple.metadata:kMDItemOMUserTags balises.

cependant, le faire-programmatiquement – dépasse probablement le cadre de la question posée par @nacross.

0
répondu Graham Perrin 2017-04-13 12:45:07

à partir de Mavericks, il est également possible de définir des tags de couleurs en cacao, en utilisant NSAppleScript .

NSURL *fileURL = [NSURL fileURLWithPath:@"/Users/sheaparis/Documents/filezilla_sites.xml"];

//Format the filepath for the AppleScript environment.
//  Without this, the file cannot be found.
NSString *filepath = [fileURL path];
NSString *appleScriptFilePath = [filepath stringByReplacingOccurrencesOfString:@"/" withString:@":"];
if ([appleScriptFilePath hasPrefix:@":"]) {
    appleScriptFilePath = [appleScriptFilePath substringFromIndex:1];
}
NSLog(@"appleScriptFilePath: %@", appleScriptFilePath);

//Tells Finder to set the Red color tag for the specified file
NSString *sourceString = [NSString stringWithFormat:
                          @"set theFile to \"%@\" as alias\n"
                          "tell application \"Finder\" to set label index of theFile to 2", appleScriptFilePath];
NSAppleScript *script = [[NSAppleScript alloc] initWithSource:sourceString];

NSDictionary *scriptErrorDict = nil;
[script executeAndReturnError:&scriptErrorDict];
if (scriptErrorDict) {
    NSLog(@"errorDict: %@", scriptErrorDict);
}

Si c'est exécutée sur un fichier qui n'a qu'une couleur, puis il efface la couleur, et définit la couleur spécifiée. Cependant, si plusieurs couleurs sont déjà définies sur le fichier, alors il ne nettoie pas les couleurs existantes avant de définir la couleur spécifiée.

utilisant l'environnement AppleScript , la cartographie des couleurs est la suivante:

  • 0: Aucun
  • 1: Orange
  • 2: rouge
  • 3: jaune
  • 4: Bleu
  • 5: Pourpre
  • 6: Vert
  • 7: Grey
0
répondu Sheamus 2016-03-21 08:37:51

à partir de Mavericks, il est possible d'obtenir et de définir des étiquettes de couleur en cacao, en utilisant NSURL .

NSURL possède un grand nombre de propriétés qui peuvent être définies ou lues, à travers les méthodes respectives setResourceValue:forKey:error: et getResourceValue:forKey:error: .

en utilisant la touche NSURLLabelNumberKey , vous pouvez définir les balises de couleur, comme suit:

NSURL *fileURL = [NSURL fileURLWithPath:@"/Users/[username]/Documents/[some_file]"];
NSError *resourceError;
if (![fileURL setResourceValue:@(2) forKey:NSURLLabelNumberKey error:&resourceError]) {
    NSLog(@"Error while setting file resource: %@", [resourceError localizedDescription]);
}

Si c'est exécutée sur un fichier qui n'a qu'une couleur, puis il efface la couleur, et définit la couleur spécifiée. Cependant, si plusieurs couleurs sont déjà définies sur le fichier, alors il ne nettoie pas les couleurs existantes avant de définir la couleur spécifiée.

Voici la cartographie valeur-couleur (sur El Capitan):

  • @(0): néant 1519240920"
  • @(1): Grey
  • @(2): Vert
  • @(3): Violet
  • @(4): Bleu
  • @(5): Jaune
  • @(6): Rouge
  • @(7): Orange

Je n'ai pas été en mesure de définir une étiquette en utilisant NSURLLabelColorKey . Voici mon expérience sur El Capitan, avec les clés liées aux 'tags' (couleurs):

  • NSURLLabelNumberKey : peut être lu / réglé avec succès, avec des nombres 0-7. Tout autre nombre retournera une erreur. S'il y a plusieurs tags définis, alors cela retournera l'index du première couleur qui est définie, car il recherche numériquement à travers les index 1 à 7. Bien que vous pouvez effacer une couleur dans Finder en cliquant sur la couleur, le réglage programmatique d'une couleur qui est déjà réglée ne clarifie pas cette couleur.
  • NSURLLabelColorKey : renvoie zéro, même si une étiquette de couleur est définie pour un fichier. Définir une valeur avec cette clé n'a aucun effet.
  • NSURLTagNamesKey : renvoie un tableau des noms de couleur pour les tags qui sont définis.
0
répondu Sheamus 2016-03-21 08:38:20