Jump to content
phyllisstein

OpenMeta Tags: Search, tag, open tagged files

Recommended Posts

Hello, fellow workers of flow! I've just thrown together a new workflow that searches and sets OpenMeta tags and opens files that have already been tagged. You can download it here! Just install it, then enter "tags" to display—after about a second—a list of all the tags currently set on your system. Select a tag and press Return to add it to the Finder selection's current tags, or keep typing. In which case the workflow will search through the tags on your system for tags containing and related to your query. (Note that "related to" really means "related to": if a document is tagged "alice" and "bob," searching for "bob" will turn up "alice" as related.) It'll also list documents tagged with your query. Select a tag and hit Return to tag the Finder selection (again), or choose a document and hit Return to open it. Hitting Tab while a tag is selected will autocomplete to that tag, making it a cinch to search for tagged documents.

 

In the updated version, also at the link above, holding down Ctrl while pressing Return will remove the chosen tag from the Finder selection or, if a file is highlighted in Alfred, clear all tags from that file. The updated version is also a bit greedier with the metadata attributes it sets, so that stale data won't be left behind for other apps to potentially use by mistake.

 

So, have fun, tag away, and enjoy using OpenMeta without paying $29 for Tags.app!

 

tags_screen.jpg

Edited by phyllisstein

Share this post


Link to post

Hey this is pretty cool.  Do you think it would be possible to add an actual File Action to tag selected files?  Thanks for making this!

Share this post


Link to post

Thanks for doing this. However, for some reason, after typing "tag" and seeing "Gathering tags..." no tag list is displayed. :(  (I know there are many OpenMeta tags in use since Tags or Yep are working fine.) Any idea why this is happening?

 

I'm on 10.8.3. Alfred 2.0.3.

Share this post


Link to post

I am having the same issue reported by mjv above. Also on 10.8.3 and Alfred 2.0.3.

 

This is a great idea for a workflow. Thanks to author for his efforts.

Share this post


Link to post

I am having the same issue reported by mjv above. Also on 10.8.3 and Alfred 2.0.3.

 

This is a great idea for a workflow. Thanks to author for his efforts.

 

What does this command show when pasted into the terminal?

mdfind -0 'kMDItemOMUserTags == *' | xargs -0 mdls -name "kMDItemOMUserTags" | grep "^    " | cut -c 5- | sed -e "s/,$//" | sort -u

Share this post


Link to post

Hey this is pretty cool.  Do you think it would be possible to add an actual File Action to tag selected files?  Thanks for making this!

 

I'll give it some thought, but I don't think so; all the internal searching is done by tag, not by file.

 

 

Thanks for doing this. However, for some reason, after typing "tag" and seeing "Gathering tags..." no tag list is displayed. :(  (I know there are many OpenMeta tags in use since Tags or Yep are working fine.) Any idea why this is happening?

 

I'm on 10.8.3. Alfred 2.0.3.

 

 

I am having the same issue reported by mjv above. Also on 10.8.3 and Alfred 2.0.3.

 

This is a great idea for a workflow. Thanks to author for his efforts.

 

Could you check the workflow's folder for a file called "feedback.log" and let me know what it contains? Thanks.

Share this post


Link to post

Could you check the workflow's folder for a file called "feedback.log" and let me know what it contains? Thanks.

 

In my case, it contains:

 

 

Traceback (most recent call last):
  File "feedback.py", line 111, in <module>
    tag_feedback()
  File "feedback.py", line 49, in tag_feedback
    subtitle="Tag the Finder selection with '{0}'".format(tag),
UnicodeEncodeError: 'ascii' codec can't encode character u'\u0308' in position 10: ordinal not in range(128)

Share this post


Link to post

 

What does this command show when pasted into the terminal?

mdfind -0 'kMDItemOMUserTags == *' | xargs -0 mdls -name "kMDItemOMUserTags" | grep "^    " | cut -c 5- | sed -e "s/,$//" | sort -u

 

A lot of tags. :) 

 

Like:

 

africa
agriculture
algarve
america
anatomy
anthracology
anthropology
ants
arch
archaeology
art
asia
atlas
...

Share this post


Link to post

 

In my case, it contains:

 

 

Traceback (most recent call last):
  File "feedback.py", line 111, in <module>
    tag_feedback()
  File "feedback.py", line 49, in tag_feedback
    subtitle="Tag the Finder selection with '{0}'".format(tag),
UnicodeEncodeError: 'ascii' codec can't encode character u'\u0308' in position 10: ordinal not in range(128)

 

Alright, I've just uploaded a new version to http://alfred.daniel.sh/Workflows/OpenMetaTags.alfredworkflow that will hopefully correct the problem. If not, let me know.

Share this post


Link to post

Now available here and via Alleyoop, a small upgrade that will hopefully provide some speed improvements. If it looks like it starts missing tags on your system after this update, let me know so that I can revert.

Share this post


Link to post

I continually get an error message with this workflow. I'm on 10.6.8. This is the message:

 

 

Traceback (most recent call last):
  File "act.py", line 149, in <module>
    do_action()
  File "act.py", line 95, in do_action
    cleanPaths = get_finder()
  File "act.py", line 40, in get_finder
    pathList = subprocess.check_output(["osascript", "getFinder.applescript"])
AttributeError: 'module' object has no attribute 'check_output'
 

I do see the 'gathering tags...' message followed by a list of tags. Any ideas? Thanks.

Share this post


Link to post

Since check_output was added in a fairly recent version of Python, it's possible that 10.6.8 doesn't ship with it. Could you open up a Terminal and run python --version and paste the output here? I'll meanwhile work on switching to an older subprocess call.

Share this post


Link to post

Sorry - another error message:

 

 

Traceback (most recent call last):
  File "act.py", line 155, in <module>
    do_action()
  File "act.py", line 110, in do_action
    check = set_tags(tags, path)
  File "act.py", line 73, in set_tags
    kCFPropertyListBinaryFormat_v1_0, NSPropertyListImmutable, None)
ValueError: too many values to unpack

Share this post


Link to post

Sorry it's giving you so much trouble—I haven't been able to do any testing on 10.6. It'd be a big help if you could spend a couple of minutes in the Python interpreter for me, but I don't want to cause too much trouble; the other thing I can always do is rewrite it in Objective-C and trust that compiled code will be more reliable than interpreted code. Not something I mind doing, though it might take a day or two.

 

Anyway, if you want to really debug the bastard, fire up a Terminal and run python. Paste the lines below in one at a time, hitting Return after each one:

from Foundation import *
t = NSMutableArray.arrayWithCapacity_(0)
t.addObject_(NSString.stringWithCString_encoding_("foo".encode("utf-8"), NSUTF8StringEncoding))
t.addObject_(NSString.stringWithCString_encoding_("bar".encode("utf-8"), NSUTF8StringEncoding))
t.addObject_(NSString.stringWithCString_encoding_("baz".encode("utf-8"), NSUTF8StringEncoding))
t.addObject_(NSString.stringWithCString_encoding_("qux".encode("utf-8"), NSUTF8StringEncoding))
NSPropertyListSerialization.dataWithPropertyList_format_options_error_(t, kCFPropertyListBinaryFormat_v1_0, NSPropertyListImmutable, None)

You shouldn't get any output from any of that until the last line; on my machine, hitting Return spits this out:

(<62706c69 73743030 a4010203 0453666f 6f536261 72536261 7a537175 78080d11 15190000 00000000 01010000 00000000 00050000 00000000 00000000 00000000 001d>, None)

It'd be a great help to know whether you get something similar. But, again, if you're not feeling Terminal, hang tight for a couple of days and I'll look into redoing it.

Share this post


Link to post

I tried that and got the same as you, except the ', None' at the end:

 

 

<62706c69 73743030 a4010203 0453666f 6f536261 72536261 7a537175 78080d11 15190000 00000000 01010000 00000000 00050000 00000000 00000000 00000000 001d>

Share this post


Link to post

Curiouser and curiouser! Well, believe it or not, that could've gone worse. I can add a version check and not look for the second value in Python < 2.7. There's one other call to NSPropertyListSerialization that I'm a little worried about; if you have a tagged file you can try this on, that'd be great, otherwise I'll upload what I have and we can see what happens. Here's s'more code for the interpreter; as convention goes, lines that start with >>> should be input, and lines that don't are what the output ought to look like.

>>> from Foundation import *
>>> from ctypes import *
>>> libc = cdll.LoadLibrary("libc.dylib")
>>> path = "/Users/danielsh/Desktop/tagged.txt".encode("utf-8")
>>> cPath = c_char_p(path)
>>> data = create_string_buffer(4096)
>>> name = "com.apple.metadata:kMDItemOMUserTags".encode("utf-8")
>>> dataSize = libc.getxattr(cPath, name, data, 4096, 0, 0x0001)
>>> dataSize
52
>>> nsData = NSData.dataWithBytes_length_(data, dataSize)
>>> NSPropertyListSerialization.propertyListWithData_options_format_error_(nsData, kCFPropertyListImmutable, None, None)
((
    sublime
), 200, None)

You'll have to enter the line path = ... by hand, since you'll need to give it the path to a file with tags. What we're looking for is for a positive number to come after dataSize, and three values, one of which is a list of tags, to be returned by NSPropertyListSerialization. If it's more or less than three, I'll have to add another version check.

Edited by phyllisstein

Share this post


Link to post

It all goes horribly wrong at datasize:

 

 

>>> from Foundation import *
>>> from ctypes import *
>>> libc = cdll.LoadLibrary("libc.dylib")
>>> path = "users/theo/desktop/tagtest.txt" .encode("utf-8")
>>> cPath = c_char_p(path)
>>> data = create_string_buffer(4096)
>>> name = "com.apple.metadata:kMDItemOMUserTags".encode("utf-8")
>>> dataSize = libc.getxattr(cPath, name, data, 4096, 0, 0x0001)
>>> dataSize
-1
>>> nsData = NSData.dataWithBytes_length_(data, dataSize)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: NSInvalidArgumentException - *** -[NSConcreteData initWithBytes:length:copy:freeWhenDone:bytesAreVM:]: absurd length: 18446744073709551615, maximum size: 9223372036854775808 bytes

Share this post


Link to post

I think you may need to add an initial slash to your path, and watch the case sensitivity; try it with:

>>> path = "/Users/theo/Desktop/tagtest.txt".encode("utf-8")

I'm also reviving some old Objective-C tagging code, just in case.

Share this post


Link to post

Here you go: 'tagtest' is the tag for the file I'm using. 

 

 

>>> from Foundation import *
>>> from ctypes import *
>>> libc = cdll.LoadLibrary("libc.dylib")
>>> path = "/Users/theo/Desktop/tagtest.txt".encode("utf-8")
>>> cPath = c_char_p(path)
>>> data = create_string_buffer(4096)
>>> name = "com.apple.metadata:kMDItemOMUserTags".encode("utf-8")
>>> dataSize = libc.getxattr(cPath, name, data, 4096, 0, 0x0001)
>>> dataSize
52
>>> nsData = NSData.dataWithBytes_length_(data, dataSize)
>>> NSPropertyListSerialization.propertyListWithData_options_format_error_(nsData, kCFPropertyListImmutable, None, None)
(
    tagtest
)

Share this post


Link to post

Well, you did ask ;)

 

 

Traceback (most recent call last):
  File "act.py", line 162, in <module>
    do_action()
  File "act.py", line 117, in do_action
    check = set_tags(tags, path)
  File "act.py", line 86, in set_tags
    bytes = c_char_p(dataToSend.bytes().tobytes())
AttributeError: 'buffer' object has no attribute 'tobytes'

Share this post


Link to post

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...