Jump to content

Recommended Posts

I want to save ticker symbols (one at a time) for later use in a script filter.

 

Do I have to implement some logic to prevent settings API from overwriting the previous saved ticker symbol or the library can handle this situation in some way?

Edited by xilopaint

Share this post


Link to post

It has the same API as a normal dictionary. I think the docs make this pretty clear.

 

So, yeah, if you save new data under the same key, it will overwrite the old data.

Share this post


Link to post

What's the best way to remove a key?

 

When trying to use json.load() for reading settings_path and dict.pop to remove the key I get  AttributeError: 'unicode' object has no attribute 'pop'.

 

with open(wf.settings_path, 'r') as f:
	data = json.load(f)

for element in data:
	element.pop('AAPL', None)
    
with open(wf.settings_path, 'w') as f:
	json.dump(data, f)

 

Share this post


Link to post

Why are you accessing the file directly? Have you read the docs? Use the dictionary exposed at Workflow.settings.

 

# Load saved symbols or empty list
symbols = wf.settings.get('symbols', [])
# Add a new symbol
symbols.append('AAPL')
# Update the settings dict to ensure the changes are saved to disk
wf.settings['symbols'] = symbols

 

Share this post


Link to post

Updated to v1.27.

 

This version replaces the old variable-setting mechanism with the new one introduced in Alfred 3.4.1. On the one hand, this makes it possible to set variables on an item as well as using type=file, but setting item- and mod-level variables does not work on older versions of Alfred 3 (Alfred 2 is unaffected).

 

Share this post


Link to post

Hey deanishe, I am thinking about starting to use Notify.app in some workflows of mine. From what I understand, I have to "install" the app with workflow.notify.install_notifier() so it's copied to data directory.


I don't see the best implementation for this. Should I write my script in a way it checks if Notify.app is present in data directory otherwise workflow.notify.install_notifier() is executed? I feel there's a better way.

Edited by xilopaint

Share this post


Link to post

Have you tried to understand the source code of notify.py? The code is very easy to follow, and well commented.

 

The only function you need to call is notify.notify(), which installs Notify.app if it isn't already installed.

 

If you want to use notify.py without Alfred-Workflow, you only need to replace the bits that call Workflow, which is only used as a convenient way to get a Logger and the path to the workflow's data directory.

 

And FWIW, Notify.app is just a simple AppleScript saved as an application, so notifications show the app bundle's icon, not an AppleScript one (install_notifier() changes the icon of the installed Notify.app to that of your workflow on install).

 

Here's the AppleScript (from Notify.app/Contents/Resources/Scripts/main.scpt):

--
-- Copyright (c) 2015 deanishe@deanishe.net
--
-- MIT Licence. See http://opensource.org/licenses/MIT
--
-- Created on 2015-11-26
--

on run (argv)
	
	-- Grab variables via shell script as non-ASCII text doesn't work
	-- when read directly in AppleScript. UTF-8 text works properly
	-- this way.
	set theTitle to do shell script "echo $NOTIFY_TITLE"
	set theMessage to do shell script "echo $NOTIFY_MESSAGE"
	set theSound to do shell script "echo $NOTIFY_SOUND"
	log "Title : " & theTitle
	log "Text : " & theMessage
	log "Sound : " & theSound
	
	if theSound ≠ "" then
		display notification theMessage with title theTitle sound name theSound
	else
		display notification theMessage with title theTitle
	end if
end run

 

Edited by deanishe

Share this post


Link to post

@deanishe, when I ask you a question you answer at once:

 

1) what I asked;

2) what I had planned to ask in the next post;

3) what I should have asked but I didn't because I am too dumb for it.

 

You would make a great teacher. Thank you for being so awesome!

Edited by xilopaint

Share this post


Link to post

Hi deanishe, I'm new here and I'm trying to write a workflow for http://bgm.tv, based on the tutorial,  and here's my code:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys

from workflow import ICON_WEB, Workflow3, web


def get_search_result(query):
    """TODO: Docstring for get_search_result.

    :query: TODO
    :returns: TODO

    """
    url = u'https://api.bgm.tv/search/subject/' + query
    params = {'responseGroup': 'simple', 'max_results': '11', 'start': '0'}
    r = web.get(url, params)
    r.raise_for_status()

    result = r.json()
    return result['list']


def main(wf):
    query = wf.args[0]

    items = wf.cached_data(
        'result:' + query, lambda: get_search_result(query), max_age=600
    )

    for item in items:
        wf.add_item(
            title=item['name'],
            subtitle=item['name_cn'],
            arg=item['url'],
            valid=True,
            icon=ICON_WEB
        )

    wf.send_feedback()


if __name__ == u"__main__":
    wf = Workflow3()
    logger = wf.logger
    sys.exit(wf.run(main))

It works pretty well in my terminal when I call things like

/bin/bash python bangumi.py "銀魂"

However, every time I try call it in Alfred, I received these messages in the log:

[2017-09-14 20:53:20][input.scriptfilter] Queuing argument '銀魂'
[2017-09-14 20:53:20][input.scriptfilter] Script with argument '(null)' finished

Could you help me please? And is there a way to log things to the log console in Alfred? I tried logging to wf.logger but nothing shows there.

------------------------------------------------------------

UPDATE:

Nevermind, I just noticed that since I used sync utility, the path to the directory of my workflows has changed, but I was still editing in the previous location.

Thanks for this great package anyway!

 

Edited by quinoa42

Share this post


Link to post
2 hours ago, quinoa42 said:

'result:' + query

 

I'd change this line, tbh. This is used as the filename for the cache, so it needs to be filesystem-safe. If a query has / in it, it will crash. I'd suggest using the MD5 hash of the query, and no colons:

import hashlib
key = 'result-' + hashlib.md5(query.encode('utf-8')).hexdigest()

Share this post


Link to post

@deanishe, I got the self-update feature to work, but I noticed in my tests that the script has to run twice in order to download the update. In the first run __workflow_update_status.cpickle and gh-releases-{github_slug}.cpickle are saved in the cache folder. Only in the second run the update is installed. Is this expected behavior or I'm doing something wrong?

Edited by xilopaint

Share this post


Link to post
1 hour ago, xilopaint said:

Is this expected behavior

 

Yes. The list of available releases is fetched asynchronously in the background, so the cached list may be weeks or months out of date when you see an "Update available!" message if you haven't used the workflow in a while.

 

So when you trigger an update, it first fetches the list of available releases to ensure it downloads the latest version.

Share this post


Link to post
27 minutes ago, deanishe said:

 

Yes. The list of available releases is fetched asynchronously in the background, so the cached list may be weeks or months out of date when you see an "Update available!" message if you haven't used the workflow in a while.

 

So when you trigger an update, it first fetches the list of available releases to ensure it downloads the latest version.

 

Ok. There's another thing.

 

If the update is downloaded but the user for any reason doesn't click on the update button in Alfred Preferences when prompted, the __workflow_update_status.cpickle file is updated in cache folder and the user will not be prompted again unless the .cpickle file is manually deleted. Is it also expected?

Edited by xilopaint

Share this post


Link to post
17 minutes ago, xilopaint said:

the user for any reason doesn't click on the update button in Alfred Preferences when prompted

 

AW can't know and doesn't care whether the user clicked the update button or not.

 

All AW does is compare the version number of the installed workflow with that of the available releases. If there is a release with a higher version number, Workflow.update_available will be True.

 

If you want more help, you're going to have to upload your workflow and log file.

 

Share this post


Link to post
1 hour ago, deanishe said:

 

AW can't know and doesn't care whether the user clicked the update button or not.

 

All AW does is compare the version number of the installed workflow with that of the available releases. If there is a release with a higher version number, Workflow.update_available will be True.

 

If you want more help, you're going to have to upload your workflow and log file.

 

 

Here.

 

The latest GitHub version is v1.0. If you have the cache cleared and change the workflow version to v0.9 the update item will be displayed. After actioning the item the update will be downloaded and you will be prompted to install the newer version. If you don't conclude the installation the Script Filter will no more display the update item unless you delete the __workflow_update_status.cpickle file.


I assumed __workflow_update_status.cpickle file stored the version number of the latest release after the update is downloaded from GitHub and as a result the Script Filter couldn't display the update item again once the installation is not concluded by the user.

Edited by xilopaint

Share this post


Link to post

Right, I see what you mean.

 

Yes, if AW is told to install an update, it sets update_available to False. However, it will be reset to True the next time it checks for an update (24h by default).

 

IIRC, this was a deliberate choice. The reasoning was that if the user rejected the update, they probably don't want an "An update is available!" notification in their face every time they use the workflow. So they will be left alone for a day. (It also prevents AW from immediately checking for an update again.)
 

The problem is that as generally used, showing a notification as the first result requires switching off item UIDs, otherwise Alfred will apply its knowledge and move other results to the top. And you will no longer see what you're looking for as the first result in any case, which makes using the workflow harder. (The "proper" way to do it, imo, is to only show the "update available" notification if the query is empty, so it doesn't interfere with the results. But some workflows require a query.)

 

Essentially, the default behaviour is designed to avoid annoying users if workflow developers aren't careful about how they use the library because AW is aimed at inexperienced developers. AwGo (my Go library) doesn't do this, as Go developers tend to be more experienced. (Though some can't code for shit; they're just obsessed with speed.)

 

If you want to force update_available to be True even if the user didn't install the update, comment out or remove L393 and L394 of update.py. That will ensure update_available is always True if the remote version is newer.

 

Share this post


Link to post
10 minutes ago, deanishe said:

IIRC, this was a deliberate choice. The reasoning was that if the user rejected the update, they probably don't want an "An update is available!" notification in their face every time they use the workflow. So they will be left alone for a day. (It also prevents AW from immediately checking for an update again.)

 

Oh, I didn't realize that it would be "silenced" for a day. I thought it wouldn't show up again unless a new release came out so I planned to suggest a "silence" feature, though in this case there's nothing to point out. Thank you for clarifying.

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