Openmeta tags

Hi,
I want to get the tags (openmeta tags-not photo or music tags) on my HD; unfortunately:
mdfind
outputs only tagged files of a certain tag, but I want the entire list of existing tags.

‘mdls’ will give you the list of tags for individual files:

set file_hpath to "Santanni:Users:thijs:Desktop:Inbox:"
set file_ppath to quoted form of (POSIX path of file_hpath)
set theTags to do shell script "mdls -name kMDItemOMUserTags " & file_ppath
(*
"kMDItemOMUserTags = (
    6,
    null,
    mixed,
    3,
    \"06-09-2010 08:00:00\",
    false
)"
*)

Hi alastor933,

thanks for your time. I found something similar on mac OsX hints:

http://hints.macworld.com/article.php?story=20050614131955346

but it isn’t what i really want. Maybe mdimport? just now i’m consulting some documents.

As far as I remember, openmeta store tags (also) as extended attributes. If that is the case, you may try to adapt the following script:


on getMetadataKeys(theFile)
	local theKeys
	set theKeys to do shell script "xattr " & quoted form of POSIX path of theFile
	set tid to AppleScript's text item delimiters
	set AppleScript's text item delimiters to character id 13 -- new line
	set theKeys to the text items of theKeys
	set AppleScript's text item delimiters to tid
	theKeys
end getMetadataKeys

on getMetadata(theFile, theKey)
	do shell script "xattr -p " & theKey & " " & quoted form of POSIX path of theFile
end getMetadata

set aFile to choose file

set theKeys to getMetadataKeys(aFile)

set theValues to {}
repeat with k in theKeys
	set the end of theValues to getMetadata(aFile, k)
end repeat
theValues

The above extracts all the (visible) extended attributes, not only those added by OpenMeta. But you can easily identify them, because their keys start with org.openmetainfo (unless OpenMeta’s specification has changed recently). Once you get the value you’re interested in, you need to parse it to extract the tags. This may not be so trivial, as they are stored in binary, if I am correct. To use the above script you don’t need anything else, because xattr is part of Mac OS X (at least since Leopard).

Alternatively, there is a command-line tool called openmeta (http://code.google.com/p/openmeta/downloads/list) that can be used instead, and which will give you the tags directly:


property openmeta : "/Here/goes/the/path/to/openmeta"

on getOpenMetaTags(theFile)
	local theTags
	set theTags to do shell script openmeta & " -t -p " & quoted form of POSIX path of theFile
	set tid to AppleScript's text item delimiters
	set AppleScript's text item delimiters to character id 32 -- space
	set theTags to the text items of theTags
	set AppleScript's text item delimiters to tid
	return items 1 thru -2 of theTags
end getOpenMetaTags

set aFile to choose file

set myTags to getOpenMetaTags(aFile)

This is certainly more convenient and immune to changes in the specification.

[EDIT: the above assumes that the tags do not contain spaces]

That first script returns hex data here - not what Joy would enjoy, I think.

The second yields a neat A/S list, which seems very satisfactory.
There’s a catch, though.
To allow multi-word tags you enclose them in double quotes, see the date tag in the sample I posted.
Splitting openmeta’s reply on spaces destroys those tags.

Splitting my sample on quotes gives me this:
{"6 null mixed 3 “, “06-09-2010 08:00:00”, " false /Users/thijs/Desktop/Inbox/”} ,
with the date tag intact.

The 2nd item, without spaces at its start or end, is the quoted (two-word) tag.
Fishing those out of a list, and splitting the other items on spaces makes it a bit more complicated.

I tinkered a bit, recently, with ‘awk’ and ‘tr’ to get the tags from the mdls reply into a list, with little success - that was the first time I tried to use those commands. There may be others more suitable, I wouldn’t know.

@ Druido,

awesome!
its really kind from you to share this thoughts with us.

:cool:

@ alastor933

thanks nevertheless

The following (pure AppleScript) version of my subroutine deals with tags with spaces. It assumes that tags do not contain double quotes, though.


on getOpenMetaTags(theFile)
	local openmeta, tagtext, taglist, Tags, tid, e
	
	set openmeta to "/Here/goes/the/path/to/openmeta"
	set tagtext to do shell script openmeta & " -t -p " & quoted form of POSIX path of theFile
	set tid to AppleScript's text item delimiters
	-- Split at closing quote
	-- Closing quotes can be recognized because they are always followed by a space
	set AppleScript's text item delimiters to {quote & " "}
	set taglist to the text items of tagtext
	-- Now, every item, but the last, must contain a corresponding opening quote
	-- Split at the opening quote
	set AppleScript's text item delimiters to {" " & quote, quote}
	repeat with e in taglist
		set e's contents to the text items of e
	end repeat
	-- Finally, every item of taglist, but the last, is a list with two elements: the first is either empty or a space-separated list of simple tags, and the second is a compound tag
	set AppleScript's text item delimiters to {" "}
	set Tags to {}
	repeat with e in taglist
		if length of e > 1 then
			set Tags to Tags & the text items of the first item of e
			set the end of Tags to the second item of e
		else
			-- Last item: it contains a list of space-separated simple tags followed by the file path, which we must get rid of 
			set e to the text items of the first item of e
			if length of e > 1 then
				set Tags to the Tags & items 1 thru -2 of e
			end if
		end if
	end repeat
	set AppleScript's text item delimiters to tid
	return Tags
end getOpenMetaTags


Extra-neat!

Running on my Inbox:

set myTags to getOpenMetaTags(aFile)--> (*6, null, mixed, 3, 06-09-2010 08:00:00, false*)
date (item 5 of myTags)--> date "maandag 6 september 2010 08:00:00"

Getting that date back as date object makes it super-extra neat.
Structured tagging looks doable again, thank you :slight_smile:

	-- Split at the opening quote
	set AppleScript's text item delimiters to {" " & quote, quote}

Um, looks like that second ‘quote’ is not needed. Or is it?
I get the same result, with or without.

[later]
Darn…
It only works with files/folders with space-less names.
We must first chop off the path string:

set openmetaReply to "6 null mixed 3 \"06-09-2010 08:00:00\" false /Users/thijs/Desktop/this is not my Inbox/"
set text item delimiters to {space & "/"} -- always beginning of POSIX path in openmeta's reply
set tagtext to text items 1 thru -2 of openmetaReply
set text item delimiters to ""
tagtext--> {"6 null mixed 3 \"06-09-2010 08:00:00\" false"}

You can give openmeta a list of paths (says its help page).
I’m not going to provide for that; the script can feed in the files one by one.

Hi guys,
usually I tend to work on several scripts, some bigger, some litter per day, so i’m split between several ideas around.
Also with little patience, I fete sometimes too soon as necessary, like for this topic.
I get similar results with my script below, collecting tags of a bunch of files.
But it isn’t what I want. I read about šxattr˜, the OpenMeta forums of google code project, other resources in man pages relevant to collect OMTags, and i’m not a bit wiser than before, how to gather tags through spotlight shells into my script.

The reason behind this research is to catch forgotten tags for managing these. So I become familiar with the variety of tags I deal with into the time and learn to set properly tags. Thats it.
Usually Tag applications gather informations through spotlight, but which commands they call to get all tags (system vide, not only file related- tats the salt in the tea) rests a misterium for me. A snipped from my script:

tell application "Finder" to set file_path to the selection

set tag_ls to {}
repeat with i in file_path
	set the_file to i as text
	set file_path to quoted form of (POSIX path of the_file)
	set theTags to do shell script "mdls -name kMDItemOMUserTags " & file_path
	
--
set rest_of to (words 3 thru -1 of theTags)
	
	--filter unique tags
	repeat with a in rest_of
		set a to a as text
		if a is not in tag_ls then copy a to end of tag_ls
	end repeat
end repeat
return tag_ls

OpenMeta keeps a backup of its stored metadata in ~/Library/Application Support/OpenMeta/backups. If you need to retrieve all the metatags for all your files anywhere in your hard disk, the most efficient way is probably to look there. A backup file is just an XML file, which you can easily parse with AppleScript (possibly search this forum for threads about that). But better advice on how to collect all the tags you would almost certainly obtain by asking to the OpenMeta mailing list.

Joy,
What tagging app do you use?
If it’s any good it should be able to show you all your tags, forgotten or not.
Leap does that, I never looked at others.

OM’s backups are per-file, and it looks like Leap backs up everything anytime it runs.
So, a lot of files in a lot of folders. Don’t think there’s much to gain here.
Except that each tag is represented as a key:value pair in those backups, so no text parsing is needed.

Heyhey,
a new challenge for me to learn something about the famous xml-format! :slight_smile:
thats it… i’ll do it in some way!
I use a great and self-sufficient Tag application (which i counsel everybody) called simply “Tagger”:

http://hasseg.org/tagger/

A worthy undertaking, but xml parsing (as an exercise) is not much different from text parsing (albeit there are osaxen to help with that).

Another method uses System Events. This scriplet will open the OpenMeta backup folder, and let you select a file.
It returns the content as an A/S record.

set ombackFolder to (((path to application support folder from user domain) as text) & "OpenMeta:backups.noindex:") as alias

set ombackFile to choose file default location ombackFolder

tell application "System Events"
	set pfPath to ombackFile as text
	set pfRec to value of property list file pfPath -- returns an A/S record
end tell

To get the item containing the tags you refer to

|org.openmetainfo:kmditemomusertags| of omDict of pfRec --> {"6", "null", "mixed", "3", "06-09-2010 08:00:00", "false"}

That result is from my “guinea pig” - a plain list which you can use as-is.

Look Ma, no parsing :smiley: