SwitchHosts!支持Alfred小记

很早就有人建议让 SwitchHosts! 支持 Alfred ,我也曾多次想过开发这个功能,但拖延症很严重,一直没有动手😅。最近注意到 SwitchHosts! 在 GitHub 上已经有超过 2000 个 star,开心的同时也觉得压力开始大了起来,于是抽空认真梳理了一遍代码,做了若干改造,修复了若干遗留问题(当然,还有一些仍待处理),最后,添加了对 Alfred workflow 的支持。

SwitchHosts-with-alfred

当然,由于 Alfred 仅支持 macOS,这个功能也只支持 macOS。

使用方法:

  1. 下载 SwitchHosts! 最新版本(v3.3.0或更新版本)
  2. 下载对应的workflow文件并安装
  3. 在 Alfred 界面输入关键词swh,即可列出当前 hosts 方案列表,并可直接在下拉菜单中进行切换

效果如下:

screen-shot

下面记录一下工作原理以及开发说明。

工作原理

工作原理非常简单:SwitchHosts! 启动时,开启一个 HTTP 服务,提供了list以及toggle两个接口,顾名思义,list就是列出所有可用的 hosts 方案,toggle则是切换指定方案。接下来,Alfred 则根据用户指令,请求对应的接口。如下图所示:

design.png@2x

HTTP 服务使用了 express.js 来实现(源码),随 app 启动,监听 50761 端口。启动 app 后,你可以在浏览器中访问 http://127.0.0.1:50761 ,如果能正常打开页面,并看到“Hello SwitchHosts!”的字样,表示 HTTP 服务已正常启动。

list接口(源码)的访问地址为 http://127.0.0.1:50761/api/list ,返回一个 JSON ,格式形如:

{
  "success": true,
  "data": [
    {
      "id": "1490959856569-442720",
      "title": "default",
      "content": "# ...",
      "on": true,
      "where": "local",
      "url": "",
      "last_refresh": null,
      "refresh_interval": 0,
      "include": []
    },
    {
      "id": "1490959856569-329205",
      "title": "my Tests",
      "content": "# ..",
      "on": true,
      "where": "local",
      "url": "",
      "last_refresh": null,
      "refresh_interval": 0,
      "include": []
    },
    ...

注意其中每个 hosts 方案都有一个id,这个id将会在下面的toggle接口中使用。

toggle接口(源码)的访问地址为 http://127.0.0.1:50761/api/toggle?id={id} ,它接受一个id参数,查询对应的 hosts,并进行切换。

目前 SwitchHosts! 只提供了 Alfred 支持,不过有了listtoggle这两个接口,理论上用户可以为任何第三方工具开发 SwitchHosts! 的支持。

接下来就是 Alfred 的部分了,源码在这里,使用的是 Python 作为开发语言,参考了这个教程

其中生成列表的代码如下:

# -*- coding: utf-8 -*-

import sys
# the workflow package below is download from:
# https://github.com/deanishe/alfred-workflow/releases
from workflow import Workflow, ICON_WEB, web

def get_subtitle(item):
    content = item.get('content', '')
    return content.partition('\n')[0].strip()

def main(wf):
    url = 'http://127.0.0.1:50761/api/list'
    r = web.get(url)

    # throw an error if request failed
    # Workflow will catch this and show it to the user
    r.raise_for_status()

    # Parse the JSON returned by pinboard and extract the posts
    result = r.json()
    items = result['data']

    # Loop through the returned posts and add an item for each to
    # the list of results for Alfred
    for item in items:
        on = item.get('on', False)
        wf.add_item(title=item['title'],
                    subtitle=get_subtitle(item),
                    arg=item['id'],
                    valid=True,
                    icon='on.png' if on else 'off.png')

    # Send the results to Alfred as XML
    wf.send_feedback()

if __name__ == '__main__':
    my_wf = Workflow()
    sys.exit(my_wf.run(main))

用到的 python workflow 模块可以从这儿下载。

用户选中切换的脚本则非常简单,传入 id 后,访问对应的 toggle 接口即可,Alfred 中的 workflow 脚本只有一行:

curl 'http://127.0.0.1:50761/api/toggle?id={query}'

最后,再贴一下 Alfred workflow 的下载地址,使用过程中有任何问题,欢迎给我提 issue

5 Replies to “SwitchHosts!支持Alfred小记”

  1. 在WIN10中以管理员身份打开,依然弹出错误,没有权限,提示用管理员身份打开软件。

    1. 可能是电脑上的安全软件引起的,比如360安全卫士、卡巴斯基等。试试将 SwitchHosts! 添加到安全软件的受信任组,并在文件监听里设置 hosts 为排除项。参见 #158

      1. 我的也出现这个问题, 未安装安全软件,win10防火墙已添加信任软件

发表评论

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Google+ photo

You are commenting using your Google+ account. Log Out / 更改 )

Connecting to %s