Jump to content

wolph

Member
  • Posts

    68
  • Joined

  • Last visited

  • Days Won

    3

Posts posted by wolph

  1. 1 hour ago, vitor said:

    That’s the important bit. Executables always run slower the first time because macOS does checks when that happens. Those are outside of Alfred’s (or any app’s) control. Speed-wise, it makes no difference to run the script from the dropdown or a previously saved file. The dropdown method is essentially saving the script and running it.

     

    That's not entirely true though. Right now it has to run both zsh and python instead of just python. Perhaps there is a different way of running it that I'm not aware of, but right now I don't see any way around running both of them. The external script option does not work because that does not support argv for some reason.

     

    1 hour ago, vitor said:

    It is possible for your Python 3 code to be slower than the Python 2 counterpart. Even by official benchmarks, Python 3 started off slower. Not sure what’s the current state, but remember /usr/bin/python3 is itself behind the current release by a few years.

     

     

    Good point, to check I've done a little benchmark but I'm not noticing any meaningful difference here:

    $ for i in /usr/bin/python3 /usr/local/bin/python[0-9].[0-9]{,[0-9]}; do time $i -c 'import sys;print(sys.version)'; done
    3.8.9 (default, Oct 26 2021, 07:25:54)
    [Clang 13.0.0 (clang-1300.0.29.30)]
    $i -c 'import sys;print(sys.version)'  0.03s user 0.01s system 92% cpu 0.038 total
    2.7.17 (default, Oct 24 2019, 12:57:47)
    [GCC 4.2.1 Compatible Apple LLVM 11.0.0 (clang-1100.0.33.8)]
    $i -c 'import sys;print(sys.version)'  0.01s user 0.01s system 90% cpu 0.030 total
    3.7.13 (default, Mar 16 2022, 20:46:34)
    [Clang 13.0.0 (clang-1300.0.29.30)]
    $i -c 'import sys;print(sys.version)'  0.02s user 0.01s system 89% cpu 0.035 total
    3.8.13 (default, Mar 16 2022, 20:38:02)
    [Clang 13.0.0 (clang-1300.0.29.30)]
    $i -c 'import sys;print(sys.version)'  0.02s user 0.01s system 90% cpu 0.035 total
    3.9.12 (main, Mar 26 2022, 15:52:10)
    [Clang 13.0.0 (clang-1300.0.29.30)]
    $i -c 'import sys;print(sys.version)'  0.03s user 0.01s system 91% cpu 0.037 total
    3.10.4 (main, Apr 26 2022, 19:43:24) [Clang 13.0.0 (clang-1300.0.29.30)]
    $i -c 'import sys;print(sys.version)'  0.02s user 0.01s system 91% cpu 0.033 total

     

     

    1 hour ago, vitor said:

    Thing is, it hasn’t and still isn’t. If you have it you won’t notice, but run /usr/bin/python3 on a fresh macOS install and instead of the code running you’ll be greeted by macOS asking you to install the developer tools. Just like /usr/bin/swift/usr/bin/python3 is a shim. That’s why many Python Workflow developers—despite not using the dropdown to invoke Python—still chose to go with Python 2; it was a better experience to the user and many were expecting Apple to eventually make Python 3 available, not to remove languages.

     

     

    Oh wow... I wasn't aware of that. I stand corrected.

     

    In that case I think I'll just switch over to /usr/local/bin/python. If the user is required to install something anyway, it might be better to go for this.

     

    With regards to languages in the dropdown, it would certainly be nice of alfred would include more options. As can be seen in the benchmark above, I've got half a dozen python versions available and the dropdown doesn't show any of them. Having /usr/local/bin/python3 or /usr/bin/python3 at the very least would be an improvement.

  2. 2 hours ago, JLoun said:

    Hi, could you please release an older version that's compatible with Alfred 2? The current v3.4 doesn't seem to be working. 

    A (temporary) solution could be to use the unit converter I wrote: http://www.alfredforum.com/topic/5256-advanced-calculator-with-fast-off-line-unit-converter/

    It's a lot faster and functions without an internet connection and it supports Alfred 2 without a problem. I should note that it probably supports less features so it's a small trade-off :)

  3. I can't imagine Andrew adding native Python support (in the sense of embedding it, like Sublime or vim).

     

    The thing with a non-standard installation method, such as pip install …, is that anything that isn't installed in Alfred's workflow directory (well in the Alfred.alfredpreferences bundle to be precise) doesn't get synced. If you start putting stuff in site-packages, you need to do it on all your machines (and potentially worry about making sure they all have the same version installed).

     

    For any installation method, you also need to strip the workflow's Hotkeys on installation (and re-instate the ones the user has set). Alfred and Packal both do this. There may be other things too (Packal has some kind of workflow signing, but I don't know the details).

     

    I'd be tempted to punt on that one, so python setup.py install would build the .alfredworkflow file and then tell Alfred to open (i.e. install) it itself. This is what AW's update mechanism does.

    That's a very good point. I think you are right, that is most likely the most convenient option here.

     

    There's almost never a need to edit info.plist by hand. In 99.5% of cases, you're better off editing it indirectly via the workflow editor in Alfred Preferences. On occasion, I'll edit a word or two in my editor because I have that open in front of me, but I'd never consider trying to add an object to the workflow that way. There are several cases where you'd want to edit it programatically, however.

     

    Again, perhaps I've misunderstood, but I'm not sure that generating XML from a setup.py would be a great help. The vast majority of the time, the XML needs to be generated dynamically based on the user query and your workflow's data, and it always has to be fed to Alfred via the STDOUT of a Script Filter process (at least in Alfred 2).

    Fully generating the files might not be that useful but some part could be. To make the creation of new packages easy it would be very nice if developers could do something like:

    @alfred.scriptfilter(keyword='spam')
    def some_function(query):
        pass
    
    That would automatically link that function to a scriptfilter using the specified keyword. Once it's generated there's no real need anymore so everything can be edited by Alfred after that but it can make the link between Alfred and the Python scripts easier :)
  4. It's worth mentioning that in v3, the built in export does a few more tasks such as stripping out specified workflow variables (i.e. if you've filled in an API key you don't want exporting)... Just keep that in mind if you are exporting workflows outside of Alfred's prefs :)

    That's indeed interesting information, thanks :)

     

    I suppose that would have to be included somewhere as well but I'm not sure what would be the best location. I don't think the entry_points would be a great fit.

     

    That's where I always refer to. Problem is I can never remember when I'm supposed to use package_data and when MANIFEST.in. (And I usually end up publishing a broken version of Alfred-Workflow as a result, which is why there are a lot of gaps in its history on the Cheeseshop.)

    There must be a clearer tutorial out there somewhere…

    Personally I would recommend the usage of MANIFEST.in alone and simply ignore package_data. They largely overlap in functionality and I would argue that the MANIFEST.in system is easier to interpret as it doesn't offer any mapping/rewrite options.

     

    As for a better tutorial, chapter 15 of my book covers the usage of MANIFEST.in but I'm not sure if it's that much clearer... I'll send you the paragraph soon so you can judge for yourself :)

     

    This is the cookiecutter template I use, but it's closely tied to the way I write workflows (docopt-based CLI programs that happen to output XML).

     

    I'm not sure if that's broadly useable, but a cookiecutter template is definitely a good idea.

     

    Looks like a very nice starting point :)
     
     

    I'm still not following regarding entry points, I'm afraid. Is this based on Alfred supporting entry points natively? So, like Alfred loads your module/package and sets keywords appropriately. Or would there be some framework responsible for receiving input from Alfred and dispatching it appropriately, like a setuptools-based plugin manager?

     

    Ideally Alfred would support the entry points natively which would even make it possible to do a pip install -e workflow for development purposes. That would break backward compatibility however so I don't think that should be the first or only option.

     

    What I would like to propose is a setuptools build command which generates the entire workflow including the Alfred XML from the setup.py file.

     

    To ease development I think it should also contain a alfred_install or alfred_develop command to symlink the package so Alfred sees the workflow straight away.

     

    The added benefit of the setuptools entry points approach is that it would allow for a plugin manager to easily detect all Alfred plugins and show a list of available entry_points. That would allow for easy documentation as well since everything will be automatically generated :)

     

     

    I can definitely see the benefit in something like an alfred tool in the vein of django-admin. I've thought about writing something to replace the workflow-build.py script I linked to above and its workflow-install.py counterpart. (Its most useful feature being the ability to symlink the source code directory to Alfred's workflow folder, so your repo isn't hidden somewhere in the depths of ~/Dropbox or ~/Library.)

    I've not yet been convinced that its utility would outweigh the effort involved (if we're talking about features like adding new Script Filters, Actions etc. to existing workflows), however. I think even more so now, as Alfred 3 looks like it will add a whole bunch of new stuff. installbuild and publish (to Packal, possibly GitHub, too) are no-brainers. Beyond that, I dunno. Perhaps create, too, as a simple wrapper around a cookiecutter call?

    I've largely avoided the need for any intelligence in my scripts, again because the actual workflow is entirely contained in a subdirectory. I only need to symlink/copy that directory to the right place to install, or zip its contents minus *.pyc files to build.

    This seems to work well enough for Python (for my purposes, at least), but I had to use a proper build script when I tried Go.

     

    That said, something that a sophisticated alfred tool would probably need that I think would be extremely useful for a lot of workflows is a library that can understand and manipulate info.plist. There's a lot of cool stuff you can do when your workflow can rewrite its own code. I'm currently rewriting Searchio! to be more easily configurable, and it will need to be able to rewrite its own info.plist.

     

    Fuzzy Folders messes with its own info.plist, but the code is neither good nor portable.

     

    The single strongest argument I can think of to go for a smart utility is consistency. A single silly mistake in a workflow can break everything which is especially annoying for inexperienced developers.

    Not having to worry about packaging, uploading and the writing of a plist file at least removes that part of the equation.

     

    Everything is open for discussion of course, as long as it makes it things easier for developers :) 

     

    With regard to Packal, we (Shawn, I and a few others) were mulling over a "standard" workflow.ini file that Packal and Alfred-Workflow and any other libraries could use. That's all a bit up in the air at the moment, as it's not clear how much of the information Packal needs will be in the Alfred 3 info.plist.

     

    That could be interesting, and generally easier to write than setup.py files :P

     

    One more thing:

     

     

    The bundler is a different beast to what we've been talking about. It's purpose is to be able to fetch dependencies post-install and keep them all in once place, so you don't have 20 copies of cocoaDialog or requests or terminal-notifier etc. spread out across your workflows.

     

    It is, AFAIK, abandonware (at least for the time being). There are a few workflows out there that use it, but I'm fairly confident it isn't being actively developed and I'm not sure Shawn would recommend using it at this time.

     

    Ok, I'll edit the start post :)

  5. For what it's worth, I don't use Alfred's export function myself. I use this script. Although the version I'm using is slightly more sophisticated, and adds the version number to the generated .alfredworkflow file (and is only useful for Alfred-Workflow-based workflows). I just recommend the standard Export method in the tutorial because it's simple.

    Noted and edited in the first post :)

     

    My main reservation with regard to Makefiles and setup.py etc. is that they're not particularly beginner-friendly. At the very least, it's something new to learn, and trying to include non-Python files via setup.py is something I get wrong all the time (I always forget how to do it and the official documentation is confusing).

    True... the documentation about extra files is lacking to say the least.

    The most useful documentation to me is the Python 2 documentation. For some reason this was removed with the Python 3 release unfortunately but the Python 2 docs are still available: https://docs.python.org/2/distutils/sourcedist.html#commands

    Given a bit of well documented boilerplate it might be enough for beginners. Alternatively, perhaps the cookiecutter package could help to make a simple create-a-workflow wizard: https://cookiecutter.readthedocs.org/en/latest/

     

    There are definitely advantages to using a Makefile/build script or creating a setup.py, but I would be hesitant to try to enforce that method in any way due to the additional complexity. As usual, my main reservation about doing things "properly" is that it often isn't very accessible to newbies (which is why Alfred-Workflow's default behaviour is counter to best practices in several respects).

    I would personally vote for a documented standard, not something that is enforced in any way but simply an easy starting point for beginners with enough documentation to get a workflow up and running without too much effort.

     

    How realistic do you think it would be to provide a boilerplate setup.py (or a script that generates one) that wouldn't require the user to know too much about setuptools, entry points etc.?

    Assuming we create a cookiecutter template I think it would be easy enough.

    Alternatively, similar to how the django-admin command makes it possible to create a project using "django-admin startproject test" a "alfred create test" command could be created as well. Possibly even with an "alfred upload" or similar.

     

    The upload_packal command is certainly very enticing, however. I could definitely see myself adding a setup.py to my own workflows.

     

    How do you envisage the Alfred entry points working? How that might work is not obvious to me.

    Ideally this type of installation would be supported by Alfred internally but until that time we could have the bdist_alfred create a package that adds scriptfilters and such to a automatically generated plist file.

    So instead of having:

    setup(
        ...
        entry_points={
            'distutils.commands': [
                'upload_sphinx = sphinx_pypi_upload:UploadDoc',
            ],
        },
    )
    
    It could be something like:

    setup(
        ...
        entry_points={
            'alfred.scriptfilters': [
                'command = workflow_script:Command',
                'optional_arg_command * = workflow_script:OptionalArgCommand',
                'required_arg_command + = workflow_script:OptionalArgCommand',
            ],
        },
    )
    
    Note that all of this is purely theoretical at this point. But I do think it would make for an easier and more reusable system.
  6. Eh? We discussed your alternatives, and I explained why I didn't think they were a good fit.

    Let's call it a difference of opinion/philosophical differences and leave it at that.

    Perhaps it wasn't meant as such but that's what I felt given your earlier reaction in this topic.

    It's probably just a matter of backgrounds, I have little experience in the Alfred world but a lot of experience with regular Python packages. With regular Python packages the workflow is generally as I suggested but that might not be the best fit for Alfred packages of course. It has given me an idea for an alternative solution however. Let's continue the discussion here: http://www.alfredforum.com/topic/8765-packaging-python-workflows-would-a-setuptools-command-be-useful/

  7. There are currently several methods for packaging workflows, all with advantages and disadvantages of course.

    For example:

    It seems to me that there is a better solution though. The setuptools package is widely used within the Python community to compile, build and deploy packages to the PyPI servers but it can do more. The Sphinx-PyPI-upload-2 package for example (https://github.com/WoLpH/sphinx-pypi-upload) makes it possible to upload Sphinx documentation to the PyPI servers which can be built using the commands from Sphinx itself.

    With that regard I propose a new solution for packaging Alfred workflows:

  8. @wolph if you're still around....El Capitan killed the Applescript library I was working with (SerialPort X) and there seems to be no update.  How's that python version coming?

    I'm still around. My apologies for not getting much up and running yet, my life has been a crazy rollercoaster ride the last year and a half... I hope/expect it to settle down a bit the coming months. Although I am about to become a father so not entirely sure about that either ;)

     

    I think wolph disappeared when he realised nobody liked him.

    It's a massive shame really. He had an awful lot to offer, but unfortunately he talked down to everyone all the time, which got a good few people's backs up :(

    This is probably a case of the pot calling the kettle black, as I certainly think I tend to do that, too.

    I dunno. Perhaps he got the hump because he doesn't realise he's doing it.

    The only thing I didn't like was your condescending attitude. I realise that you have been a tremendous help for the Alfred community and I respect you for that but I if you're not open to discussing alternative solutions to common workflow problems... well, let's just say that limits my usefulness with your projects

    About this script, I'll resume working on it and will report back with the progress in about 2 weeks.

  9. Wow, works great :)

    Thanks Andrew!

    As for losing focus, while that's indeed an annoyance it might be preferable behaviour to the potential bugs after fixing it. Switching applications and purposefully defocussing Alfred might not be possible otherwise. At the very least that should have to be configurable.

  10. What I personally do (and which will probably work for deanishe as well) is have a computer connected to the TV which has Airserver installed. Airserver is a full Airplay server for both video and audio (even lossless) so it works perfectly for iphones and even macbooks.

    With that you can keep the current setup and speakers and only requires you to buy Airserver but beyond that it gives you all the needed options.

  11. That's definitely annoying... reading those reports though... I do think it might actually be the underlying driver that's responsible for the issue, but it's quite possibly being caused by PySerial.

    Regardless, if Python is not the best option, other languages can do as well :)

    It's actually not that difficult of a script to write, although the network version is slightly more difficult due to the auto detection of the receiver through broadcast messages. I've been making it far too complicated with an automated setup and everything... resulting in nothing really working right now. Argh... I really should try to do everything a bit more KISS

  12. I'm currently writing it in Python using Dean Jackson's workflow library with the Onkyo-EISCP library from Miracle2k (https://github.com/miracle2k/onkyo-eiscp). The commands between the serial version and the network version are luckily much the same, it's just a different socket and the network version requires some magic packet :)

    Onkyo obviously didn't need any performance here... 9600 baud, wow :P

×
×
  • Create New...