2013-06-27 2 views
0

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

Мне нужно проверить наличие отдельных файлов на машине учителя и либо (a) выставить сообщение, в котором говорится, что «этот файл уже существует, переименовать его и загрузить снова» или (b) добавить что-то в имя файла, чтобы отличить его ... случайное число или «копия 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 

ответ

0

Я думаю, что это поможет, если ваша попытка-блок имел блок на-ошибок, чтобы сообщить Вам о каких-либо ошибок.

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 
0

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

Пример: если test.doc существует в папке уже тогда скрипт будет пытаться скопировать его с именем test_1.doc и так далее ..

оригинальный файл никогда не переименовывается, а старые файлы никогда не перезаписываются. Сценарий полностью прокомментирован, чтобы объяснить, что он делает.

** Update2 **

Копия в код назначения теперь в его собственном обработчике. Исходные файлы помечены индексом метки поиска 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 
+0

Незначительное обновление обработчику, чтобы использовать сообщение об ошибке для триггера, а не просто любую ошибку из команды cp shell. – markhunte

+0

Появляется новое обновление ** Update2 **, которое перестает копировать уже скопированные файлы. – markhunte

+0

Я думаю, что опубликованные полностью работающие, закодированные примеры могут быть хорошими, но я думаю, что это тоже хорошо, чтобы объяснить, как вы получили решение. – Kaydell

0

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

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

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

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

  3. Я установил блок ошибок в файле try-statement для отображения любых ошибок.

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