【问题标题】:AppleScript to automatically save mail attachments - works for new but not old emailsAppleScript 自动保存邮件附件 - 适用于新邮件但不适用于旧邮件
【发布时间】:2020-07-15 18:30:08
【问题描述】:

感谢大家迄今为止的帮助。很抱歉,我在上一个问题的“答案”部分提出了这个问题,我现在明白我不应该这样做......所以我在这里开始了一个新问题。

所以,我想编写一个脚本,以便在附件到达时将它们保存在电子邮件中 ​​- 每个电子邮件发件人都有一个不同的文件夹。我从这个网站上的人那里得到了很多帮助。

它有点工作......对于新收到的电子邮件它工作得很好,但是当我对我邮箱中的旧电子邮件运行它时,它会保存一些附件而不是其他附件。

我认为问题是查找重复项时出错(我认为这不太可能,因为我已将时间戳与电子邮件的数据戳一起添加到文件名中。)所以我添加了 delFile 删除过程来检查对于同名文件,如果找到则删除它。

当我执行脚本时,它会处理比以前更多的附件,但不是全部......有趣的是,没有任何东西被放入垃圾箱。

我现在被难住了!!作为 AppleScript 的新手,我还不知道如何调试或处理错误。

有人可以帮忙吗?

use scripting additions

using terms from application "Mail"
    on perform mail action with messages messageList for rule aRule
        set destinationPath to (POSIX file "/volumes/Data/Dropbox/WORK ITEMS/Email Attachments/") as string
        tell application "Mail"
            repeat with aMessage in messageList
                repeat with anAttachment in mail attachments of aMessage
                    set senderName to (extract name from sender of aMessage)
                    set {year:y, month:m, day:d, hours:h, minutes:min} to date received of aMessage
                    set timeStamp to (d & "/" & (m as integer) & "/" & y & " " & h & "." & min) as string
                    set attachmentName to timeStamp & " - " & name of anAttachment
                    
                    set doSave to true
                    set originalName to name of anAttachment
                    if originalName contains "jpg" then
                        set doSave to false
                    else if originalName contains "jpeg" then
                        set doSave to false
                    else if originalName contains "gif" then
                        set doSave to false
                    else if originalName contains "png" then
                        set doSave to false
                    else if originalName contains "html" then
                        set doSave to false
                    else if originalName contains "ics" then
                        set doSave to false
                    end if
                    
                    if doSave is true then
                        tell application "System Events"
                            if not (exists folder (destinationPath & senderName)) then
                                make new folder at end of alias destinationPath with properties {name:senderName}
                            end if
                        end tell
                    end if
                    
                    if doSave is true then
                        set delFile to destinationPath & senderName & ":" & attachmentName
                        tell application "System Events" to if (exists file delFile) then delete file delFile
                    end if
                    
                    if doSave is true then save anAttachment in file (destinationPath & senderName & ":" & attachmentName) with replacing
                    
                    
                    
                end repeat
            end repeat
        end tell
        
    end perform mail action with messages
end using terms from

谢谢

【问题讨论】:

  • 在你原来的问题中,我建议你去掉 if ... else if 并使用 list,甚至给你 code我>为它。我还建议您不要在 date 中使用/,而是使用-。你应该听那些比你更了解的人!

标签: applescript attachment


【解决方案1】:

我不确定我能否帮助您了解脚本失败的确切原因,但我或许可以帮助您了解它的失败之处。

首先,我会将您希望排除的文件扩展名列表替换为长 if...else if 块。比如:

set ignore list to {".jpg", ".jpeg", ".gif", ".png", ".html", ".ics"} 在脚本顶部,set fileExtension to rich text (offset of "." in originalName) thru end of originalName 在循环中。

然后您可以测试:

if fileExtension is not in ignoreList then

并将其包裹在保存代码周围(您无需多次执行相同的测试)。

我认为您的删除文件块是多余的,因为它应该与以下save...with replacing 执行相同的操作(如果文件已经存在)。 (如果文件存在,您可能希望删除该文件,在这种情况下,请稍后删除 with replacing。)

要开始调试,首先删除顶部处理传入消息的代码并将其替换为set messageList to selection。尝试在您不确定发生了什么的地方插入一些display dialog <varname>。例如,您知道 anAttachment 是什么,但您确定 destinationPath & senderName & ":" & attachmentName 是什么?

最后,请注意,我没有在您的数据上运行此程序,因此请务必进行备份。它不应该破坏任何东西,但安全总比后悔好!

如有任何问题,请回来。祝你好运!

编辑:

我在顶部添加了一个函数(on getExtension(fileName) 块。这由 set fileExtension to my getExtension(originalName) 行调用

这是通过反转名称字符串来细化扩展获取,因此只有第一个 '.'被发现。一旦得到扩展名就被反转了。

另一个关键部分是它包含try ... on error ... end try。这就是 AppleScript 进行错误处理的方式。如果没有“/”,则会引发错误。这被on error 捕获,它返回“skip”。 (此时,这在主程序中没有使用,但可用于将所有输出集中到一个包罗万象的文件夹中。)

最后的改变是我将保存部分包裹在If originalName does not contain "/" then ... end if中。这是为了捕获那些包含“/”的文件并在不做任何事情的情况下“跳过”它们。

我不需要添加delay,因此请尝试不添加delay。这可能是一个红鲱鱼!

set ignoreList to {".jpg", ".jpeg", ".gif", ".png", ".html", ".ics"}
set destinationPath to (POSIX file "/volumes/Data/Dropbox/WORK ITEMS/Email Attachments/") as string

on getExtension(fileName)
    try
        set fileName to (reverse of every character of fileName) as string
        set extension to text 1 thru (offset of "." in fileName) of fileName
        set extension to (reverse of every character of extension) as string
        return extension
    on error
        return "skip"
    end try
end getExtension


tell application "Mail"
    set messageList to selection
    
    repeat with aMessage in messageList
        repeat with anAttachment in mail attachments of aMessage
            set senderName to (extract name from sender of aMessage)
            set {year:y, month:m, day:d, hours:h, minutes:min} to date received of aMessage
            set timeStamp to (d & "/" & (m as integer) & "/" & y & " " & h & "." & min) as string
            set attachmentName to timeStamp & " - " & name of anAttachment
            set originalName to name of anAttachment
            if originalName does not contain "/" then
                set fileExtension to my getExtension(originalName)
                if fileExtension is not in ignoreList then
                    
                    tell application "System Events"
                        if not (exists folder (destinationPath & senderName)) then
                            make new folder at end of alias destinationPath with properties {name:senderName}
                        end if
                    end tell
                    
                    save anAttachment in file (destinationPath & senderName & ":" & attachmentName) with replacing
                end if
            end if
        end repeat
    end repeat
    
end tell

从邮件规则调用:

use scripting additions

set ignoreList to {".jpg", ".jpeg", ".gif", ".png", ".html", ".ics"}
set destinationPath to (POSIX file "/Users/bernardharte/test/") as string

on getExtension(fileName)
    try
        set fileName to (reverse of every character of fileName) as string
        set extension to text 1 thru (offset of "." in fileName) of fileName
        set extension to (reverse of every character of extension) as string
        return extension
    on error
        return "skip"
    end try
end getExtension

using terms from application "Mail"
    on perform mail action with messages messageList for rule aRule
        
        tell application "Mail"
            
            repeat with aMessage in messageList
                repeat with anAttachment in mail attachments of aMessage
                    set senderName to (extract name from sender of aMessage)
                    set {year:y, month:m, day:d, hours:h, minutes:min} to date received of aMessage
                    set timeStamp to (d & "/" & (m as integer) & "/" & y & " " & h & "." & min) as string
                    set attachmentName to timeStamp & " - " & name of anAttachment
                    set originalName to name of anAttachment
                    if originalName does not contain "/" then
                        set fileExtension to my getExtension(originalName)
                        if fileExtension is not in ignoreList then
                            
                            tell application "System Events"
                                if not (exists folder (destinationPath & senderName)) then
                                    make new folder at end of alias destinationPath with properties {name:senderName}
                                end if
                            end tell
                            
                            save anAttachment in file (destinationPath & senderName & ":" & attachmentName) with replacing
                        end if
                    end if
                end repeat
            end repeat
            
        end tell
        
    end perform mail action with messages
end using terms from

【讨论】:

  • 另一个想法:destinationPath 正确吗?它不应该以大写的“V”开头吗?
  • 谢谢以上,对解释和代码很有帮助。太有趣了!我如上所述运行它,显示带有 4 封电子邮件的对话,它运行良好。我重新添加了邮件命令并运行了 4 封电子邮件,它运行良好,然后删除了显示对话框并运行了 200 封电子邮件,它几乎没有工作,但是当我将显示对话框命令放回时它工作正常。邮件是否有可能运行得太快而无法继续发送邮件消息(与显示对话框的唯一区别是它运行缓慢,因为我需要确认我已经看到了消息)
  • 我将编辑原始答案中的代码并解释我所做的事情。
  • 这就解释了为什么会出现问题:冒号在 macOS 上被用作路径分隔符。老实说,我不确定它是如何从一个转移到另一个的,但是您可以通过在名称字符串中的该位置替换其他内容来处理它。可能再过一次;)
  • 我无法确定它没有作为邮件规则运行的原因。我怀疑这与权限/沙盒有关。我建议您专门发布另一个问题 - 连同您的脚本。这样你会得到更多帮助。
猜你喜欢
  • 2013-12-29
  • 1970-01-01
  • 2012-05-07
  • 1970-01-01
  • 2011-11-26
  • 1970-01-01
  • 2011-01-09
  • 1970-01-01
  • 2020-11-10
相关资源
最近更新 更多