Jump to content

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
Link to comment
  • 1 month later...

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.

Link to comment

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
Link to comment

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.

Link to comment

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)
Link to comment

 

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
...
Link to comment

 

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.

Link to comment
  • 2 weeks later...

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.

Link to comment

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.

Link to comment

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
Link to comment

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.

Link to comment

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>
Link to comment

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
Link to comment

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
Link to comment

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
)
Link to comment

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'
Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...