0

我正在编写一个脚本,允许学生将他们的文件上传到计算机实验室(同一网络)教师计算机上的共享文件夹。我有一个工作脚本,执行时会将学生机器上 UPLOAD 文件夹中的所有文件复制到教师机器上的文件夹 SUBMISSIONS 中。但是,如果教师计算机上已经存在文件,则脚本会挂起。

我需要能够测试教师机器上是否存在单个文件,并且(a)弹出一条消息,说明“此文件已经存在,重命名并再次上传”或(b)在文件名中附加一些内容区分它......一个随机数或“副本1”等。

理想情况下,我希望它作为文件夹操作运行。当一个文件被添加到“上传”文件夹时,它会自动发送给老师。但我不希望文件复制同名文件……或者让脚本挂起。

欢迎任何想法或替代方法。

这是我的代码:

set home_path to path to home folder as string
set work_folder to alias (home_path & "Desktop:" & "Upload")

try
    mount volume "afp://[LOGIN INFO].local/Submissions"
    set this_folder to result as alias
    tell application "Finder"
        tell application "Finder"
            duplicate every file of work_folder to this_folder
        end tell
        eject this_folder
    end tell
end try
4

4 回答 4

0

好的。我再次尝试编写一些代码。这是我的版本。

它做了几件事与原始海报发布的代码不同。

  1. 它将文件和文件夹复制到服务器上带有时间戳的新文件夹中,以应对服务器上是否已存在某些文件的问题。

  2. 我将重复语句的措辞从复制每个“文件”更改为复制每个“项目”,以便文件夹也被复制。

  3. 我在 try 语句中放入了一个 on-error 块来显示任何错误。

  4. 我激活 Finder 以便您可以看到进度窗口。

  5. 如果没有错误,我会在最后弹出一个对话框。

我有一个必须解决的问题:

  1. 在服务器上,我必须为客户端启用写权限,否则我收到 -5000 错误。

我认为下面的代码应该工作得很好。它几乎是 100% AppleScript。它只使用对 shell 的一次调用,即获取当前日期并将其格式化为在服务器上创建的新文件夹的时间戳。

# set the path to the "work_folder" where the files are to be uploaded
set home_path to path to home folder as string
set work_folder to alias (home_path & "Desktop:" & "Upload")

# duplicate the files and folders in work_folder to the server
try
    # TODO set the name of your server here
    set the_volume to mount volume "afp://32-bit.local/Submissions"
    set destination_path to the_volume as text
    set folder_name to getTimeStamp()
    tell application "Finder"
        activate
        set new_folder to make new folder at alias destination_path with properties {name:folder_name}
        duplicate every item of work_folder to new_folder
        eject the_volume
        display alert "Successfully uploaded the files and folders"
    end tell
on error error_message number error_number
    if error_number is not equal to -128 then
        display alert "Error: " & error_message & return & return & (error_number as text)
    end if
end try

# This function returns the current date and time as a time-stamp of the form yyyy-mm-dd-hh-ss
# This function uses a shell script because it's just a lot easier to do than in AppleScript
on getTimeStamp()
    set time_stamp to do shell script "date '+%Y-%m-%d-%H-%M-%S'"
    return time_stamp
end getTimeStamp
于 2013-06-30T01:09:16.010 回答
0

这是调试的另一个想法。您可以调用“显示对话框”以了解您的脚本在哪里失败:

display dialog "Entering script"
set home_path to path to home folder as string
display dialog "home_path: " & home_path
set work_folder to alias (home_path & "Desktop:" & "Upload")
display dialog "work_folder: " & work_folder as string

try
    mount volume "afp://32-bit.local/Submissions"
    set this_folder to result as alias
    display dialog "this_folder: " & this_folder as string
    tell application "Finder"
        display dialog "Inside of the first tell application Finder"
        tell application "Finder"
            display dialog "About to call duplicate"
            duplicate every file of work_folder to this_folder
            display dialog "Just returned from calling duplicate"
        end tell
        display dialog "About to call eject"
        eject this_folder
        display dialog "Just returned from call to eject"
    end tell
on error error_message number error_number
    display alert "Error:" & error_message & return & return & (error_number as text)
end try
display dialog "Exiting script"

另一种调试技术是将输出记录到文本文件中。

另一种调试技术是购买 AppleScript 调试器:

http://www.latenightsw.com/sd4/index.html

我相信这个调试器要花费 200.00 美元,这对我来说太贵了,但是我使用过其他调试器,调试器是很棒的工具,可以让您在脚本运行时“窥视”脚本的内部,以查看变量的值并跟踪其中的哪些行正在执行代码。

于 2013-06-30T01:26:58.320 回答
0

此脚本会将每个文件复制到已安装的卷上。如果在目的地存在同名的文件,它将在复制文件名的末尾添加一个数字并尝试。

示例:如果文件夹中已经存在test.doc,则脚本将尝试使用名称test_1.doc复制它,依此类推..

原始文件永远不会被重命名,旧文件永远不会被覆盖。该脚本已完全注释以解释它在做什么。

**更新2 **

复制到目标代码现在在它自己的处理程序中。原始文件由查找器标签索引 6(绿色)标记,表示复制成功。

这也将通过使用索引颜色作为检查来阻止相同的原始文件被复制两次。如果它被标记为索引标签 7,它将被忽略。

如果您想使用脚本将成功复制的文件移动到另一个文件夹中,您可以这样做。但我没有在这个脚本中这样做。

            set home_path to path to home folder as string
        set work_folder to alias (home_path & "Desktop:" & "Upload")
        set counter to ""
        global counter
        --try

        set this_folder to mount volume "afp://myMac/UserName/"
        this_folder as text


tell application "Finder" to set theFiles to every file of work_folder as alias list #GET ALL FILES OF LOCAL FOLDER AS ALIASES
tell application "Finder" to set theRemoteFiles to (every file of ((this_folder & "Submissions:" as string) as alias)) #GET ALL FILES OF REMOTE FOLDER -- ONLY NEEDED FOR COUNT CHECK LATER

repeat with i from 1 to number of items in theFiles #PROCESS EACH LOCAL FILE 

    set this_item to item i of theFiles #GET A LOCAL FILE
    tell application "Finder" to set LabelIndex to label index of this_item
    if LabelIndex is not 6 then
        tell application "Finder" to set this_name to displayed name of this_item #GET ITS DISPLAYED NAME
        tell application "Finder" to set this_extension to name extension of this_item #GET ITS EXTENSION NAME i.E "txt"
        set realName to (do shell script "echo " & quoted form of this_name & "| awk -F '" & quoted form of this_extension & "' '{print $1}'") #GET ITS NAME WITHOUT EXTENSION NAME

        set counter to 1 # SET A NUMBER TO ADD TO THE FILE NAME IF THE FILE NAME EXIST ALREADY IN THE REMOTE FOLDER
        my checkName(this_name, realName, this_item, this_extension, theRemoteFiles, this_folder) # CALL TO HANDLER THAT WILL DO THE CHECKING AND COPYING
    end if

end repeat
tell application "Finder" to eject this_folder

# THE  CALL TO THE HANDLER INCLUDES VARIABLES THAT ARE NOT GLOBAL OR PROPERTIES BUT NEED TO BE PASSED ON TO IT  I.E(this_name, realName, this_item, this_extension, theRemoteFiles, this_folder)
on checkName(this_name, realName, this_item, this_extension, theRemoteFiles, this_folder)


    # (1) IF THE NUMBER OF theRemoteFiles IS GREATER THAN 0 THEN FILES EXIST IN THE REMOTE FOLDER AND MAY CONTAIN FILES WITH THE SAME NAMES AS THE LOCAL ONES. PROCESS..
    # (2) IF THE NUMBER OF theRemoteFiles IS NOT GREATER THAN 0.THEN FILES DO NOT EXIST IN THE REMOTE FOLDER AND THE LOCAL ONES CAN JUST BE COPIED OVER.
    if (count of theRemoteFiles) is greater than 0 then # (1)

        try
            my copyOver(this_item, this_folder, this_name)

        on error errMssg #WE USE not overwritten ERROR TO TRIGGER THE RENAME THE DESTINATION  FILE NAME TO INCLUDE A NEW NUMBER.
            --tell application "Finder" to set label index of this_item to 6
            if errMssg contains "not overwritten" then

                set this_name to (realName & counter & "." & this_extension)
                set counter to counter + 1 #WE SETUP THE FILE NAME NUMBER FOR THE POSSIBLE NEXT RUN

                # RUN THE HANDLER AGAIN WITH THE CHANED DETAILS
                my checkName(this_name, realName, this_item, this_extension, theRemoteFiles, this_folder)
            end if

        end try

    else # (2)
        my copyOver(this_item, this_folder, this_name)
    end if
end checkName

on copyOver(this_item, this_folder, this_name)
    # THE -n  OPTION IN THE SHELL COMMAND TELLS CP NOT TO OVERWRITE EXISTING FILES. AN ERROR OCCURE IF THE FILE EXISTS.
    # THE -p  OPTION IN THE SHELL COMMAND TELLS CP   TO PRESERVE THE FOLLOWING ATTRIBUTES OF EACH SOURCE FILE  IN THE COPY:
    # modification time, access time, file flags, file mode,
    #user ID, and group ID, as allowed by permissions.  Access Control
    #Lists (ACLs) and Extended Attributes (EAs), including resource
    #forks, will also be preserved.
    # THE -v  OPTION IN THE SHELL COMMAND TELLS CP TO USE VERBOS MODE. WHICH GIVES US A BETTER CLUE OF THE ERROR

    set theResult to (do shell script "cp -npv " & quoted form of (POSIX path of this_item) & space & quoted form of (POSIX path of (this_folder & "Submissions:" as string) & this_name))
    if theResult contains "->" then
        tell application "Finder" to set label index of this_item to 6
    else
        tell application "Finder" to set label index of this_item to 7
    end if

end copyOver
于 2013-06-29T12:47:09.750 回答
0

我认为,如果您的 try-block 有一个 on-error 块来通知您任何错误,这将有所帮助。

try
    # try stuff here
    j # this will compile but will throw a runtime error and you can see the error
on error error_message number error_number
    display alert "Error: " & error_message & return & return & (error_number as text)
end try
于 2013-06-29T10:59:36.920 回答