Python中如何编写Bangumi的Alfred workflow进行练手

可以在 alfred 里点格子;)

刚接触 python 没多久,感觉自己代码越写越不 OOP 了……可能该看看 fluent python 之类的书了

github


Python中如何编写Bangumi的Alfred workflow进行练手

1 回复

要写一个Bangumi的Alfred workflow,核心就是用Python处理Alfred的输入输出格式。Alfred workflow本质上就是个脚本,它通过sys.argv接收查询参数,然后输出特定格式的JSON给Alfred显示。

这里给你一个最基础的搜索番剧的示例。这个脚本会接收Alfred传入的查询关键词,然后调用Bangumi的API搜索动画,并把结果格式化成Alfred能识别的JSON。

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

import sys
import json
import urllib.request
import urllib.parse

def search_bangumi(query):
    """搜索Bangumi动画"""
    # 对查询词进行URL编码
    encoded_query = urllib.parse.quote(query)
    
    # Bangumi搜索API(这里用的是搜索条目接口,你可以根据需要调整)
    url = f"https://api.bgm.tv/search/subject/{encoded_query}?type=2&responseGroup=large"
    
    # 设置请求头,Bangumi API要求User-Agent
    headers = {
        'User-Agent': 'BangumiAlfredWorkflow/1.0 (your-email@example.com)',
        'Accept': 'application/json'
    }
    
    try:
        req = urllib.request.Request(url, headers=headers)
        with urllib.request.urlopen(req) as response:
            data = json.loads(response.read().decode('utf-8'))
            
            # 构建Alfred需要的items数组
            items = []
            for item in data.get('list', [])[:10]:  # 限制前10个结果
                # 提取需要的信息
                title = item.get('name', '未知标题')
                name_cn = item.get('name_cn', '') or title
                bangumi_id = item.get('id', '')
                image_url = item.get('images', {}).get('large', '')
                
                # 构建Alfred的item格式
                alfred_item = {
                    'uid': f'bgm_{bangumi_id}',
                    'title': name_cn,
                    'subtitle': f"原名: {title} | ID: {bangumi_id}",
                    'arg': f"https://bgm.tv/subject/{bangumi_id}",  # 按回车时传递的参数
                    'icon': {
                        'path': image_url if image_url else 'icon.png'
                    },
                    'text': {
                        'copy': f"https://bgm.tv/subject/{bangumi_id}",
                        'largetype': f"{name_cn}\n原名: {title}"
                    }
                }
                items.append(alfred_item)
            
            # 如果没有结果
            if not items:
                items.append({
                    'title': '没有找到相关动画',
                    'subtitle': '请尝试其他关键词',
                    'valid': False
                })
            
            # 输出Alfred格式的JSON
            output = {'items': items}
            print(json.dumps(output))
            
    except Exception as e:
        # 错误处理
        error_item = {
            'items': [{
                'title': '搜索失败',
                'subtitle': str(e),
                'valid': False
            }]
        }
        print(json.dumps(error_item))

if __name__ == '__main__':
    # Alfred会把查询词作为命令行参数传入
    query = ' '.join(sys.argv[1:]) if len(sys.argv) > 1 else ''
    search_bangumi(query)

怎么用这个脚本:

  1. 保存文件:比如保存为 bangumi_search.py
  2. 创建Alfred workflow
    • 新建一个空白workflow
    • 添加一个"Script Filter"输入
    • 语言选/bin/bash
    • 脚本里写:python3 /path/to/bangumi_search.py "{query}"
    • 设置好关键词触发(比如 bgm
  3. 添加后续动作:在Script Filter后面可以接一个"Open URL"动作,用 {query} 接收番剧链接

几个关键点:

  • Alfred的输入通过sys.argv[1:]获取
  • 输出必须是特定格式的JSON,包含items数组
  • 每个item要有titlesubtitlearg等字段
  • arg字段的值会传递给下一个动作

可以扩展的功能:

  • 搜索书籍、音乐、游戏(改API的type参数)
  • 添加收藏状态查询(需要用户认证)
  • 缓存搜索结果提升速度
  • 显示更多信息(评分、放送时间等)

这个基础版本能跑起来,你可以基于这个框架慢慢加功能。Alfred workflow的Python开发主要就是处理好输入输出格式,剩下的就是调用Bangumi API获取数据。

总结:先搞定基础搜索,再慢慢加功能。

回到顶部