gpt4 book ai didi

javascript - 具有执行Javascript并传递Applescript变量的Applescript

转载 作者:行者123 更新时间:2023-11-30 14:01:16 28 4
gpt4 key购买 nike

我编写了一个脚本,该脚本可以在我管理的网站上自动创建产品。在我的过程中,我上传产品的JPEG图像,并提取JPEG中标记的关键字以添加到产品信息中。在此过程中,我使用Applescript激活Safari并处理Javascript代码行。代码行包含一个从Applescript Shell脚本派生的变量。

下面的代码

tell application "Finder"
set sourceFolder to folder POSIX file "/Users/<username>/Desktop/Upload/Temp/HighRes/"
set theFiles to files of sourceFolder
set inputPath to "/Users/<username>/Desktop/Upload/Temp/"

end tell

repeat with afile in theFiles

set filename to name of afile

set fname to text 1 thru ((offset of "." in filename) - 1) of filename

--INPUT CODE TO BE LOOPED OVER BELOW--


--Add Image Keywords from Metadata--
try
set pathVAR1 to "/Users/<username>/Desktop/Upload/Temp/HighRes/"

set pathVAR2 to pathVAR1 & filename

set myvar to do shell script "mdls -name kMDItemKeywords " & quoted form of pathVAR2

set var1 to ((offset of "(" in myvar) + 1)

set var2 to ((length of myvar) - 1)

set myKeywords to ((characters var1 thru var2 of myvar) as string)

--Inputs the Keywords from the Image Metadata--
tell application "Safari"
activate
do JavaScript "document.getElementById('ctl00_cphMainContent_txtKeyWords').value = \"" & myKeywords & "\";" in current tab of window 1
end tell
end try

--END OF CODE TO BE LOOPED OVER--


end repeat


==结束代码==

问题:

下面的代码没有将变量myKeywords传递给Safari,但是如果我运行一个对话框,它将显示在对话框中。

do JavaScript "document.getElementById('ctl00_cphMainContent_txtKeyWords').value = \"" & myKeywords & "\";" in current tab of window 1

最佳答案

我没有一个绝对可以解决您问题的特定解决方案,但是我对您的脚本有很多观察,并提出了有关如何更改脚本以提高其速度,健壮性和遵循最佳实践原则的建议。


摆脱该try块。如果用不必要的错误捕获掩盖错误,则您不知道发生错误时脚本中正在发生什么。 try...end try唯一需要包含的行是do shell script,但是只有在知道代码可以正常工作时才将其放入。通常,仅应使用try块:


当脚本有可能引发完全可以预测和解释的错误时,并且您了解错误发生的原因和条件,并允许您实施有效的错误处理方法;
在发生错误的代码行数最少的情况下,保留所有代码行的存在不依赖于容易出错的语句的结果;
在编写,测试和调试脚本之后,在出现未知原因的不便错误后,放置try块不再用于强制脚本继续执行,但该脚本具有清晰,良好的功能,定义的功能,以与您的代码和谐地执行,而不是与之相反。

作为AppleScript中的一般规则,如果可以避免,请不要使用Finder来执行文件系统操作:它很慢,并且在执行操作时会阻塞,这意味着您在此期间无法与GUI进行交互。请改用系统事件。它是一个无面子的应用程序,在执行任务时不会停止其他操作。特别是在AppleScript和Finder的情况下,它速度很快,并且不像Finder那样容易超时。它本机处理posix路径(包括波浪号的扩展),而无需使用POSIX file进行任何强制转换;它返回alias对象,这是其他所有可编写脚本的应用程序都可以理解的文件对象的通用类。

在某些情况下,仍需要使用Finder。系统事件不能reveal文件;也无法在Finder中获取当前选择的文件。但是,使Finder将selection作为alias list检索,然后切换到“系统事件”以对该列表进行实际的文件处理非常简单。
这很好奇:

set filename to name of afile
set fname to text 1 thru ((offset of "." in filename) - 1) of filename


我是否认为 fname打算仅保留文件名的基本文件名部分,并且此操作旨在删除扩展名是对的吗?这是一个很好的第一次尝试,并且在这里使用 text逐项列出字符串的组成部分而不是 characters做得很好。但是,如果文件名中包含多个 ".",那么它最终会砍掉的不仅仅是文件扩展名,这并不罕见。

一种安全地cast割文件名末尾的方法是使用 text item delimiters

set filename to the name of afile
set fname to the filename

set my text item delimiters to "."
if "." is in the filename then set fname to text items 1 thru -2 of the filename as text


然后,您应该注意或重新设置 text item delimiters,否则稍后尝试将字符串连接在一起时会产生后果。

不使用 text item delimiters切分扩展名的另一种方法是字符串扫描,它是您遍历字符串的字符,在执行过程中执行操作或测试,并获得所需的结果。它比听起来快,并且是用于非常复杂的字符串搜索和操作的强大技术:

set filename to the name of afile
set fname to the filename

repeat while the last character of fname ≠ "."
set fname to text 1 thru -2 of fname
end

set fname to text 1 thru -2 of fname


您还可以检索文件的 name extension属性,获取文件的长度,并从文件名末尾删除 (1 + that)许多字符。有无数种方法可以达到相同的结果。
在这种特定情况下,这是错误的:

set myKeywords to ((characters var1 thru var2 of myvar) as string)


characters生成一个 list,然后必须将其连接回 string,如果不确定 text item delimiters设置为什么,这将是不安全的。由于您在脚本中没有对其进行引用,因此应将其设置为空字符串,这将导致字符重新组合成单​​词,从而产生预期的结果。但是,如果您执行了文件扩展名cast割的第一种技术而忽略了将 text item limiters设置回去的事实,那么情况就很容易发生,那么结果字符串在每个字母之间会有一个句点。

作为AppleScript中的一项策略(您可以选择坚持还是忽略),如果您执行列表强制转换操作而不先将 text item delimiters设置为最终值,则某些人会将其视为较差的形式。

但是您不必在这里这样做,因为您可以使用 characters而不是使用 text

set myKeywords to text var1 thru var2 of myvar

您正在执行如下所示的shell命令: mdls -name kMDItemKeywords <file>,然后笨拙地跟随AppleScript的两行尝试修剪bash数组的文本表示形式周围的前后括号。相反,您可以打开 -rawmdls标志,通过为您剥离键名来简化输出。然后,将括号作为第一个和最后一个字符。但是,由于在输出中也有大量空白空格,因此您最好让bash为您执行所有清理工作:

mdls -raw -name kMDItemContentTypeTree <file> | grep -E -io '[^()",[:blank:]]+'


这不考虑括号,双引号,逗号和空格,因此您得到的只是一个关键字列表,每行一个,并且没有任何多余的负担。如果需要逐项列出,则可以将变量设置为 the paragraphs of命令 do shell script的输出,该命令将文本分成几行,将每个关键字放入列表中。但是在这里似乎您需要文本并且不介意它是多线性的。




当我开始写这个答案时,我并不清楚什么是导致您来到这里的特定问题的原因。详细介绍了 mdls格式化其输出的细节之后,我现在看到的问题是 myKeywords字符串将包含一串双引号,并且您已经包围了 myKeywords实体的位置在JavaScript表达式中用双引号引起来。所有这些引号在AppleScript环境中仅被均等地转义一次,而在JavaScript环境中仅被一次转义,这导致每个相邻的双引号都充当开/闭对。我在bash中运行了类似的命令来获取值数组( kMDContentTreeType),然后以AppleScript的方式处理文本,然后在浏览器中打开JavaScript控制台并将其粘贴以说明发生了什么:

JavaScript console

字符串中包含红色的内容。因此,其他所有内容都将用作JavaScript标识符或对象(或者如果弄乱的引号也不会弄乱语法,则将导致未终止的字符串,该字符串仍希望最后一个引号与之配对。

我认为解决方案是使用连续字符 "\"与较旧的浏览器向后兼容:因此,您需要在每行(最后一行除外)后面加上反斜杠,并且需要更改双引号对JavaScript表达式中的 myKeywords值应为一对单引号。在较新的浏览器中,您可以不必在每行上添加连续标记,而将一对外部双引号替换为一对反引号( `)来代替:


❌'This line throws
an EOF error in
JavaScript';


✅'This line is \
processed successfully \
in JavaScript';


✅`This line is also
processed successfully
in JavaScript`;

关于javascript - 具有执行Javascript并传递Applescript变量的Applescript,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56281333/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com