【问题标题】:osascript: how to keep nested lists structure when output from command-lineosascript:从命令行输出时如何保持嵌套列表结构
【发布时间】:2022-02-13 08:45:35
【问题描述】:

我正在尝试编写一个能够提取给定应用程序菜单结构的脚本。这是一个简化的工作示例:

tell application "System Events"
    tell process "Terminal"
        tell menu bar 1
            set listA to name of every menu bar item
            set listB to name of every menu of every menu bar item
            set listC to name of every menu item of every menu of every menu bar item
            set listD to name of every menu of every menu item of every menu of every menu bar item
            set listE to name of every menu item of every menu of every menu item of every menu of every menu bar item
        end tell
    end tell
end tell
return {listA, listB, listC, listD, listE}

当我在脚本编辑器上运行这个脚本时,结果是一组嵌套列表,像这样(实际结果太长,所以我给出一个示例):

{{{"Option1", "Option2", "Option3"}, {{"subOption1.1", "subOption1.2"}, {"subOption2.1", subOption2.2", "subOption2.3"}, {"subOption3.1"}}}

因此,很容易知道菜单 Option1 里面有两个项目,依此类推...

但是当我从 python 运行相同的脚本时,使用“osascript -e”,列表结构和大括号都消失了,就像这样

{{"Option1", "Option2", "Option3"}, {"subOption1.1", "subOption1.2", "subOption2.1", subOption2.2", "subOption2.3", "subOption3.1"}}

所以没有办法知道哪个子列表相互对应。

有没有办法保留这些大括号或将它们转换为您以后可以管理的不同的东西,或者将其写入一种保持嵌套结构的“原始”数据?

提前致谢!

【问题讨论】:

  • osascript 有一个 s 标志,可以以可重新编译的形式输出文本(参见手册页) - 您如何在 Python 脚本中使用结果?
  • 感谢您的回复!!! @red_menace,“-s”选项正是我需要的。我打算构建一个菜单结构(Python dict),您可以在其中拥有所有相关信息、项目层次结构、标题、矩形等。因此您甚至可以模拟对给定选项的点击。
  • 感谢您的回复!!! @foo,在开始编写我的模块(PyGetWindowMP)时,我尝试了很长时间的 py-applescript。我出于一个我现在不记得的原因丢弃了它(对不起)。也许只是为了避免依赖外部依赖。无论如何我都会尝试一下(新的)。

标签: macos applescript osascript


【解决方案1】:

遵循@red_menace 的建议,我终于设法获得了所有应用程序菜单结构:

    itemList = []

    def findit():

        level = 0

        while True:
            part = ""
            for lev in range(level):
                if lev % 2 == 0:
                    part = " of every menu" + part
                else:
                    part = " of every menu item" + part
            subCmd = "set itemList to name" + part + " of every menu bar item"

            if level % 2 == 0:  # Grabbing items only (menus will have non-empty lists on the next level)

                cmd = """
                        on run arg1
                        set procName to arg1 as string
                        tell application "System Events"
                            tell process procName
                                tell menu bar 1
                                    %s
                                end tell
                            end tell
                        end tell
                        return itemList as list
                        end run
                        """ % subCmd
                # https://stackoverflow.com/questions/69774133/how-to-use-global-variables-inside-of-an-applescript-function-for-a-python-code
                # Didn't find a way to get the "injected code" working when passed as argument
                proc = subprocess.Popen(['osascript', '-s', 's', '-', str(self._parent._app.localizedName())],
                                        stdin=subprocess.PIPE, stdout=subprocess.PIPE, encoding='utf8')
                ret, err = proc.communicate(cmd)
                ret = ret.replace("\n", "").replace('missing value', '"separator"').replace("{", "[").replace("}", "]")
                item = ast.literal_eval(ret)

                if err is None and not self._isListEmpty(item):
                    itemList.append(item)
                else:
                    break
            level += 1

        return itemList != []

    def fillit(subList):
       # Pending: build hierarchy structure (dict format) from list


    if findit():
        print(itemList)
        fillit(itemList)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-24
    • 1970-01-01
    • 1970-01-01
    • 2018-11-19
    • 1970-01-01
    相关资源
    最近更新 更多