Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tutorial options for keywords need to be updated for Alfred 4 #145

Open
elsatch opened this issue Aug 12, 2019 · 11 comments
Open

Tutorial options for keywords need to be updated for Alfred 4 #145

elsatch opened this issue Aug 12, 2019 · 11 comments

Comments

@elsatch
Copy link

elsatch commented Aug 12, 2019

As I was following the tutorials, I discovered that they Keywords screen has changed. Now there are two options for input: "with input as argv", "with input as {query}". The option "with input as argv" is selected by default.

Tutorial is written using "with input as {query}", so initially it doesn't match on the screen. There is no option to choose the Escaping options in the "with input as argv".

Alfred 4 Screenshot

@deanishe
Copy link
Owner

What exactly are you asking me to do?

There is no option to choose the Escaping options in the "with input as argv".

Escaping isn't necessary when using argv.

@elsatch
Copy link
Author

elsatch commented Aug 14, 2019

In section "Adding a Script Filter" of the tutorial, under the "And enter the details for this action (the Escaping options don’t matter at the moment because our script currently doesn’t accept a query):" there is a screenshot.

In Alfred 4, the options for Escaping do not appear unless you manually select "with input a {query} in the dropdown menu".

Down in the same section, there is this sentence: "We’re going to create the pinboard.py script in a second. The Escaping options don’t matter for now because our Script Filter doesn’t accept an argument." I would add at the end of that phrase. (Note/Warning: If you are using Alfred 4, you might need to select "with input as {query}" in the dropdown menu to make the Escaping options appear. But don't worry now, as we will not be using them right now".

I was checking the repo contents, and I've seen the tutorial itself is at docs/tutorial_1.rst. If you prefer, I can create a pull request with suggested changes and you can review them.

@deanishe
Copy link
Owner

If you prefer, I can create a pull request with suggested changes and you can review them.

I wouldn't bother at this point. The library needs rewriting for Catalina/Python 3.

@sniarn
Copy link

sniarn commented Sep 12, 2019

I wouldn't bother at this point. The library needs rewriting for Catalina/Python 3.

Does that mean a rewrite for Python 3 is planned or not?

@deanishe
Copy link
Owner

Does that mean a rewrite for Python 3 is planned or not?

Well, yes. That's why I'm advising against big updates to the current version.

It'll be almost a complete rewrite for Python 3 only, and it's going to look a lot more like a Pythonic version of my Go library than it will the current version.

I want to remove a lot of stuff. Obviously, the Alfred 2- and 3-specific code is going, but there are still a few other things I need to decide on, such as whether to drop support for JSON in the caching code.

My main goal, apart from tidying up the API, is to improve loading time.

I'm open to any input regarding the API, features and docs (especially #103).

@sniarn
Copy link

sniarn commented Sep 16, 2019

Hmm. Perhaps something that would make it easier (or at least clearer) on how to write workflows that contain both Script Filter and Run Script actions. Today I always end up with a lot of deeply nested code. I'm not sure how this would work exactly, but the thought of it is nice.

@deanishe
Copy link
Owner

Perhaps something that would make it easier (or at least clearer) on how to write workflows that contain both Script Filter and Run Script actions.

I have an idea for the next tutorial that will have more parts and be a more complex workflow, combining multiple (free) APIs. That should give people a better idea how to deal with lots of actions.

Today I always end up with a lot of deeply nested code.

How so? Do you have an example?

@sniarn
Copy link

sniarn commented Sep 16, 2019

I have an idea for the next tutorial that will have more parts and be a more complex workflow, combining multiple (free) APIs. That should give people a better idea how to deal with lots of actions.

Perhaps a workflow that has two (or more) Script Filter actions that are connected sequentially. The first Script Filter would then trigger a secondary Script Filter displaying different options depending on which action was chosen in the first Script Filter. But then again, perhaps that would be a bit too much for a tutorial.

How so? Do you have an example?

Perhaps deeply nested is a bit of a stretch. I think my main point is that there are two very different ways of providing feedback to Alfred depending on whether the script is invoked by a Script Filter or a Run Script action. I typically end up with code like this:

if args.mode == 'something':
    # do something
    wf.send_feedback()
elif args.mode == 'something-else':
    # do something else
    v = Variables('blah')
    print(v)
elif args.mode == 'something-else-entirely':
    # do something else entirely
    wf.send_feedback()

@deanishe
Copy link
Owner

You can't really avoid all the ifelif clauses without a bit of "magic", but normally, once it starts getting complicated, you'd have each clause call a function instead of inlining the code:

if args.mode == 'something':
    return do_something()
elif args.mode == 'something-else':
    return do_something_else()
elif args.mode == 'something-else-entirely':
    return do_something_else_entirely()

If you have a large number of "modes", you can use reflection to call functions based on the value of mode:

def do_something():
    print('did something')

def do_something_else():
    print('did something else')

def do_something_else_entirely():
    print('did something else entirely')


def run(mode):
    name = 'do_' + mode.replace('-', '_')
    func = globals().get(name)
    if func:
        return func()
    raise ValueError('Unknown mode: ' + mode)


run(args.mode)

Or encapsulate your program in a class with the same technique:

class Program(object):
    """An example program."""

    def do_something(self):
        print('did something')

    def do_something_else(self):
        print('did something else')

    def do_something_else_entirely(self):
        print('did something else entirely')

    def run(self, mode):
        """Call method for ``mode``."""
        name = 'do_' + mode.replace('-', '_')
        meth = getattr(self, name)
        if meth:
            return meth()
        raise ValueError('Unknown mode: ' + mode)


p = Program()
p.run(args.mode)

@sniarn
Copy link

sniarn commented Sep 16, 2019

I think I used a dictionary at one point to do something similar. I'll try to clean up my code. Thanks for the tips!

Looking forward to see what you come up with for the Python 3 version of alfred-workflow.

@deanishe
Copy link
Owner

deanishe commented Sep 16, 2019

I think I used a dictionary at one point to do something similar

That works well, too. The advantage of using reflection is that you don't have to remember to add new functions to the dictionary.

My Zothero workflow is a pretty big one. That might be worth checking out as an example of how to structure a large workflow, even if the workflow itself isn't very interesting for you.

I tend to build my workflows as command-line programs, and it might be worth looking at other Python CLI programs, like beets.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants