Script: Copy Attachments to Default Folder for Library

Users asking other users for AppleScripts that work with Bookends.
Post Reply
DrJJWMac
Posts: 345
Joined: Sat Jun 22, 2019 8:04 am
Location: Alabama USA

Script: Copy Attachments to Default Folder for Library

Post by DrJJWMac »

This script will copy attachments into the default folder for an open library. This does NOT remove the links to the source attachment that may be in a different folder.

Code: Select all

(*
version 1.0
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 «----
*)

use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions

tell application "Bookends"
	
	activate
	-- collect information
	set the LName to name of the front library window
	set LName to (text items 1 thru -5 of LName) & "/" as text
	set theDPath to the default attachments path & LName
	
	-- collect the bibliographies to process
	set thePList to every publication item of front library window
	
	-- process
	repeat with thePub in thePList
		if the attachment items of thePub is not {} then
			set theAttachmentPath to the path of the first attachment item of thePub as text
			set theDesiredPath to theDPath & the name of the attachment item of thePub as text
			if theAttachmentPath is not equal to theDesiredPath then
				set sourceRef to (POSIX file theAttachmentPath) as alias
				set destFolder to (POSIX file theDPath) as alias
				-- copy fails if file already exists, so just try
				try
					tell application "Finder" to copy file sourceRef to folder destFolder
				end try
			end if
		end if
	end repeat
	return
end tell

--
JJW
DrJJWMac
Posts: 345
Joined: Sat Jun 22, 2019 8:04 am
Location: Alabama USA

Re: Script: Copy Attachments to Default Folder for Library

Post by DrJJWMac »

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
--
JJW
DrJJWMac
Posts: 345
Joined: Sat Jun 22, 2019 8:04 am
Location: Alabama USA

Re: Script: Copy Attachments to Default Folder for Library

Post by DrJJWMac »

This version fixes an oversight. Prior to changing the AppleScript text item delimiters, I now store the default and restore the default.

Code: Select all

(*
Create Stand-Alone BE Library
version 2021-07-12
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 oDelimiters to AppleScript's text item delimiters
	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
	set AppleScript's text item delimiters to oDelimiters
	return trimedText
end TrimSpaces

on getAuthorString(AuthorList)
	set oDelimiters to AppleScript's text item delimiters
	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
	set AppleScript's text item delimiters to oDelimiters
	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 oDelimiters to AppleScript's text item delimiters
	set AppleScript's text item delimiters to "/"
	set FolderParts to (text items 1 thru -2 of AttachmentPath)
	set FolderName to every item of FolderParts as text
	set AppleScript's text item delimiters to oDelimiters
	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
[\code]
--
JJW
DrJJWMac
Posts: 345
Joined: Sat Jun 22, 2019 8:04 am
Location: Alabama USA

Re: Script: Copy Attachments to Default Folder for Library

Post by DrJJWMac »

This version is updated with these changes

* copies or moves the attachment
* renames the attachment using the format libraryname_date author. This is equivalent to the renaming format "!_d a".

Run this with the Report option on All references to learn what actions would be taken.

CAVEAT: When the attachment already exists in the sub-folder AND exists in a different folder as the main reference, running action to DO will MOVE the attachment and likely overwrite the existing file in the sub-folder.

Code: Select all

(*
Put Attachments into Sub-Folder
version 2022-06-04
- final clean up
*)

use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions

-- set this to the label value for an error on a file attachment
-- use -1 to keep current label intact
property errLabel : 3

-- set this to true to make doing it the default action
property DoIt : false

on run {}
	
	if DoIt is false then
		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
	else
		set theAction to "Do"
	end if
	
	set theSet to the button returned of (display dialog "[All] or Selected Only?" buttons {"All", "Selected", "Cancel"} default button "All" cancel button "Cancel")
	if theSet is "Cancel" then end
	
	copyinto_AttachementsFolder(theAction, theSet)
	
end run

on copyinto_AttachementsFolder(theAction, theSet)
	
	if theAction is "Do" then
		set DoIt to true
		set theActionText to "Actions that Have Been Done" & return
	else
		set theActionText to "Actions that Would Be Done" & return
	end if
	
	set theAction to ""
	set theListBlank to {}
	set theListCopied to {}
	set theListMoved to {}
	set theListIgnored to {}
	set theListEmpty to {}
	
	--set theAttachmentFullPath to ""
	
	tell application "Bookends"
		activate
		
		-- set up
		tell the front library window to set theDesiredPath to the library attachments subfolder path as text
		set theActionText to theActionText & "Attachments Folder: " & theDesiredPath & return
		if theSet is "All" then
			set thePList to every publication item of front library window
		else
			set thePList to the selected publication items of front library window
		end if
		set nTotal to the number of items in thePList
		set theReport to "Year, Title, Current Name, New Name, Action" & return
		set theFrontWindowName to the name of the front library window
		set theLibraryName to my generate_LibraryName(theFrontWindowName)
		
		-- process
		repeat with thePub in thePList
			
			set thePubYear to the publication date string of thePub as text
			set thePubTitle to ("\"" & the title of thePub & "\"") as text
			set theAReport to ""
			
			-- 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 theAttachmentCurrName to the name of theAttachment
					set theAttachmentNewName to my set_AttachmentNewName(theLibraryName, the name of theAttachment, NAttached)
					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
						set theAction to "ORPHANED"
					else
						-- set the desired path
						set theDesiredFullPath to theDesiredPath & "/" & theAttachmentNewName
						if theAttachmentFullPath is not equal to theDesiredFullPath then
							-- possible need to copy or move file
							if theAttachmentCurrName is not equal to theAttachmentNewName then
								-- copy file
								set theShellCmd to "cp " & quoted form of theAttachmentFullPath & " " & quoted form of theDesiredFullPath
								-- try to copy ... failure means file already exists in destination
								set Copied to true
								set theAction to "TO COPY"
								if DoIt then
									set theAction to "COPIED"
									try
										do shell script theShellCmd
										copy {source:theAttachmentFullPath, destination:theDesiredFullPath, why:"copied", action:theAction} to the end of theListCopied
									on error
										set theAction to "NOT COPIED"
										set Copied to false
										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
								if Copied is true then
									set the name of theAttachment to theDesiredFullPath as text
								end if
							else
								-- move file
								set theShellCmd to "mv " & quoted form of theAttachmentFullPath & " " & quoted form of theDesiredFullPath
								set theAction to "TO MOVE"
								set Moved to true
								if DoIt then
									set theAction to "MOVED"
									do shell script theShellCmd
									copy {source:theAttachmentFullPath, destination:theDesiredFullPath, why:"moved", action:theAction} to the end of theListMoved
								else
									copy {source:theAttachmentFullPath, destination:theDesiredFullPath, why:"just reporting", action:theAction} to the end of theListMoved
								end if
							end if
						else
							-- attached file is already desired file
							copy {source:theAttachmentFullPath, destination:theDesiredFullPath, why:"destination = source", action:theAction} to the end of theListIgnored
							set theAction to "IGNORED"
						end if
					end if
					
					copy theAttachmentNewName to the end of theAttachmentsNameList
					set theAReport to theAReport & (thePubYear & "," & thePubTitle & "," & theAttachmentCurrName & "," & theAttachmentNewName & "," & theAction & return) as text
					set NAttached to NAttached + 1
				end repeat
				
				if DoIt then
					set the attachments of thePub to my reset_AttachmentsNames(theAttachmentsNameList)
				else
					set theAttachmentNames to my reset_AttachmentsNames(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
				set theAction to "NONE"
				set theAReport to theAReport & (thePubYear & "," & thePubTitle & ",NONE,NONE," & theAction & return) as text
			end if
			set theReport to theReport & theAReport as text
		end repeat
	end tell
	my reportValues(theActionText, nTotal, theListBlank, theListMoved, theListCopied, theListEmpty, theListIgnored)
	my writeValuestoFile(theReport, theDesiredPath, theFrontWindowName)
end copyinto_AttachementsFolder

on generate_LibraryName(theName)
	set theLibraryName to my trim_Spaces((text items 1 through -5 of theName as text))
	return theLibraryName & "_"
end generate_LibraryName

on trim_Spaces(inputText)
	set oDelimiters to AppleScript's text item delimiters
	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 text
	set AppleScript's text item delimiters to oDelimiters
	return trimedText
end trim_Spaces

on set_AttachmentNewName(LibName, FileName, NAttached)
	set theSuffix to ""
	if NAttached is not equal to 0 then
		set theSuffix to "_s" & NAttached as text
	end if
	set FileName to my splitoff_LibraryName(FileName)
	if the FileName contains the LibName then
		set theName to FileName
	else
		set theName to LibName & FileName & theSuffix
	end if
	return theName
end set_AttachmentNewName

on splitoff_LibraryName(theName)
	set oDelimiters to AppleScript's text item delimiters
	set AppleScript's text item delimiters to "_"
	set trimedText to text items of theName
	if the number of items in trimedText > 1 then
		set theName to (items 2 thru -1 of trimedText) as text
	else
		set theName to trimedText as text
	end if
	set AppleScript's text item delimiters to {}
	return theName as text
end splitoff_LibraryName

on reset_AttachmentsNames(AList)
	if the number of items in AList = 0 then return ""
	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 reset_AttachmentsNames

on reportValues(theActionText, nTotal, theListBlank, theListMoved, theListCopied, theListEmpty, theListIgnored)
	
	set nBlank to the number of items in theListBlank
	set nMoved to the number of items in theListMoved
	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 theActionText & "Total Processed: " & nTotal & return ¬
		& "Blank Path (error): " & nBlank & ¬
		"    No Attachment: " & nEmpty & return ¬
		& "Not Moved/Copied: " & nIgnored & return ¬
		& "Moved: " & nMoved & ¬
		"    Copied: " & nCopied
	
	display dialog theDialog buttons {"OK"}
	
end reportValues

on writeValuestoFile(theReport, thePath, theName)
	
	set theDate to do shell script "date '+%Y%m%d%H%M'"
	set theFileName to thePath & "/ Library Report " & theName & " " & theDate & ".csv" as string
	set theOpenedFile to open for access POSIX file theFileName with write permission
	write theReport to theFileName starting at eof
	close access theOpenedFile
	return
	
end writeValuestoFile
--
JJW
DrJJWMac
Posts: 345
Joined: Sat Jun 22, 2019 8:04 am
Location: Alabama USA

Re: Script: Copy Attachments to Default Folder for Library

Post by DrJJWMac »

I should post a short description on the possible reasons to use this script.

Suppose you have a (large) collection in the Attachments folder. You decide to split off a sub-collection in a library called MyCitations. This library should hold only the citations that you have authored. For whatever reason, you also decide that you want to put all the associated attachments for your citations into a new default Finder folder called My Citation Set. Here is how you would do this using this script.

- Create a new empty library MyCitations
- Open your master library side-by-side to MyCitations
- Drag + Drop or Copy + Paste the citations from your master library into the MyCitations library
- Close your master library
--> You now have a self-standing library that has only your citations. The problem remains to get the attachments COPIED into a new default sub-folder for this specific MyCitations library.

- While in the MyCitations library, open the menu File->Set Default Attachment SubFolder ...
- Create the new library Finder folder My Citation Set in the main Attachments folder
- Run the script to do a Report on All
--> You should end with a dialog that says what will happen when you Do (rather than Report) the script. You should also end with a CSV file in the My Citation Set Finder folder. The CSV report should show you a report about every citation in your MyCitations library. Specifically, the report will tell whether the reference has an attachment and whether that attachment will be copied. You will find that the new file names that will be COPIED into the Finder folder My Citation Set will follow the convention

LibraryName_YYYY Author

This is the same as using the naming format "!_d a" for attachments. The one distinction here is as follows: When a reference has more than one attachment, subsequent attachments will be suffixed with a number starting with 1. So these three files are indicated to belong to the same reference in the library MyCitations

MyCitations_2000 Jones.pdf
MyCitations_2000 Jones1.pdf
MyCitations_2000 Jones2.pdf

- When you are comfortable about what the report is saying, run the script with Do on All

I hope this provides the necessary and sufficient information to be comfortable using the script. Feel free to ask questions here.
--
JJW
Post Reply