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


我正在尝试在OSX下定义一个指向python脚本的新URL处理程序。

我已将Python脚本包装到applet中(右键单击.py,然后打开Open With - > Build Applet)

我已将以下内容添加到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>

我也用过 更多Internet首选项窗格 将“dmt”指定为协议,但当我尝试将协议链接到我的applet时,它会说“将应用程序设置为帮助程序时出现问题”

谁知道我应该从哪里去?

谢谢


7336
2018-03-10 17:09


起源



答案:


在经历了很多混乱之后,我已经成功地在OSX下工作了......

这就是我这样做的方式:

在AppleScript脚本编辑器中,编写以下脚本:

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

如果你想确保你从某个shell运行Python(在我的情况下,我通常使用tcsh,并且有一个.tcshrc文件,它定义了我想要访问的一些环境变量)那么那个中间line可能想成为:

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

我想在python脚本中进行所有实际处理 - 但由于URL处理器在OSX中的工作方式,他们必须调用应用程序包而不是脚本,因此在AppleScript中执行此操作似乎是最简单的方法做到这一点。

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

找到已保存的应用程序包和打开内容。找到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

12
2018-03-23 10:35



我相信你也可以使用py2app来删除AppleScript位。 - spieden
你有没有找到一个更简单的方法来做到这一点?这似乎仍然是一个相关的过程。而且,我正在建设一个 .app 在Python之外,想要使用自定义回调协议回调来进行Web服务授权。与运行Python脚本不同,我希望应用程序的实例在进行协议调用时运行。如何确保打开的应用程序实例处理它? - fatuhoku
@fatuhoku应用程序需要检测它已经在运行并通过某种ipc转发请求。 - Erik Aronesty


答案:


在经历了很多混乱之后,我已经成功地在OSX下工作了......

这就是我这样做的方式:

在AppleScript脚本编辑器中,编写以下脚本:

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

如果你想确保你从某个shell运行Python(在我的情况下,我通常使用tcsh,并且有一个.tcshrc文件,它定义了我想要访问的一些环境变量)那么那个中间line可能想成为:

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

我想在python脚本中进行所有实际处理 - 但由于URL处理器在OSX中的工作方式,他们必须调用应用程序包而不是脚本,因此在AppleScript中执行此操作似乎是最简单的方法做到这一点。

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

找到已保存的应用程序包和打开内容。找到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

12
2018-03-23 10:35



我相信你也可以使用py2app来删除AppleScript位。 - spieden
你有没有找到一个更简单的方法来做到这一点?这似乎仍然是一个相关的过程。而且,我正在建设一个 .app 在Python之外,想要使用自定义回调协议回调来进行Web服务授权。与运行Python脚本不同,我希望应用程序的实例在进行协议调用时运行。如何确保打开的应用程序实例处理它? - fatuhoku
@fatuhoku应用程序需要检测它已经在运行并通过某种ipc转发请求。 - Erik Aronesty