Jump to content

[SOLVED] JSON Config - ??? so confused


Recommended Posts

Guys, can anyone help me out? I'm trying to use a `JSON Config` object to set some variables in my workflow. But it's not working. I've read https://www.alfredapp.com/help/workflows/utilities/json/ and done as much googl'ing as I can. I made a simple test workflow that illustrates my dilemma. When setting args using `Args and Vars` (hold SHIFT) it works, but the JSON Config seemingly does nothing.

 

Download below:

JSONConfig.alfredworkflow (github)
 

Any ideas?

 

image.png.a24ef412448d1b104281d7629ebc49e1.png

Edited by luckman212
Link to comment
2 hours ago, luckman212 said:

I've read https://www.alfredapp.com/help/workflows/utilities/json/ and done as much googl'ing as I can.

 

You need to read more carefully ;) This is the example from that page:

{
  "alfredworkflow" : {
    "arg" : "{query}",
    "config" : {
    },
    "variables" : {
    }
  }
}

Notice that variables is a sibling of config, not a child. Also, there is no argument field.


The config object contains settings for the following workflow element. It is a separate thing.

 

This is your JSON:

{
  "alfredworkflow" : {
    "config" : {
      "argument" : "",
      "variables" : {
        "a" : "apple",
        "b" : "ball",
        "c" : "chips"
      }
    }
  }
}

This is the correct JSON:

{
  "alfredworkflow" : {
    "arg" : "{query}",
    "config" : {
    },
    "variables" : {
      "a" : "apple",
      "b" : "ball",
      "c" : "chips"
    }
  }
}

 

Edited by deanishe
Link to comment

Wow, thanks @deanishe 🤘

Ok so here's where I got tripped up—

I right clicked on the configured "Args and Vars" object and selected "Copy Configuration"

Then I pasted that into the JSON Config object, and it gives me this:

{
  "alfredworkflow" : {
    "config" : {
      "argument" : "",
      "variables" : {
        "c" : "chips",
        "a" : "apple",
        "b" : "ball"
      }
    }
  }
}

As you noted, this seems to be incorrect/nonfunctional. So, not sure if this is intended behavior, or a bug...

 

Link to comment
3 minutes ago, luckman212 said:

I right clicked on the configured "Args and Vars" object and selected "Copy Configuration"

 

Ah, right. Well, the Arg and Vars object does have variables in its configuration.


The config object is element-specific, though. What works with Arg and Vars won't work with other elements.

 

But I can see how that would lead to confusion.

Link to comment
Just now, luckman212 said:

A couple of example workflows featuring the JSON Object would have gone a long way.

 

The docs in general would benefit from a bit more depth. It's also just dumb bad luck that you copied the config from an Arg and Vars element. Anything else, and you'd have had the "right" JSON. But you picked the only one (AFAIK) that doesn't have the standard arg and variables fields.

Link to comment
  • vitor changed the title to [SOLVED] JSON Config - ??? so confused

@deanishe sorry to ask, but could you possibly nudge me in the right direction on this?

 

I'm trying to dynamically generate the JSON to set variables using a Script Action (ruby). Got this:

require 'json'

json = []
cc = 20

for i in 0..cc do
  varname = 'clip' + (i).to_s
  clipname = '{clipboard:' + (i).to_s + '}'
  json.push( varname => clipname )
end

puts({ "alfredworkflow" => { "arg" => "{query}", "variables" => json }}.to_json)

Which generates almost the right output, but not quite (the variables are output as independent items in []'s instead of as direct descendants of `variables`. Any idea what I'm doing wrong here?

Link to comment
8 minutes ago, luckman212 said:

Any idea what I'm doing wrong here?

 

I don't know Ruby, so I'm just guessing, but it looks like you're setting variables to an array, not to a hash. This line json = [] should be json = {}, and json.push( varname => clipname ) should be json[varname] = clipname.

 

Link to comment

@deanishe that worked! :D So the script is:

 

require 'json'

json = {}
cc = 20

for i in 0..cc do
  varname = 'clip' + (i).to_s
  clipname = '{clipboard:' + (i).to_s + '}'
  json[varname] = clipname
end

puts({ "alfredworkflow" => { "arg" => "{query}", "variables" => json }}.to_json)

So now the script generates "perfect" output, BUT instead of substituting {query} and {clipboard:1} etc. values, Alfred is setting these as literal values. E.g. instead of the actual query or clipboard history contents, I'm getting the literal text "{clipboard:1}".

 

edit: here's a python version of the same script, also suffers from the same problem of non-substituted variables

import json, os

obj = {}
j = {}
varlist = {}

cc = int(os.getenv('CLIP_COUNT', 3))

for i in range(cc):
  varname = 'clip' + str(i)
  clipname = '{clipboard:' + str(i) + '}'
  varlist[varname] = clipname

j['variables'] = varlist
j['arg'] = '{query}'
obj['alfredworkflow'] = j
print json.dumps(obj)

Seems impossible that this would be the way the Dynamic Placeholders feature was designed. Do I need to ask @Andrew ?

Edited by luckman212
Link to comment
2 hours ago, luckman212 said:

Seems impossible that this would be the way the Dynamic Placeholders feature was designed

 

That's exactly how it's designed. From that page:

 

Quote

Alfred offers dynamic placeholders, which allow you to insert dynamically-created content when using Snippets and in certain workflow objects.

 

Alfred—quite rightly—doesn't mess with the output from your scripts.

 

What exactly are you trying to achieve?

Link to comment
11 minutes ago, deanishe said:

What exactly are you trying to achieve?

 

Trying to create a workflow that references items from the clipboard history (up to 25, 50, or more). So I want to set up the variables programmatically via a loop vs. tediously like

{
  "alfredworkflow" : {
    "variables" : {
      ...
      "clip30" : "{clipboard:30}",
      "clip31" : "{clipboard:31}",
      "clip32" : "{clipboard:32}",
      "clip33" : "{clipboard:33}",
      "clip34" : "{clipboard:34}",
      ...
    }
  }
}

 

Link to comment
27 minutes ago, luckman212 said:

Trying to create a workflow that references items from the clipboard history (up to 25, 50, or more). So I want to set up the variables programmatically via a loop vs. tediously like

 

That's not what you're trying to achieve, that's how you're trying to achieve it.

 

What is the end goal here?

Link to comment

Ok, well the end goal is a workflow that displays the most recent N clipboard history items and upon selecting one, "types" it to the foreground app by simulating keystrokes (AppleScript `keystroke`). The reason for this to exist is e.g. some websites don't allow copy/paste so you want to "type" something into a field. Or Remote Desktop / ARD / other remote control sessions where a "paste" doesn't always work. This might not be useful for many people but I use it all the time.

 

Here's the workflow as it stands if you want to see:

(removed - updated version below...)

 

Edited by luckman212
Link to comment
6 hours ago, luckman212 said:

This might not be useful for many people but I use it all the time.

 

I use it quite a lot, too.

 

The best way to get the clipboard history is to read it from Alfred's clipboard database. It's a *little* hacky, but I've seen Andrew recommend people do it this way, so it's pretty safe. Also, it's extremely fast.

from contextlib import contextmanager
import os
import sqlite3

# Number of clipboard items to retrieve
COUNT = 10

# Path to clipboard history database
# For Alfred 3, replace "Alfred" with "Alfred 3"
dbpath = os.path.expanduser('~/Library/Application Support/Alfred/Databases/clipboard.alfdb')


@contextmanager
def database(path):
    """Open and close database."""
    db = sqlite3.connect(path)
    yield db
    db.close()

clips = []
with database(dbpath) as db:
    # each row is a tuple, even though we're only selecting one column
    rows = db.execute('SELECT item FROM clipboard ORDER BY ts DESC LIMIT ' + str(COUNT))
    clips = [row[0] for row in rows]

for s in clips:
    print(s)

 

Link to comment
  • 1 month later...

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...