oniony / TMSU

TMSU lets you tags your files and then access them through a nifty virtual filesystem from any other application.
Other
2.04k stars 119 forks source link

Output tags in json or yaml format #106

Open dotreloaded opened 7 years ago

dotreloaded commented 7 years ago

It'd make it a bit easier to interact with metadata stored in tmsu databases from other programs/scripts if the tmsu tags command had an option to output this info as json or yaml.

0ion9 commented 7 years ago

What language are you using, that a list of strings is more difficult to deal with than a json document?

(FWIW, tmsu tags |head -c 1| jq -R --slurp 'split("\n")' will get a json list of tags)

dotreloaded commented 7 years ago

Oh I meant to say tmsu tags [FILE], not tmsu tags. It's just a little annoying to have to split on equal signs and unescape spaces.

0ion9 commented 7 years ago

Oh, so you want to get something like this:

{"somefile.ext" : [["tag with a space"], ["year","2016"], ["sometag"]]}

Seems less trivial, yeah. You also have to handle any escaped : in the filenames, in addition to what you mentioned.

oniony commented 7 years ago

OK, this seems like a reasonable request.

0ion9 commented 7 years ago

Here is a stopgap implementation. It returns a JSON dict {filename: [[tag, value],[tag,value]..],..} where value is "" (empty string) if, in tmsu terms, there is no value assigned. Example output: {"bar" : [["foo", ""]]}

tmsu-tags-to-json () {
    python3 -c 'import sys, json
import re
sys.stdout.write("{")
filename = None
for line in sys.stdin:
    line = line.strip()
    if filename is not None:
        sys.stdout.write(", ")
    try:
        filename, tags = re.split(r"(?<!\\):(?<!\\) ", line, 1)
    except ValueError:
        if line.endswith(":"):
            filename = line[:-1]
            tags = ""
        else:
            sys.stderr.write("could not parse line %r\n" % (line,))
    tags = [v.replace(r"\ "," ") for v in re.split(r"(?<!\\) ", tags)]
    if tags == [""]:
        tags = []
    for i, v in enumerate(list(tags)):
        if re.search(r"(?<!\\)=", v):
            lhs, rhs = re.split(r"(?<!\\)=", v, 1)
            lhs = lhs.replace(r"\=","=")
            rhs = rhs.replace(r"\=","=")
            tags[i] = [lhs,rhs]
        else:
            # In TMSU, `tmsu tag somefile bar=` is the same as `tmsu tag somefile bar`.
            # Therefore it is safe to use <empty string> to represent an absence of value.
            tags[i] = [v.replace(r"\=","="),""]
    filename = filename.replace(r"\:",":")
    # We output data as a stream, so that we can cope easily with large inputs.
    sys.stdout.write("%s : %s" % (json.dumps(filename),json.dumps(tags)))
sys.stdout.write("}")
'
}
c-nv-s commented 1 year ago

@oniony came searching for this feature and saw that it was requested 6 years ago.... any chance of still adding it?

oniony commented 1 year ago

Yes, there's a chance, but not before I've done the first version in the Rust rewrite. Struggling for time at the moment but planning on getting back to it.

On Thu, 21 Sep 2023, 10:17 c-nv-s, @.***> wrote:

@oniony https://github.com/oniony came searching for this feature and saw that it was requested 6 years ago.... any chance of still adding it?

— Reply to this email directly, view it on GitHub https://github.com/oniony/TMSU/issues/106#issuecomment-1729184625, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAABOB6YSSKHPXTRWDY3XTDX3QAZ5ANCNFSM4C3B74NQ . You are receiving this because you were mentioned.Message ID: @.***>