Xattr: Difference between revisions
No edit summary |
No edit summary |
||
| (5 intermediate revisions by the same user not shown) | |||
| Line 1: | Line 1: | ||
Xattr tags are "eXtended | Xattr tags are "eXtended ATTRibute" tags, which is a feature of MacOS 10.4 or later. They're like "spotlight comments" in that they are a type of meta tagging facility built into the file system when seen thru the lense of the Mac OS. (they also work on FAT32 volumes with the "._" prefixed sidecar file). For the most fantastic explanation ever, see the [http://arstechnica.com/apple/reviews/2005/04/macosx-10-4.ars/7 Ars Techica] article on it. | ||
Anyway I use xattr tags currently on all QuickTime compatible files that do not have the ".mov" extension, and also on zip files so i do not need to open the zip to get at the tagging info. Here is what my xattr looks like: | Anyway I use xattr tags currently on all QuickTime compatible files <strike>that do not have the ".mov" extension</strike>, and also on zip files so i do not need to open the zip to get at the tagging info. Here is what my xattr looks like: | ||
[oxford:kj/media/bin] davec% xattr - | [oxford:kj/media/bin] davec% xattr -l "Rave On.bin" | ||
Rave On.bin | Rave On.bin | ||
com.meta.albm Unknown Album | com.meta.albm Unknown Album | ||
| Line 16: | Line 16: | ||
Note: It's a very simple format, I'm just using QuickTime “Common Key Format” tag names (from Movies.h) as the keys (prepended with "com.meta."). I've added a few others: | Note: It's a very simple format, I'm just using QuickTime “Common Key Format” tag names (from Movies.h) as the keys (prepended with "com.meta."). I've added a few others: | ||
<pre> | <pre> | ||
/* | |||
kQTMetaDataCommonKeyAuthor = 'auth', | |||
kQTMetaDataCommonKeyComment = 'cmmt', | |||
kQTMetaDataCommonKeyCopyright = 'cprt', | |||
kQTMetaDataCommonKeyDirector = 'dtor', | |||
kQTMetaDataCommonKeyDisplayName = 'name', | |||
kQTMetaDataCommonKeyInformation = 'info', | |||
kQTMetaDataCommonKeyKeywords = 'keyw', | |||
kQTMetaDataCommonKeyProducer = 'prod', | |||
kQTMetaDataCommonKeyAlbum = 'albm', | |||
kQTMetaDataCommonKeyArtist = 'arts', | |||
kQTMetaDataCommonKeyArtwork = 'artw', | |||
kQTMetaDataCommonKeyChapterName = 'chap', | |||
kQTMetaDataCommonKeyComposer = 'comp', | |||
kQTMetaDataCommonKeyDescription = 'desc', | |||
kQTMetaDataCommonKeyGenre = 'genr', | |||
kQTMetaDataCommonKeyOriginalFormat = 'orif', | |||
kQTMetaDataCommonKeyOriginalSource = 'oris', | |||
kQTMetaDataCommonKeyPerformers = 'perf', | |||
kQTMetaDataCommonKeySoftware = 'soft', | |||
kQTMetaDataCommonKeyWriter = 'wrtr' | |||
*/ | |||
enum { | enum { | ||
CM_Key_TESTAMUNDO = 'tmdo', // bool | |||
CM_Key_NONE = 'xxxx', | |||
CM_Key_ALL = '****', | |||
CM_Key_NAME = kQTMetaDataCommonKeyDisplayName, // 'name', | CM_Key_NAME = kQTMetaDataCommonKeyDisplayName, // 'name', | ||
CM_Key_ARTIST = kQTMetaDataCommonKeyArtist, // 'arts', | CM_Key_ARTIST = kQTMetaDataCommonKeyArtist, // 'arts', | ||
| Line 27: | Line 50: | ||
CM_Key_GENRE = kQTMetaDataCommonKeyGenre, // 'genr', | CM_Key_GENRE = kQTMetaDataCommonKeyGenre, // 'genr', | ||
CM_Key_COMMENT = kQTMetaDataCommonKeyComment, // 'cmmt', | CM_Key_COMMENT = kQTMetaDataCommonKeyComment, // 'cmmt', | ||
CM_Key_KEYWORDS = kQTMetaDataCommonKeyKeywords, // | CM_Key_KEYWORDS = kQTMetaDataCommonKeyKeywords, // 'keyw' | ||
CM_Key_SOFTWARE = kQTMetaDataCommonKeySoftware, // | CM_Key_SOFTWARE = kQTMetaDataCommonKeySoftware, // 'soft' | ||
CM_Key_WRITER = kQTMetaDataCommonKeyWriter, // 'wrtr' | |||
CM_Key_COPYRIGHT = kQTMetaDataCommonKeyCopyright, // 'cprt' | |||
CM_Key_SORT_NAME = 'Snam', | |||
CM_Key_SORT_ARTIST = 'Sart', | |||
CM_Key_SORT_ALBUM = 'Salb', | |||
CM_Key_CUSTOM = 'cust', | |||
CM_Key_PLI_INDEX = 'piIx', // int | CM_Key_CUSTOM_NUM = 'cstN', | ||
CM_Key_SUB_GENRE = 'SUBg', // string | |||
CM_Key_SwitchableAlbum_Dict = 'LDct', // list of albums for popup menu, including default index value | |||
CM_Key_SwitchableSongs_Dict = 'SDct', // list of songs for popup menu, including default index value | |||
CM_Key_PLI_INDEX = 'piIx', // int, same as PLI_ID | |||
CM_Key_SORT_INDEX = 'stIx', // int | CM_Key_SORT_INDEX = 'stIx', // int | ||
CM_Key_DUET = 'Duet', // bool | CM_Key_DUET = 'Duet', // bool | ||
CM_Key_DUET_STR = 'DueS', // STR | |||
CM_Key_BITRATE = 'bRat', // string | |||
CM_Key_DOWNLOAD = 'dl ', // bool | |||
CM_Key_STREAM = 'strm', // bool | |||
CM_Key_TIER = 'Tier', // string | |||
CM_Key_TWIRLED = 'Twrl', // bool | CM_Key_TWIRLED = 'Twrl', // bool | ||
CM_Key_KEY = 'Keyc', // | CM_Key_LANGUAGE = 'Lang', // string | ||
CM_Key_KEY = 'Keyc', // string | |||
CM_Key_KEY_CHANGES = 'KeCH', // string | |||
CM_Key_VOLUME = 'volm', // float | CM_Key_VOLUME = 'volm', // float | ||
CM_Key_LABEL = 'colr', // integer | |||
CM_Key_RATING = 'rtng', // integer | CM_Key_RATING = 'rtng', // integer | ||
CM_Key_GRAPHIC_CHANNELS = 'gChn', // integer | CM_Key_GRAPHIC_CHANNELS = 'gChn', // integer | ||
| Line 47: | Line 90: | ||
CM_Key_PIPE_TYPE = 'mPip', // int MetaPipeType | CM_Key_PIPE_TYPE = 'mPip', // int MetaPipeType | ||
CM_Key_PUSH_LEVEL = 'mPsh', // int meta push level | CM_Key_PUSH_LEVEL = 'mPsh', // int meta push level | ||
CM_Key_SONG_ID = 'soID', // int | CM_Key_SONG_ID = 'soID', // int | ||
CM_Key_SINGER_ID = 'siID', // int | CM_Key_SINGER_ID = 'siID', // int | ||
CM_Key_PLAYLIST_ID = 'plID', // int | CM_Key_PLAYLIST_ID = 'plID', // int | ||
CM_Key_SINGER_PLI = 'sPLI', // int | |||
CM_Key_TEMP_PLID = 'sTid', // long used for music stores and CDs | |||
CM_Key_FORMAT = 'Frmt', // string | CM_Key_FORMAT = 'Frmt', // string | ||
CM_Key_COPY_META_FLAGS = 'cMfl', // int, based on CM_Key_FORMAT | |||
CM_Key_SOURCE = 'SRCE', | CM_Key_SOURCE = 'SRCE', | ||
CM_Key_TRACK = 'trak', | CM_Key_TRACK = 'trak', // int | ||
CM_Key_YEAR = 'cryr', // int (NOT date) | CM_Key_YEAR = 'cryr', // int (NOT date) | ||
CM_Key_DURATION = 'drtn', // int | CM_Key_ORIG_YEAR = 'ORyr', // int (NOT date) | ||
CM_Key_START = 'strt', // int sectors | |||
CM_Key_DURATION = 'drtn', // int sectors | |||
CM_Key_PREVIEW_DURATION = 'pDrn', // int sectors | |||
CM_Key_SKIP_SILENCE_END = 'ssNd', // int subcodes (records) | |||
CM_Key_TRIM_START = 'Tsrt', // int subcodes | |||
CM_Key_TRIM_END = 'Tend', // int subcodes | |||
CM_Key_TIMES_SUNG = 'tsng', // integer, times sung | CM_Key_TIMES_SUNG = 'tsng', // integer, times sung | ||
CM_Key_SIZE = 'SIZE', | CM_Key_SIZE = 'SIZE', // int | ||
CM_Key_DATE_LAST_SUNG = 'Date', | CM_Key_DATE_LAST_SUNG = 'Date', // date | ||
CM_Key_PLAY_ME = 'PLME', | CM_Key_DATE_ADDED = 'DAdd', // date | ||
CM_Key_PLAY_ME = 'PLME', // bool | |||
CM_Key_PITCH = 'PICH', // int | |||
CM_Key_CENTS = 'cent', // float | |||
CM_Key_TEMPO = 'TMPO', | CM_Key_BPM = 'bpm ', // int | ||
CM_Key_TEMPO = 'TMPO', // float | |||
CM_Key_MISSING = 'Msng', // bool | |||
CM_Key_SINGER_PASS = 'Spas', | CM_Key_NO_CDG = 'nCDG', // bool | ||
CM_Key_PRODUCER_DICT = 'prod', | CM_Key_IGNORE_RS_ERR = 'igRS', // bool ignore reed-solomon error correction | ||
CM_Key_SINGER = 'SNGR', // string | |||
CM_Key_SINGER_NICK = 'nick', // string | |||
CM_Key_SINGER_PASS = 'Spas', // string | |||
CM_Key_SINGER_SMS_ENABLE = 'SmsB', // bool | |||
CM_Key_SINGER_SMS_REGION = 'SmsR', // string | |||
CM_Key_SINGER_SMS_CARRIER = 'SmsC', // string | |||
CM_Key_SINGER_SMS_NUMBER = 'SmsN', // string | |||
CM_Key_BIO = 'Bio ', // string | |||
CM_Key_PRESENT = 'PSNT', // bool | |||
CM_Key_PLI_SORT_TO_TOP = 'pStt', // bool // not stored in PLI, but directly in Singer or PlayList | |||
CM_Key_SINGER_IS_KJ = 'sgKJ', // bool | |||
CM_Key_PRODUCER_DICT = 'prod', // dictinary | |||
CM_Key_MEDIA_STREAM = 'meSt', // dictinary | |||
CM_Key_SONGWRITER = 'swrt', // string | |||
CM_Key_GENDER = 'gndr', // string | |||
CM_Key_COMPOSER = 'cpsr', // string | |||
CM_Key_PUBLISHER = 'pbls', // string | |||
CM_Key_ORIGINAL_PUBLISHER = 'ORpb', // string | |||
CM_Key_ACTUAL_DURATION = 'aDur', // string | |||
CM_Key_RENDITION = 'rdtn', // string | |||
CM_Key_BACKING_VOCALS = 'bVoc', // bool | |||
CM_Key_LEAD_VOCALS = 'lVoc', // bool (center channel lead vocals) | |||
CM_Key_VOCAL_CHANNEL = 'vChn', // integer | |||
CM_Key_COLOR_BACKGROUND = 'cBak', // string | |||
CM_Key_EXPLICIT = 'Expl', // bool, parental advisory lyrics | |||
CM_Key_CAVS_TYPE = 'cavT', | CM_Key_SONG_SLIP = 'Slip', // int | ||
CM_Key_CAVS_DATA = 'cavD', | CM_Key_CAVS_TYPE = 'cavT', // int | ||
CM_Key_CAVS_DATA = 'cavD', // cfdata | |||
CM_Key_FSRef_0_AUDIO = 'Sfs0', // CData::ValType_FILEREF | CM_Key_FSRef_0_AUDIO = 'Sfs0', // CData::ValType_FILEREF | ||
| Line 88: | Line 170: | ||
CM_Key_FSRef_8_UNPACK = 'Sfs8', | CM_Key_FSRef_8_UNPACK = 'Sfs8', | ||
CM_Key_FSRef_9_TEMP_ZIP = 'Sfs9', | CM_Key_FSRef_9_TEMP_ZIP = 'Sfs9', | ||
CM_Key_FSRef_10_PROJ = 'Sf10', | |||
CM_Key_FSRef_11_LAUNCH = 'Sf11', | |||
// store related | |||
CM_Key_STORE_NAME = 'StrN', // string | |||
CM_Key_STORE_NUM_SONGS = 'SNmS', // long | |||
CM_Key_STORE_URL = 'sURL', // string | |||
CM_Key_STORE_ID = 'stor', // long | |||
CM_Key_SAMPLE = 'Smpl', // string | |||
CM_Key_STREAMING_URL = 'stmR', // string | |||
CM_Key_PRICE_USD = 'pUSD', // string | |||
CM_Key_PRICE_USD_FREE = 'USDf', | |||
CM_Key_PRICE_USD_STREAM = 'USDs', | |||
CM_Key_PRICE_USD_BUY_STREAM = 'USDb', | |||
CM_Key_PURCHASE_CODE = 'pTRI', // string | |||
CM_Key_PURCHASED = 'purc', // bool | |||
CM_Key_MUST_COMPLETE_PURCHASE = 'CplP', // bool | |||
CM_Key_PLAY_AFTER_PURCHASE = 'PlaP', // bool | |||
CM_Key_RECENT = 'Rcnt', // bool | |||
CM_Key_STORE_SONG_ID = 'SsID', // long | |||
CM_Key_STORE_CUSTOM_ID = 'ScID', // long | |||
CM_Key_SONG_PAGE_URL = 'spRL', // string | |||
CM_Key_SONG_NO_SYNCED_LYRICS = 'sNSL', // bool | |||
CM_Key_SORT_INDEX_ROTATION = 'rotn', | |||
CM_Key_ALPHA_LABEL = 'ALFA' | |||
}; | }; | ||
</pre> | </pre> | ||
For compatibility with 10.3 I'm using a standard plist sidecar file (XML) with the ".xattr" extension, which can be easily edited with any [http://www.barebones.com/products/bbedit/ text editor], [http://donkeydevelopment.com/ XML editor], or [http://www.fatcatsoftware.com/plisteditpro/ plist editor]. | For compatibility with 10.3 I'm using a standard plist sidecar file (XML) with the ".xattr" extension, which can be easily edited with any [http://www.barebones.com/products/bbedit/ text editor], [http://donkeydevelopment.com/ XML editor], or [http://www.fatcatsoftware.com/plisteditpro/ plist editor]. | ||
Latest revision as of 19:36, 20 April 2016
Xattr tags are "eXtended ATTRibute" tags, which is a feature of MacOS 10.4 or later. They're like "spotlight comments" in that they are a type of meta tagging facility built into the file system when seen thru the lense of the Mac OS. (they also work on FAT32 volumes with the "._" prefixed sidecar file). For the most fantastic explanation ever, see the Ars Techica article on it.
Anyway I use xattr tags currently on all QuickTime compatible files that do not have the ".mov" extension, and also on zip files so i do not need to open the zip to get at the tagging info. Here is what my xattr looks like:
[oxford:kj/media/bin] davec% xattr -l "Rave On.bin"
Rave On.bin
com.meta.albm Unknown Album
com.meta.arts Buddy Holly
com.meta.crdt 2006
com.meta.genr Rock
com.meta.name Rave On
com.meta.soft kJams Pro 1.0d45r21
com.meta.trak 1
[oxford:kj/media/bin] davec%
Note: It's a very simple format, I'm just using QuickTime “Common Key Format” tag names (from Movies.h) as the keys (prepended with "com.meta."). I've added a few others:
/*
kQTMetaDataCommonKeyAuthor = 'auth',
kQTMetaDataCommonKeyComment = 'cmmt',
kQTMetaDataCommonKeyCopyright = 'cprt',
kQTMetaDataCommonKeyDirector = 'dtor',
kQTMetaDataCommonKeyDisplayName = 'name',
kQTMetaDataCommonKeyInformation = 'info',
kQTMetaDataCommonKeyKeywords = 'keyw',
kQTMetaDataCommonKeyProducer = 'prod',
kQTMetaDataCommonKeyAlbum = 'albm',
kQTMetaDataCommonKeyArtist = 'arts',
kQTMetaDataCommonKeyArtwork = 'artw',
kQTMetaDataCommonKeyChapterName = 'chap',
kQTMetaDataCommonKeyComposer = 'comp',
kQTMetaDataCommonKeyDescription = 'desc',
kQTMetaDataCommonKeyGenre = 'genr',
kQTMetaDataCommonKeyOriginalFormat = 'orif',
kQTMetaDataCommonKeyOriginalSource = 'oris',
kQTMetaDataCommonKeyPerformers = 'perf',
kQTMetaDataCommonKeySoftware = 'soft',
kQTMetaDataCommonKeyWriter = 'wrtr'
*/
enum {
CM_Key_TESTAMUNDO = 'tmdo', // bool
CM_Key_NONE = 'xxxx',
CM_Key_ALL = '****',
CM_Key_NAME = kQTMetaDataCommonKeyDisplayName, // 'name',
CM_Key_ARTIST = kQTMetaDataCommonKeyArtist, // 'arts',
CM_Key_ALBUM = kQTMetaDataCommonKeyAlbum, // 'albm',
CM_Key_GENRE = kQTMetaDataCommonKeyGenre, // 'genr',
CM_Key_COMMENT = kQTMetaDataCommonKeyComment, // 'cmmt',
CM_Key_KEYWORDS = kQTMetaDataCommonKeyKeywords, // 'keyw'
CM_Key_SOFTWARE = kQTMetaDataCommonKeySoftware, // 'soft'
CM_Key_WRITER = kQTMetaDataCommonKeyWriter, // 'wrtr'
CM_Key_COPYRIGHT = kQTMetaDataCommonKeyCopyright, // 'cprt'
CM_Key_SORT_NAME = 'Snam',
CM_Key_SORT_ARTIST = 'Sart',
CM_Key_SORT_ALBUM = 'Salb',
CM_Key_CUSTOM = 'cust',
CM_Key_CUSTOM_NUM = 'cstN',
CM_Key_SUB_GENRE = 'SUBg', // string
CM_Key_SwitchableAlbum_Dict = 'LDct', // list of albums for popup menu, including default index value
CM_Key_SwitchableSongs_Dict = 'SDct', // list of songs for popup menu, including default index value
CM_Key_PLI_INDEX = 'piIx', // int, same as PLI_ID
CM_Key_SORT_INDEX = 'stIx', // int
CM_Key_DUET = 'Duet', // bool
CM_Key_DUET_STR = 'DueS', // STR
CM_Key_BITRATE = 'bRat', // string
CM_Key_DOWNLOAD = 'dl ', // bool
CM_Key_STREAM = 'strm', // bool
CM_Key_TIER = 'Tier', // string
CM_Key_TWIRLED = 'Twrl', // bool
CM_Key_LANGUAGE = 'Lang', // string
CM_Key_KEY = 'Keyc', // string
CM_Key_KEY_CHANGES = 'KeCH', // string
CM_Key_VOLUME = 'volm', // float
CM_Key_LABEL = 'colr', // integer
CM_Key_RATING = 'rtng', // integer
CM_Key_GRAPHIC_CHANNELS = 'gChn', // integer
CM_Key_COOP_THREAD = 'Coop', // bool, must be extracted on a cooperative thread
CM_Key_DEMUX_MPEG = 'Muxd', // bool, must be demuxed
CM_Key_PIPE_TYPE = 'mPip', // int MetaPipeType
CM_Key_PUSH_LEVEL = 'mPsh', // int meta push level
CM_Key_SONG_ID = 'soID', // int
CM_Key_SINGER_ID = 'siID', // int
CM_Key_PLAYLIST_ID = 'plID', // int
CM_Key_SINGER_PLI = 'sPLI', // int
CM_Key_TEMP_PLID = 'sTid', // long used for music stores and CDs
CM_Key_FORMAT = 'Frmt', // string
CM_Key_COPY_META_FLAGS = 'cMfl', // int, based on CM_Key_FORMAT
CM_Key_SOURCE = 'SRCE',
CM_Key_TRACK = 'trak', // int
CM_Key_YEAR = 'cryr', // int (NOT date)
CM_Key_ORIG_YEAR = 'ORyr', // int (NOT date)
CM_Key_START = 'strt', // int sectors
CM_Key_DURATION = 'drtn', // int sectors
CM_Key_PREVIEW_DURATION = 'pDrn', // int sectors
CM_Key_SKIP_SILENCE_END = 'ssNd', // int subcodes (records)
CM_Key_TRIM_START = 'Tsrt', // int subcodes
CM_Key_TRIM_END = 'Tend', // int subcodes
CM_Key_TIMES_SUNG = 'tsng', // integer, times sung
CM_Key_SIZE = 'SIZE', // int
CM_Key_DATE_LAST_SUNG = 'Date', // date
CM_Key_DATE_ADDED = 'DAdd', // date
CM_Key_PLAY_ME = 'PLME', // bool
CM_Key_PITCH = 'PICH', // int
CM_Key_CENTS = 'cent', // float
CM_Key_BPM = 'bpm ', // int
CM_Key_TEMPO = 'TMPO', // float
CM_Key_MISSING = 'Msng', // bool
CM_Key_NO_CDG = 'nCDG', // bool
CM_Key_IGNORE_RS_ERR = 'igRS', // bool ignore reed-solomon error correction
CM_Key_SINGER = 'SNGR', // string
CM_Key_SINGER_NICK = 'nick', // string
CM_Key_SINGER_PASS = 'Spas', // string
CM_Key_SINGER_SMS_ENABLE = 'SmsB', // bool
CM_Key_SINGER_SMS_REGION = 'SmsR', // string
CM_Key_SINGER_SMS_CARRIER = 'SmsC', // string
CM_Key_SINGER_SMS_NUMBER = 'SmsN', // string
CM_Key_BIO = 'Bio ', // string
CM_Key_PRESENT = 'PSNT', // bool
CM_Key_PLI_SORT_TO_TOP = 'pStt', // bool // not stored in PLI, but directly in Singer or PlayList
CM_Key_SINGER_IS_KJ = 'sgKJ', // bool
CM_Key_PRODUCER_DICT = 'prod', // dictinary
CM_Key_MEDIA_STREAM = 'meSt', // dictinary
CM_Key_SONGWRITER = 'swrt', // string
CM_Key_GENDER = 'gndr', // string
CM_Key_COMPOSER = 'cpsr', // string
CM_Key_PUBLISHER = 'pbls', // string
CM_Key_ORIGINAL_PUBLISHER = 'ORpb', // string
CM_Key_ACTUAL_DURATION = 'aDur', // string
CM_Key_RENDITION = 'rdtn', // string
CM_Key_BACKING_VOCALS = 'bVoc', // bool
CM_Key_LEAD_VOCALS = 'lVoc', // bool (center channel lead vocals)
CM_Key_VOCAL_CHANNEL = 'vChn', // integer
CM_Key_COLOR_BACKGROUND = 'cBak', // string
CM_Key_EXPLICIT = 'Expl', // bool, parental advisory lyrics
CM_Key_SONG_SLIP = 'Slip', // int
CM_Key_CAVS_TYPE = 'cavT', // int
CM_Key_CAVS_DATA = 'cavD', // cfdata
CM_Key_FSRef_0_AUDIO = 'Sfs0', // CData::ValType_FILEREF
CM_Key_FSRef_1_VIDEO = 'Sfs1',
CM_Key_FSRef_2_ZIP = 'Sfs2',
CM_Key_FSRef_3_AUD_CACHE = 'Sfs3',
CM_Key_FSRef_4_VID_CACHE = 'Sfs4',
CM_Key_FSRef_5_META = 'Sfs5',
CM_Key_FSRef_6_AUD_CD = 'Sfs6',
CM_Key_FSRef_7_VID_CD = 'Sfs7',
CM_Key_FSRef_8_UNPACK = 'Sfs8',
CM_Key_FSRef_9_TEMP_ZIP = 'Sfs9',
CM_Key_FSRef_10_PROJ = 'Sf10',
CM_Key_FSRef_11_LAUNCH = 'Sf11',
// store related
CM_Key_STORE_NAME = 'StrN', // string
CM_Key_STORE_NUM_SONGS = 'SNmS', // long
CM_Key_STORE_URL = 'sURL', // string
CM_Key_STORE_ID = 'stor', // long
CM_Key_SAMPLE = 'Smpl', // string
CM_Key_STREAMING_URL = 'stmR', // string
CM_Key_PRICE_USD = 'pUSD', // string
CM_Key_PRICE_USD_FREE = 'USDf',
CM_Key_PRICE_USD_STREAM = 'USDs',
CM_Key_PRICE_USD_BUY_STREAM = 'USDb',
CM_Key_PURCHASE_CODE = 'pTRI', // string
CM_Key_PURCHASED = 'purc', // bool
CM_Key_MUST_COMPLETE_PURCHASE = 'CplP', // bool
CM_Key_PLAY_AFTER_PURCHASE = 'PlaP', // bool
CM_Key_RECENT = 'Rcnt', // bool
CM_Key_STORE_SONG_ID = 'SsID', // long
CM_Key_STORE_CUSTOM_ID = 'ScID', // long
CM_Key_SONG_PAGE_URL = 'spRL', // string
CM_Key_SONG_NO_SYNCED_LYRICS = 'sNSL', // bool
CM_Key_SORT_INDEX_ROTATION = 'rotn',
CM_Key_ALPHA_LABEL = 'ALFA'
};
For compatibility with 10.3 I'm using a standard plist sidecar file (XML) with the ".xattr" extension, which can be easily edited with any text editor, XML editor, or plist editor.