OSX:定义一个新的URL处理程序,直接指向一个Python脚本

15

我想在OSX下定义一个新的URL处理程序,它将指向一个Python脚本。

我已经将Python脚本打包成了一个小应用(右键点击.py文件,然后选择“打开方式”->“创建Applet”)

我已经将以下内容添加到应用程序的Info.plist中:

<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleURLName</key>
        <string>Do My Thing</string>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>dmt</string>
        </array>
    </dict>
</array>

我还使用了 More Internet 首选项面板 来指定 "dmt" 作为一种协议,但是当我尝试将该协议与我的小程序关联起来时,它显示“设置 app 作为 helper 时发生问题”。

有人知道我该从哪里开始吗?

谢谢

1个回答

17

经过一番折腾,我终于在OSX下使它工作了...

以下是我的解决方案:

在AppleScript Script Editor中编写以下脚本:

on open location this_URL
    do shell script "/scripts/runLocalCommand.py '" & this_URL & "'"
end open location

如果您想确保您正在运行特定shell中的Python(在我的情况下,我通常使用tcsh,有一个.tcshrc文件定义了一些环境变量,我希望能够访问),那么中间的行可能需要更改为:

do shell script "tcsh -c \"/scripts/localCommand.py '" & this_URL & "'\""

我希望在一个Python脚本中完成所有的实际处理,但由于OSX中URL处理程序的工作方式,它们必须调用应用程序包而不是脚本,因此在AppleScript中进行操作似乎是最简单的方法。

在脚本编辑器中,另存为“应用程序包”

找到保存的应用程序包,打开“Contents”。找到“Info.plist”文件并打开。添加以下内容:

<key>CFBundleIdentifier</key>
<string>com.mycompany.AppleScript.LocalCommand</string>
<key>CFBundleURLTypes</key>
<array>
  <dict>
    <key>CFBundleURLName</key>
    <string>LocalCommand</string>
    <key>CFBundleURLSchemes</key>
    <array>
      <string>local</string>
    </array>
  </dict>
</array>

在最后两行之前,应该是:

</dict>
</plist>

这里有三个字符串可能需要更改:

com.mycompany.AppleScript.LocalCommand
LocalCommand
local
第三个是处理程序ID - 因此URL将是local://something。然后传递到Python脚本。这就是我为此得到的内容。
#!/usr/bin/env python
import sys
import urllib
arg = sys.argv[1]
handler, fullPath = arg.split(":", 1)
path, fullArgs = fullPath.split("?", 1)
action = path.strip("/")
args = fullArgs.split("&")
params = {}
for arg in args:
    key, value = map(urllib.unquote, arg.split("=", 1))
    params[key] = value

你也可以使用py2app来剪掉AppleScript部分,我相信。 - spieden
1
你最近有没有找到更简单的方法来做这件事?似乎仍然是一个相当复杂的过程。此外,我正在使用Python构建一个.app,希望使用自定义回调协议回调进行Web服务授权。与仅运行Python脚本不同,我期望在协议调用时应用程序实例正在运行。如何确保它由打开的应用程序实例处理? - fatuhoku
@fatuhoku 应用程序需要检测到它已经在运行,并通过某种 IPC 转发请求。 - Erik Aronesty

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接