首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Applescript:用新的bookmark.plist编辑文件

Applescript:用新的bookmark.plist编辑文件
EN

Stack Overflow用户
提问于 2018-03-05 02:43:55
回答 1查看 1K关注 0票数 0
代码语言:javascript
运行
复制
set some_host to "test.mydomain.com"

try
    -- Ping the host.
    do shell script "ping -c 1 -t 1 " & some_host
    -- Set ipAddr.
    set ipAddr to word 3 of result
    -- Combine the IP with the URL & port.
    set urlAddr to "http://" & ipAddr & ":80"
    display dialog "Connection Successful. " & urlAddr buttons {"OK"} default button 1
on error
    -- if we get here, the ping failed
    display dialog "Conection failed. " & some_host & " is down" buttons {"OK"} default button 1
    return
end try

-- Update the URL with the new IP.
tell application "System Events"
    tell property list file "~/Library/Safari/Bookmarks.plist"
    set value of property list item "key" to text of urlAddr
    end tell
end tell

,这是我遇到的错误。,我应该提到,"key“将被我试图更改的书签名称所取代。

代码语言:javascript
运行
复制
error "System Events got an error: Can’t set property list item \"key\" of property list file \"~/Library/Safari/Bookmarks.plist\" to \"http://000.000.000.000:80\"." number -10006 from property list item "key" of property list file "~/Library/Safari/Bookmarks.plist"

Bookmark.plist示例:让我们将"Key“替换为"NVR摄像机”。

代码语言:javascript
运行
复制
<dict>
        <key>URIDictionary</key>
        <dict>
            <key>title</key>
            <string>NVR Camera</string>
        </dict>
        <key>URLString</key>
        <string>https://12.123.456.789:88</string>
        <key>WebBookmarkType</key>
        <string>WebBookmarkTypeLeaf</string>
        <key>previewText</key>
        <string>your description</string>
        <key>previewTextIsUserDefined</key>
        <true/>
    </dict>

我试图这样做,以更新URL自动到新的IP,如果它改变。如果有人有更好的解决方案,我会洗耳恭听的!提前感谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-03-05 05:56:27

属性列表数据与XML数据

下面是我的Safari bookmarks.plist文件的摘录:

代码语言:javascript
运行
复制
    <?xml version=\"1.0\" encoding=\"UTF-8\"?>
    <!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
    <plist version=\"1.0\">
    <dict>
        <key>Children</key>
        <array>
            <dict>
                <key>Title</key>
                <string>History</string>
                <key>WebBookmarkIdentifier</key>
                <string>History</string>
                <key>WebBookmarkType</key>
                <string>WebBookmarkTypeProxy</string>
                <key>WebBookmarkUUID</key>
                <string>92E8B75A-B335-4CA3-8DE9-08A09817792D</string>
            </dict>
            <dict>
                <key>Children</key>
                <array>
                    <dict>
                        <key>ReadingListNonSync</key>
                        <dict>
                            <key>neverFetchMetadata</key>
                            <false/>

这仅仅是前24行,标签<key>的标签出现了8次--大约每三行就出现一次。您可以想象为什么当有这么多人被告知要获取名为"key"的标记时,"key"会感到有点困惑。

话虽如此,但这并不是脚本抛出错误的原因。我在脚本编辑器中运行了这个命令

代码语言:javascript
运行
复制
    tell application "System Events" to ¬
        tell the property list file ¬
            "~/Library/Safari/Bookmarks.copy.plist" to ¬
            get every property list item whose name is "key"

(我使用的是bookmarks.plist文件的副本,因为它没有完全破坏任何.plist文件读取或写入的能力。)

该命令的输出是:{},它告诉我们没有标记为key的属性列表项。

尽管plist文件看起来像XML,但是AppleScript处理数据的方式与XML文件的处理方式不同。对于XML文件,可以使用其标记的名称(如<key> )引用元素。对于属性列表文件,元素以键/值对形式引用,因此,对于plist,XML数据中的<key>标记将有一个由名称"key"表示的,因此它将包含该属性的名称,该属性的值将立即跟随。

例如:

代码语言:javascript
运行
复制
    <key>Title</key>
    <string>History</string>

对于AppleScript中的XML数据,我们有两个XML元素:一个用值"Title"调用"key",另一个用值"History"调用"string"。对于plist数据,我们只有一个属性列表键/值对(item),名为"Title",其值为"History"

回到我最初的观点,确实存在多个具有相同名称的标记;同样,也有多个键/值对具有相同的键,而且很可能具有相同的值。

因此,无论您将数据作为XML处理还是作为属性列表处理,总是必须的才能告诉AppleScript所引用的属性列表树的哪个级别。

AppleScripting

要引用的层次结构级别完全取决于您希望将书签存储在何处:在它自己的文件夹中;在收藏夹中或其他已经存在的文件夹中;或者仅仅在书签集合的顶层,以便它在打开书签边栏时立即出现在列表中。

为了方便起见,我将演示最后一个选项:向文件夹树的顶层添加一个书签。我在下面标记了在plist文件中插入新条目的位置:

代码语言:javascript
运行
复制
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
        <key>Children</key>
        <array>
            <dict>...</dict>
            <dict>...</dict>
            <dict>...</dict>
            <!-- etc... //-->
            <dict>...</dict>
            <!-- insert new entry here //-->
        </array>
        <!-- other stuff //-->
    </dict>
    </plist>

如果运行以下命令:

代码语言:javascript
运行
复制
    tell application "System Events" to ¬
        tell the property list file ¬
            "~/Library/Safari/Bookmarks.copy.plist" to ¬
            get the properties of the last property list item of ¬
                the property list item "Children"

AppleScript将返回一个记录,这是它作为键/值对存储数据的(较小的)尝试。它基本上是一个AppleScript列表,其中列表中的每个条目都有一个标签,用于引用项目,而不是索引号。输出返回如下(为便于阅读而格式化):

代码语言:javascript
运行
复制
     {value:{URIDictionary: ¬
         {title:"website.com"}, ¬
          previewText:"The title of the website", ¬
          ReadingListNonSync:{neverFetchMetadata:false}, ¬
          Sync:{ServerID:"DAV-DB576E16-E590-44D3-839F-63C0A1A8D3BC", ¬
               |data|:«a whole lot of data»}, ¬
          WebBookmarkUUID:"A5E4774A-2C26-4AD1-9938-D192C26860B8", ¬
          URLString:"https://website.com/path/etc", ¬
          WebBookmarkType:"WebBookmarkTypeLeaf", ¬
          previewTextIsUserDefined:true}, ¬
      kind:record, ¬
      class:property list item, ¬
      name:missing value, ¬
      text:"The XML representation of the property list data."}

这将告诉我在plist文件中哪些项构成单个书签条目。请记住,从AppleScript的角度来看,每个项目本身都是一个property list item,因此需要单独创建。我将假设我们可以忽略WebBookmarkUUIDsync,这两种数据都包含我们不可能自己生成的数据。不过,其余的都很简单。

创建新书签条目

代码语言:javascript
运行
复制
    set urlAddr to "http://000.000.000.000:80"

    tell application "System Events" to tell ¬
        the property list file "~/Library/Safari/Bookmarks.plist" to tell ¬
        the property list item "Children" to tell ¬
        (make new property list item ¬
            at end of property list items ¬
            with properties {kind:record})

        make new property list item with properties ¬
            {name:"URIDictionary", kind:record}

        tell the result to make new property list item ¬
            with properties {name:"title", value:"mydomain.com", kind:string}

        make new property list item with properties ¬
            {name:"previewText", value:"Information about mydomain.com", kind:string}

        make new property list item with properties ¬
            {name:"URLString", value:urlAddr, kind:string}

        make new property list item with properties ¬
            {name:"WebBookmarkType", value:"WebBookmarkTypeLeaf", kind:string}

        make new property list item with properties ¬
            {name:"previewTextIsUserDefined", value:true, kind:boolean}

        make new property list item with properties ¬
            {name:"_tag", value:"AppleScript", kind:string}
    end tell

    return the result

在我的系统上运行它成功地创建了一个名为"mydomain.com“的新书签条目,当单击它时,尝试带我到URL "http://000.000.000.000”(根据您的urlAddr变量的虚拟值)。

更新书签

要在每次运行脚本时更新它,只需获取对书签的引用,然后是对包含书签所指向的property list item的信息的引用。

您会注意到,上面我创建了一个名为_tag的属性列表项,其他书签条目没有。我这样做是为了简单地通过搜索包含_tag的书签来获得对书签的引用。

代码语言:javascript
运行
复制
    tell application "System Events" to tell ¬
        the property list file "~/Library/Safari/Bookmarks.copy.plist" to tell ¬
        the property list item "Children" to ¬
        set bookmark to ¬
            the first property list item whose ¬
            name of property list items contains "_tag"

使用存储在变量bookmark中的书签引用,更新它所指向的URL,如下所示:

代码语言:javascript
运行
复制
    tell application "System Events" to tell ¬
        the property list file "~/Library/Safari/Bookmarks.plist" to tell ¬
        the property list item "Children"

        set bookmark to ¬
            the first property list item whose ¬
            name of property list items contains "_tag"

        set URLString to the first property list item ¬
            of bookmark whose name is "URLString"

        set the value of URLString to urlAddr
    end tell

更新:

在进一步测试并返回到通过AppleScript提交的更改之后检查AppleScript文件时,就会发现自动删除了用户定义的密钥_tag ,这令人遗憾。相反,它插入WebBookmarkUUID并为其生成值,这是很棒的。

因此,不幸的是,我们不能使用上面描述的方法标记我们的书签条目,以便于以后进行引用。

因此,这一新剧本因需要而更长。它旨在取代脚本中以tell application "System Events"开头的部分。

它将首先检查与指定的title匹配的书签是否存在于书签层次结构的顶层;如果没有,它将创建它;如果存在,它将用变量urlAddr中包含的内容更新它所指向的地址。

代码语言:javascript
运行
复制
    set urlAddr to "http://google.com"
    set myTitle to "mydomain.com"
    set plistFile to "~/Library/Safari/Bookmarks.plist"


    tell application "System Events"
        tell ¬
            the property list file plistFile to tell ¬
            the property list item "Children" to ¬
            set top_level to a reference to it


        set bookmarks to a reference to ¬
            (property list items of the top_level ¬
                whose name of property list items ¬
                contains "URLString")

        set labels to ¬
            a reference to property list item "title" of ¬
                property list item "URIDictionary" of ¬
                property list items of ¬
                the bookmarks


        if the value of the result ¬
            does not contain myTitle then ¬
            return saveBookmark of me ¬
                for urlAddr ¬
                to plistFile ¬
                at a reference to property list items of the top_level ¬
                given |title|:myTitle, previewText:"your description"


        repeat with i from the number of bookmarks to 1 by -1

            if item i of ¬
                the value of the labels is ¬
                myTitle then ¬
                exit repeat

        end repeat

        set bookmark to item i of bookmarks
        set the value of ¬
            property list item "URLString" of ¬
            the bookmark to ¬
            the urlAddr
    end tell


    to saveBookmark for www as string ¬
        at locationRef ¬
        to plist as string : "~/Library/Safari/Bookmarks.plist" given title:T ¬
        as string, previewText:_t as string : ""

        local www, locationRef, plist
        local T, _t


        tell application "System Events" to tell the property list file plist

            tell (make new property list item at end of locationRef ¬
                with properties {kind:record})

                tell (make new property list item with properties ¬
                    {name:"URIDictionary", kind:record}) to ¬
                    make new property list item with properties ¬
                        {name:"title", value:T, kind:string}

                make new property list item with properties ¬
                    {name:"previewText", value:_t}

                make new property list item with properties ¬
                    {name:"URLString", value:www}

                make new property list item with properties ¬
                    {name:"WebBookmarkType", value:"WebBookmarkTypeLeaf"}

                make new property list item with properties ¬
                    {name:"previewTextIsUserDefined", value:true}

            end tell
        end tell
    end saveBookmark

如果您的书签存在于书签层次结构的其他地方(例如在文件夹中),则当前将找不到它,并且将在顶层创建一个新的书签。我将让您使用我在这个示例脚本中演示的内容,并可能实现书签文件夹树的更深入遍历。

如果你有任何问题或问题,请留下评论,我会回复你的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49102741

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档