Applescript копирует файлы на смонтированный том; тест для файла (ов) уже существует

Я пишу сценарий, чтобы ученики могли загружать свои файлы в общую папку на компьютере учителя в компьютерной лаборатории (той же сети). У меня есть рабочий сценарий, который при выполнении дублирует все файлы из папки UPLOAD на компьютере ученика в папку SUBMISSIONS на машине учителя. Однако, если файл уже существует на компьютере учителя, сценарий зависает.

Мне нужно иметь возможность проверить наличие отдельных файлов на компьютере учителя и либо (а) выдать сообщение, которое говорит: "Этот файл уже существует, переименовать его и загрузить снова", либо (б) добавить что-то к имени файла, чтобы дифференцировать это... случайное число или "копия 1" и т. д.

В идеале я хочу, чтобы он работал как действие папки. Когда файл добавляется в папку "UPLOAD", он автоматически отправляется учителю. Но я не хочу, чтобы файлы копировались поверх файлов с одинаковыми именами... или чтобы скрипт зависал.

Любые мысли или альтернативные подходы будут приветствоваться.

Вот мой код:

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 ответа

Этот скрипт будет копировать каждый файл на подключенный том. Если файл существует с тем же именем в месте назначения, он добавит число в конец имени файла копии и попытается сделать это.

Пример: если 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

Я думаю, что было бы полезно, если бы у вашего блока try был блок 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

ХОРОШО. Я попытался снова написать код. Вот моя версия.

Он делает несколько вещей иначе, чем код, размещенный на оригинальном постере.

  1. Он копирует файлы и папки в новую папку на сервере с отметкой времени, чтобы справиться с проблемами того, существуют ли некоторые файлы на сервере.

  2. Я изменил формулировку дублирующего оператора с дублирования каждого "файла" на дублирование каждого "элемента", чтобы папки также дублировались.

  3. Я вставил блок ошибки в оператор try, чтобы отобразить любые ошибки.

  4. Я активирую Finder, чтобы вы могли видеть окно прогресса.

  5. В конце я выскакиваю диалог, если ошибок не было.

У меня была проблема, которую мне пришлось исправить:

  1. На сервере мне пришлось включить разрешения на запись для клиента, или я получил ошибку -5000.

Я думаю, что следующий код должен работать довольно хорошо. Это почти 100% AppleScript. Он использует только один вызов оболочки, чтобы получить текущую дату и отформатировать ее для отметки времени для новых папок, созданных на сервере.

# 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

Вот еще одна идея для отладки. Вы можете вызывать "диалог отображения", чтобы узнать, где происходит сбой вашего скрипта:

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, что для меня слишком дорого, но я использовал другие отладчики, и отладчики - замечательные инструменты, которые позволяют вам "заглянуть внутрь" вашего скрипта во время его работы, чтобы увидеть значение переменных и отследить, какие строки код выполняется.

Другие вопросы по тегам