This version has the following features:
* choose whether to report, do, or cancel
* choose whether to change label on items that have "ghost" (missing) attachments
* define (by scripting) the format for the desired file name
--> default is LFOLDER_YYYY Authors{_sN} where LFOLDER is a trimmed version of the library folder name, Authors takes the first two (with etal if more) and _sN is a sequence number for more than one attachments
* MOVES the attachment file if it is already in the desired folder, otherwise COPIES the attachment file
What remains is to have the ability to determine the library attachment sub-folder for a given library window. The default is the library name. If the default library sub-folder does not exist, this code will likely crash.
If you have ScriptDebugger (and probably ScriptEditor), I encourage you to run this in Report mode with the editor open. You can see the accumulation of variables and decode what will and will not be copied/moved.
Code: Select all
(*
Create Stand-Alone BE Library
version 2021-07-06
author jjw
- open a library
- run this script
- searches over all publications
- when attachments are not in the default folder for the library, copies attachments to the default folder for the library
----» ASSUMPTION: the default folder name is the same as the library name «----
- renames the attachement with a prefix for the default folder name
*)
use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions
-- set this to the label value for an error
-- use -1 to keep current label intact
property errLabel : 3
-- set this to the default action
property DoIt : false
-- the function to return the desired name for the attachment file
-- LibraryName is the library name
-- thePub is the publication item
on setDesiredName(LibraryName, thePub, NAttached)
set rtnStr to ""
-- remove spaces from LibraryName and add suffix
set prefixStr to my TrimSpaces(LibraryName) & "_"
-- capture only the year
tell application "Bookends" to set thePubDateStr to the publication date string of thePub as text
try
set theYear to (text items 1 thru 4 of thePubDateStr) as text
on error
set theYear to "0000"
end try
-- get only the first author from the Authors
tell application "Bookends" to set AuthorList to authors of thePub as text
set AuthorStr to my getAuthorString(AuthorList)
-- handle multiple attachments after the first (0 valued)
if (NAttached is not equal to 0) then set AuthorStr to AuthorStr & "_s" & NAttached
-- set the return
set rtnStr to prefixStr & theYear & " - " & AuthorStr & ".pdf" as text
return rtnStr
end setDesiredName
on TrimSpaces(inputText)
set AppleScript's text item delimiters to {space}
set trimedText to text items of inputText
set AppleScript's text item delimiters to {}
set trimedText to trimedText as string
return trimedText
end TrimSpaces
on getAuthorString(AuthorList)
set AppleScript's text item delimiters to {"
"}
set theEAStr to ""
set theAList to every text item of AuthorList as list
set NAuthors to the number of items in theAList
if NAuthors > 1 then
if NAuthors = 2 then
set theFirstA to (the first item of theAList) as text
set theSecondA to (the second item of the theAList) as text
set AppleScript's text item delimiters to ","
set theANames to (the first text item of theFirstA) & " and " & (the first text item of theSecondA) as text
else
set theFirstA to (the first item of theAList) as text
set AppleScript's text item delimiters to ","
set theANames to (the first text item of theFirstA) as text
set theEAStr to " etal"
end if
else
if NAuthors = 0 then
set theANames to {"unknown"}
else
set theFirstA to (the first item of theAList) as text
set AppleScript's text item delimiters to ","
set theANames to (the first text item of theFirstA) as text
end if
end if
set theRStr to theANames & theEAStr as text
return theRStr
end getAuthorString
on setAttachmentsNames(AList)
set theNameList to the first item of AList as text
set the AList to the rest of the AList
repeat with theItem in AList
set theNameList to theNameList & "
" & theItem as text
end repeat
return theNameList
end setAttachmentsNames
on run {}
set theListBlank to {}
set theListCopied to {}
set theListIgnored to {}
set theListEmpty to {}
set theAction to the button returned of (display dialog "Report or Do?" buttons {"Report", "Do", "Cancel"} default button "Report" cancel button "Cancel")
if theAction is "Cancel" then end
if theAction is "Do" then set DoIt to true
tell application "Bookends"
activate
set LName to the (name of the front library window) as text
set theLibraryName to (text items 1 thru -5 of LName) as text
set theRootAttachmentFolder to the default attachments path as text
set theLibraryFolder to theRootAttachmentFolder & theLibraryName as text
set thePList to every publication item of front library window
set nTotal to the number of items in thePList
-- process
repeat with thePub in thePList
-- check for attachments
if the attachment items of thePub is not {} then
-- process publications that should have attachments
set NAttached to 0
set theAttachmentsNameList to {}
set theAttachmentNames to ""
repeat with theAttachment in the attachment items of thePub
set theAttachmentFullPath to (the path of theAttachment) as text
if theAttachmentFullPath is "" then
-- store info when attachment file path is blank
set thePubDate to the publication date string of thePub as text
set thePubAuthors to the authors of thePub as text
copy {PubDate:thePubDate, pubAuthors:thePubAuthors, pubPath:theAttachmentFullPath} to the end of theListBlank
set the label color of thePub to errLabel
else
-- process first attachment
-- set the desired path
set theDesiredName to my setDesiredName(theLibraryName, thePub, NAttached) as text
set theDesiredFullPath to theLibraryFolder & "/" & theDesiredName
if theAttachmentFullPath is not equal to theDesiredFullPath then
set CopyIt to false
set theSourceFolder to my getSourceFolder(theAttachmentFullPath)
if theSourceFolder is not equal to theLibraryFolder then set CopyIt to true
-- attached file is not in desired location
if CopyIt then
set theShellCmd to "cp " & quoted form of theAttachmentFullPath & " " & quoted form of theDesiredFullPath
set theAction to "copy"
else
set theShellCmd to "mv " & quoted form of theAttachmentFullPath & " " & quoted form of theDesiredFullPath
set theAction to "move"
end if
-- try to copy ... failure means file already exists in destination
if DoIt then
try
do shell script theShellCmd
--set the attachments of thePub to theDesiredName
copy {source:theAttachmentFullPath, destination:theDesiredFullPath, why:"copied/moved", action:theAction} to the end of theListCopied
on error
copy {source:theAttachmentFullPath, destination:theDesiredFullPath, why:"already exists", action:theAction} to the end of theListIgnored
end try
else
copy {source:theAttachmentFullPath, destination:theDesiredFullPath, why:"just reporting", action:theAction} to the end of theListCopied
end if
else
-- attached file is already desired file
copy {source:theAttachmentFullPath, destination:theDesiredFullPath, why:"destination = source", action:theAction} to the end of theListIgnored
end if
copy theDesiredName to the end of theAttachmentsNameList
end if
set NAttached to NAttached + 1
set NAttachedStr to " " & NAttached as text
end repeat
if DoIt then
set the attachments of thePub to my setAttachmentsNames(theAttachmentsNameList)
else
set theAttachmentNames to my setAttachmentsNames(theAttachmentsNameList)
end if
else
-- store info for publications without attachments
set thePubDate to the publication date string of thePub as text
set thePubAuthors to the authors of thePub
set thePubID to the id of thePub as text
copy the {PubDate:thePubDate, pubAuthors:thePubAuthors, pubID:thePubID} to the end of theListEmpty
end if
end repeat
end tell
my reportValues(nTotal, theListBlank, theListCopied, theListEmpty, theListIgnored)
end run
on getSourceFolder(AttachmentPath)
set AppleScript's text item delimiters to "/"
set FolderParts to (text items 1 thru -2 of AttachmentPath)
--set AppleScript's text item delimiters to ""
set FolderName to every item of FolderParts as text
return FolderName
end getSourceFolder
on reportValues(nTotal, theListBlank, theListCopied, theListEmpty, theListIgnored)
set nBlank to the number of items in theListBlank
set nCopied to the number of items in theListCopied
set nEmpty to the number of items in theListEmpty
set nIgnored to the number of items in theListIgnored
set theDialog to "Total: " & nTotal & return ¬
& "Blank: " & nBlank & tab ¬
& "Empty: " & nEmpty & tab & tab ¬
& "Ignored: " & nIgnored & tab ¬
& "Copied/Moved: " & nCopied & tab
display dialog theDialog buttons {"OK"}
end reportValues