Alfred Workflow 豆瓣插件开发

1 篇文章 0 订阅
本文介绍了如何改造Alfred workflow,以实现豆瓣评分和信息的查询。作者首先分析了原有Python2版本的工作原理,然后利用Python3和lxml库解析网页以获取信息。在开发过程中,作者遇到的挑战包括Alfred的bash环境限制和变量传递问题,并分享了调试技巧。此外,文章还提到了将插件重构为Go语言版的可能性,以解决环境依赖问题。
摘要由CSDN通过智能技术生成

背景:

Alfred的介绍和使用不过多介绍,作为mac上的神器,他的workflow支持外部扩展,也可以自己开发,支持多种开发语言,其实远不止他显示的这几种,因为支持bash,只要本地能运行的程序理论上都支持。

作为豆瓣的轻度依赖者,我基本上使用豆瓣来查看书籍和电影的评分,主要用于判断是否值得投入时间来看。之前用的插件是  GitHub - xinhangliu/alfred-workflow,他依赖了豆瓣提供的api。现在豆瓣应该不提供api了,导致基本不可用了,我只能用他来快速跳转到豆瓣,没办法直接查看相关的评分和信息。调研了一下,发现可以通过解析网页的方式来获取相应的信息。加上原来的插件是用python2写的,也算是自己熟悉的语言,于是想着改造应该也不困难。 改造之后的代码:GitHub - ykdsg/workflow-douban: alfred workflow for douban. Use python3 and lxml.

workflow相关概念:

首先开发workflow,需要对他的核心组件有一定的了解,像Trigger、Inputs、Actions、Utilities、Outputs 分别代表什么意思。最便捷的方式是通过查看别人的workflow,以及官方的示例。

 还有就是查看官方文档了  Workflows - Alfred Help and Support

这里直接引用这篇文章里面的介绍:使用Python写一个Alfred Workflow - 执子之手

Triggers: Activate Alfred from a hotkey, another Alfred feature or an external source. 简单的说Triggers的用途就是通过热键或者其他方式启动Alfred,进而启动Workflow。

Inputs: Keyword-based objects used to perform an action, on its own or followed by a query. Inputs通过一个定义的关键字对象来执行一个action,这个关键字可以带查询参数也可以不带。例如你定义关键字mc,那么在Alfred搜索框中输入mc就可以启动这个功能。

Actions: The objects that do most of the work in your workflows; opening or revealing files and web searches, running scripts and performing commands. Actions对象在workflows中负责完成绝大多数的工作,例如可以打开文件,打开搜索,执行脚本等等。

Utilities: Utilities give you control over how your objects are connected together and how the arguments output by the previous object is passed on to the next object. Utilities可以让你控制你的对象如何连接在一起工作,控制参数如何在对象之间传递。这个对象我用的不多。

Outputs: Collect the information from the earlier objects in your workflow to pop up a Notification Centre message, show output in Large Type, copy to clipboard or run a script containing the result of your workflow. Outputs对象负责从你的Workflow中的前一个对象中收集信息,然后真正输出到系统中,这个输出可能是:弹出一个通托盘通知,拷贝到剪贴板,写一个文件,播放一个声音等等。

这是几个大类,每个大类下有很多具体的组件,实际用不上这么多,刚开始对大类有个印象就行了。

 这里直接用网上的一张图来说明各个部分的大概作用。上面是有道翻译的workflow,可以比较清晰的看到各个部分的作用。

插件开发:

因为在原来的插件基础上开发,所以先看下原来插件的情况

 双击第一个script filter

可以看到就是在alfred中输入“douban”会唤起这个插件,并调用selection.py 这个脚本,点击右下角的方块可以打开workflow的本地目录,就能看到相应文件。看了下selection.py这个文件,逻辑还是比较简单的 ,想要达到的效果就是:

对于 script filter 输出结果需要满足Alfred的要求,可以具体参考 : Script Filter JSON Format - Workflow Input Objects - Alfred Help and Support

是一个json格式,类似:

{
   "items":[
      {
         "title":"Search Douban for 'test'",
         "icon":{
            "path":"image/douban.png"
         },
         "arg":"test",
         "variables":{
            "selection":"douban"
         }
      },
      {
         "title":"Book",
         "icon":{
            "path":"image/book.png"
         },
         "arg":"test",
         "variables":{
            "selection":"book"
         }
      },
      {
         "title":"Movie",
         "icon":{
            "path":"image/movie.png"
         },
         "arg":"test",
         "variables":{
            "selection":"movie"
         }
      },
      {
         "title":"Settings",
         "icon":{
            "path":"image/settings.png"
         },
         "arg":"test",
         "variables":{
            "selection":"settings"
         }
      }
   ]
}

 比较重要的是arg和variables,arg会作为参数传递到后面的组件,variables中的变量用于区分我们选择了book还是movie。

接着继续查看后面的组件

可以看到根据上面variables中的变量selection用于判断相应的流程,但是这里的形式已经变成了{var:selection} 。

接着再往下看下一个Script Filter,这个就是这个插件最核心的部分。

 

其中{query} 就是上一步 操作选中item的arg。很多时候我们也需要selection,但是在这里是不能用{var:selection}来传递的,这个在后面我自己维护的时候发现是个坑。貌似{var:selection}只能用于workflow自己组件内部,在bash里面没有传入,但是可以通过环境变量来获取,神不神奇。

selection = os.getenv('selection') 

查看core.py,整体逻辑就是通过访问douban api,然后输出json,格式跟上面的items一样。 清楚之后改造就简单了,利用python的lxml库能够比较方便的解析html结构,获取相应的信息组装成items就行了。源码在  GitHub - ykdsg/workflow-douban: alfred workflow for douban. Use python3 and lxml.

Debug:

在开发的过程中,通常是本地测试好之后,在workflow中跑起来,实际还是会有一些问题,这个时候就需要debug。

点击右上角就能够开启debug模式,会输出相应的日志,注意这里只会输出标出错误的信息,就是普通的log.info 是不会输出的,只有log.error 才会输出。

需要特别注意的地方:

  1. 虽然支持bash,zsh 但是跟本地终端还是不一样的,会发现他很多命令找不到,但是本地终端上是明确可以运行的。这个是Alfred 的默认保护机制,他只加载少数特定的目录,类似/usr/bin ,/usr/local/bin ,其他不会加载。所以如果你要用的命令找不到的话,就需要使用绝对路径。
  2. variables 在程序中只能通过环境变量获取,在bash 中通过{var:selection} 是传递不了的。

关于go 版本

python 的开发还是比较简单的,因为动态语言的特性,加上丰富的三方库,特别适合干这类杂活。但是存在一个问题是如果要把插件分享出去,就需要对应的同学有相应的环境:python的版本以及依赖的lxml,这个实在太不友好了,目前也没找到特别好的解决方案(可以把lxml拷贝到当前workflow的目录下,但是python3环境不一定所有人都有)。刚好最近在学习go ,就想着能不能用go重写这个插件,因为可以打包成可执行文件,就不存在环境依赖的问题。所以用go 重新写了这个插件 ,Releases · ykdsg/my_go (github.com)

源码在:https://github.com/ykdsg/my_go/tree/master/douban

这里吐槽下go的开发:

  1. 大小写决定是否private,所谓简单的原则,在很多时候造成的是麻烦,比如alfred 规定了items的json格式,而且是大小写敏感的,那就非常坑了,必须用下面这种格式来标记序列化之后的字段
    Title     string            `json:"title"`

  2.  log.Panicln 会导致整个程序退出,我天,简直刷新三观了。我打印一下日志,你就理所当然的帮我exit了,go标榜的简单哲学是不是太过了。说好的只做一件事呢,这么干确定不会增加程序员的心智负担吗。

最后看一下这个版本的效果:

选择book之后(略微有一丢慢,这个是douban网站的速度决定的): 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值