【问题标题】:How do I pause and resume an AppleScript without a dialog box?如何在没有对话框的情况下暂停和恢复 AppleScript?
【发布时间】:2020-01-23 12:51:02
【问题描述】:

我正在努力在 AppleScript 中概述工作流程。该脚本接受了我需要从 Omnifocus 执行的下一个任务,并要求我确定是否可以在 2 分钟或更短的时间内完成。如果可以的话,它会启动一个计时器,我希望它等到我真正完成任务。现在我会弹出一个对话框,我可以在完成后将任务标记为完成。不幸的是,我需要在 Omnifocus 中完成一些任务,而在打开对话框的情况下,我无法在 Omnifocus 中执行任何操作。

我想避免使用该对话框,以便在脚本运行时在 Omnifocus 中工作。我希望能够告诉脚本我已完成,以便它可以停止计时器,告诉我完成任务需要多长时间,然后继续在 Omnifocus 中将任务标记为完成。我最初认为最好的方法是输入一个组合键。经过一番研究,我认为我不能在 AppleScript 中做到这一点。我对如何让我在脚本中间工作然后告诉程序我完成任务的任何想法持开放态度。

这是我的代码:

on run {}
    with timeout of (30 * 60) seconds
        tell application "OmniFocus"
            activate
        end tell
        tell application "OmniFocus"
            tell default document to tell front document window
                set perspective name to "Daily Wrap-Up"
                tell content to set TreeList to (value of first leaf)
                repeat with ListItem in TreeList
                    set ProjectName to name of containing project of ListItem as text
                    set TaskName to " - " & name of ListItem
                    set NoteName to " - " & note of ListItem
                    display dialog "The task is:" & return & ProjectName & TaskName & NoteName & return & "Can you do this in 2 minutes or less?" buttons {"Yes", "No"} default button "Yes"
                    set Button_Returned to button returned of result
                    if Button_Returned = "Yes" then

                        say "Get to work!"


                        set T1 to minutes of (current date)

                        set T1s to seconds of (current date)


                        display dialog "Click when done." buttons {"Complete", "Cancel"} default button "Complete"
                        set Button_Returned to button returned of result

                        if Button_Returned = "Complete" then



                            set T2 to minutes of (current date)

                            set T2s to seconds of (current date)

                            set TT_ to ((T2 * 60) + T2s) - ((T1 * 60) + T1s)

                            say "that took you" & TT_ & "seconds to complete"
                            display dialog ProjectName & TaskName & NoteName buttons {"Complete", "Defer", "Cancel"} default button "Complete"
                            set Button_Returned to button returned of result
                            if Button_Returned = "Complete" then
                                mark complete ListItem
                                tell application "OmniFocus"
                                    compact default document
                                end tell
                            else if Button_Returned = "Defer" then
                                display dialog "Defer for how long (in minutes)?" default answer "60"
                                set TimeAdd to text returned of result
                                set defer date of ListItem to ((current date) + (TimeAdd * minutes))
                                tell application "OmniFocus"
                                    compact default document
                                end tell
                            else if Button_Returned = "Cancel" then
                                tell application "OmniFocus"
                                    compact default document
                                end tell
                            else if Button_Returned = "No" then
                                tell application "OmniFocus"
                                    compact default document
                                end tell
                            end if
                        else if Button_Returned = "No" then
                            display dialog "Breakdown task."

                            set perspective name to "Projects"


                        end if
                    end if
                end repeat
            end tell
        end tell
    end timeout
end run

提前感谢您的帮助。

【问题讨论】:

  • 常规的AppleScript确实做不到,但是AppleScriptObjC可以用来创建一个显示窗口或者在菜单栏中放置一个statusItem来显示经过的时间。计时器只是您手动启动/停止的一种荣誉吗?
  • 是的。只是为了让我负责。我正在尝试将任务分解为小块。计时器给我反馈,以确保我成功并专注于我应该做的事情。
  • 我不使用 OmniFocus,但看看您的脚本,它似乎非常可编写脚本。由于这听起来像是供个人使用的东西,只有在您专注于执行这些任务时才会运行,因此创建一个在后台闲置并每隔几秒轮询一次以检查的 保持打开状态 应用程序并非不合理项目列表中的特定任务是否已在 OmniFocus 中勾选为已完成。可能比对话框更好?
  • 您可以使用保持打开的脚本应用程序来完成此操作,即使使用普通 AppleScript 也是如此,但如果您需要花里胡哨的功能,则需要使用 applescriptobjc。我将在今天晚些时候发布一个基本示例。

标签: applescript


【解决方案1】:

我的机器上没有 OmniFocus,所以我不能正确地编译这个少测试它,但在原版 AppleScript 中你可以执行以下操作:

global start_time, end_time, TreeList, current_task_index, TaskName, NoteName

on run
    tell application "OmniFocus"
        tell default document to tell front document window
            set perspective name to "Daily Wrap-Up"
            tell content to set TreeList to (value of first leaf)
        end 
    end
    set current_task_index to 1
    beginTask()
end

on reopen
    -- inserted try block to aid debugging
    try
        set end_time to (current date)
        set elapsed_time to end_time -start_time
        say "that took you " & elapsed_time & " seconds to complete"
        display dialog ProjectName & TaskName & NoteName buttons {"Complete", "Defer", "Cancel"} default button "Complete"
        set Button_Returned to button returned of result
            if Button_Returned = "Complete" then
                mark complete ListItem
                tell application "OmniFocus"
                    compact default document
                end tell
            else if Button_Returned = "Defer" then
                display dialog "Defer for how long (in minutes)?" default answer "60"
                set TimeAdd to text returned of result
                set defer date of ListItem to ((current date) + (TimeAdd * minutes))
                tell application "OmniFocus"
                    compact default document
                end tell
            else if Button_Returned = "Cancel" then
                tell application "OmniFocus"
                    compact default document
                end tell
            else if Button_Returned = "No" then
                tell application "OmniFocus"
                    compact default document
                end tell
            end if
        else if Button_Returned = "No" then
            display dialog "Breakdown task."
            set perspective name to "Projects"
        end if
        set current_task_index to current_task_index + 1
        if current_task_index <= count of TreeList then
            beginTask()
        else
            quit
        end
    on error errstr number errnum
        display alert "Error " & errnum & ": " & errstr
    end try
end

on idle
    (*
        you can use this handler if you want the app to give you a countdown, or 
        announce a time limit, or anything that needs doing while you're working on the task
    *)
end

on beginTask()
    tell application "OmniFocus"
        tell default document to tell front document window
            set perspective name to "Daily Wrap-Up"
            set ListItem to item current_task_index of TreeList
            set ProjectName to name of containing project of ListItem as text
            set TaskName to " - " & name of ListItem
            set NoteName to " - " & note of ListItem
            display dialog "The task is:" & return & ProjectName & TaskName & NoteName & return & "Can you do this in 2 minutes or less?" buttons {"Yes", "No"} default button "Yes"
            set Button_Returned to button returned of result
            if Button_Returned = "Yes" then
                say "Get to work!"
                set start_time to (current date)
            end if
        end tell
    end tell
end

将其复制到脚本编辑器中,对其进行调试,然后将其保存为应用程序,并选中“运行处理程序后保持打开”复选框。操作如下:

  1. 当 OmniFocus 准备就绪时,运行此脚本应用程序。它会提示您开始第一个任务。
  2. 完成第一个任务后,再次双击脚本应用程序图标以调用reopen 处理程序。该脚本将向您显示第一个任务所用的时间,为您提供您概述的选择,然后提示您开始第二个任务。
  3. 最后一个任务完成后,脚本会自动退出。

开头的全局变量允许在脚本进行时在处理程序之间传递必要的数据。

如果您想要更复杂的东西——例如,一个浮动窗口或菜单栏项,可以为您提供更细粒度的控制——那么您需要开始使用 ASOC 来构建它。但这是微调;这应该给你一个一般的结构。

【讨论】:

  • 这是重大进展。谢谢!我已经能够调试脚本并创建应用程序。在告诉我花了多长时间后,它不会创建对话框。我无法在脚本中将任务标记为完成。我想我可以排除故障,但我不知道如何查看应用程序的日志。我只能在编辑器中看到脚本第一部分的日志。我可以说,没有办法在编辑器中“重新打开”脚本。这意味着我看不到应用程序运行时出了什么问题。必须有一种获取日志的方法——我只是不知道它是什么。
  • @WillMcLemore — 嗯,首先,我想我看到了问题所在。我忘记在开头将ProjectName 添加到全局变量列表中,因此您可能会在reopen 处理程序的显示对话框语句中收到“未分配变量”错误。哎呀!不过,更一般地说,您可以将整个代码块封装在 try 博客中,并通过应用程序显示错误。我将编辑上面的reopen 处理程序,以便您明白我的意思;当你看到它时告诉我,以便我可以将代码恢复正常。
  • 泰德,我正在路上。谢谢您的帮助。我不清楚 try 块如何为我提供有关错误的更多信息,但让定义的变量修复了我需要的内容。 “重新打开”代码回答了我的问题并做了我想做的事情。谢谢。
猜你喜欢
  • 1970-01-01
  • 2020-09-04
  • 1970-01-01
  • 2011-03-27
  • 1970-01-01
  • 2019-05-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多