script that limits or at least warns of folder size

hello and first of all apologies for my ignorance. I am very new to applescript.
I am a photographer, desperate to find a folder script that warns me when the
folder contents reach 649 Mb.

I fill folders with pictures and then burn these
folders onto cds for archival purposes. But every time it is very hard to make
sure the contents of the folder do not exceed the capacity of the cd.
can you help me or let me know who can help me?
I presume it would be a very easy script, but whilst i have learnt how to use
scripts i am useless at writing them.
I hope someone can help me.

I have a script (still a work in process) that does something similar. The behavior is like this: It looks for a networked drive named “Jobs”. If it is mounted then it looks for the last folder inside. Jobs contains DVD folders named “DVD 001”, “DVD 002”, etc. As each reaches its capacity (4.2 GB) it is considered filled by the script and the script will make a new DVD folder named “DVD 003”, or whatever is the next increment in the chain of DVD numbers.

This script will read each file or folder that is currently selected in the front-most window of the Finder. It loops through each one, comparing its size with the capacity of the last DVD folder, if it will fit without exceeding the maximum capacity (defined by the property maxSize) then it is moved into it, otherwise a new DVD folder is made and then the new files are all added into it, until it is full…

(*****PROPERTIES*****)
property maxSize : 4900 --the size in megabytes that is the disk's maximum capacity
--for a CD just change to 649
property theLastFolder : null

(*****SCRIPT BODY*****)
tell application "Finder"
	--choose folder with prompt "choose destination folder"
	--set theFolder to the result
	--set theLastFolder to the last folder of theFolder
	--choose folder with prompt "choose the source folder"
	--set theFiles to the result
	
	set theWindow to front window
	--return theWindow
	set theFiles to get selection
	--return theItems
	
	if disk "Jobs" exists then
		set theFolder to folder "6 Completed" of disk "Jobs"
		--return theFolder
	else
		display dialog "The network drive 'Jobs' is unavailable"
		return false
	end if
	
	set theLastFolder to the last folder of theFolder
	--return theLastFolder
	
	repeat with i from 1 to (count of theFiles)
		
		set thisFile to item i of theFiles
		log thisFile
		
		--obtain the physical size of the destination folder and source files we are trying to move
		set theFolderSize to my check_folder_size(theLastFolder)
		set theFilesSize to my check_folder_size(thisFile)
		
		--test to see if the source files will fit into the destination folder
		set test to my willFileFit(theFilesSize, theFolderSize)
		
		--if the files fit then move them, otherwise make a new folder, then move the files into the new folder
		if test = true then
			log "test was true - moving files"
			my moveItems(thisFile, theLastFolder)
		else
			log "test was false - making new folder then moving"
			set thisFolder to my makeNewFolder(theFolder)
			my moveItems(thisFile, thisFolder)
			set theLastFolder to thisFolder
		end if
		
	end repeat
end tell

(*****HANDLERS*****)
on check_folder_size(theFolder)
	--Input: the folder whose size is of interest
	--Output: the size of the folder in MB
	
	tell application "Finder"
		try
			--this repeats 3 times because the Finder will lag a bit in calculating the size of a folder if it does not yet exist
			--this forces the Finder to calculate the size and insures (hopefully) that enough time has elapsed to do so.
			--if you find that 5 times is not enough then increase the number
			repeat 100 times
				if physical size of theFolder ? missing value then exit repeat
			end repeat
		end try
		
		set folderSize to physical size of theFolder
	end tell
	
	set adjustedFolderSize to (folderSize / (1024 * 1024))
	return adjustedFolderSize
end check_folder_size



on moveItems(theseItems, thisFolder)
	--Input: the list of items to be moved, and the destination they are to be moved to
	--Output: true or false based on success of the move
	tell application "Finder"
		set folderContents to name of folders of thisFolder
		set itemName to name of theseItems
		--check to see if the file to be moved already exists in the target folder
		if folderContents does not contain itemName then
			try
				move theseItems to thisFolder
				return true
			on error
				error
				return false
			end try
		else
			display dialog ("The folder '" & itemName & "' already exists in '" & thisFolder & "'.")
		end if
	end tell
end moveItems



on makeNewFolder(theParentFolder)
	--Input: the parent folder that will contain the new folder
	--Output: New folder with incremented name
	log "making new folder..."
	
	tell application "Finder"
		set theName to name of last folder of theParentFolder
		log theName
		set theShortName to characters -1 thru -3 of theName
		set temp to (item 1 of theShortName & item 2 of theShortName & item 3 of theShortName)
		
		repeat 1 times
			if (character -3 of temp = "0") then
				
				if ((character -2 of temp = "9") and (character -1 of temp = "9")) then
					set folderNumber to temp + 1
					exit repeat
					
				else if (character -2 of temp = "0") and (character -1 of temp ? "9") then
					set folderNumber to ("00" & temp + 1)
					exit repeat
				end if
				
				set folderNumber to ("0" & temp + 1)
				exit repeat
			else
				set folderNumber to temp + 1
			end if
		end repeat
		
		set newFolderName to ("DVD " & folderNumber)
		make new folder at theParentFolder with properties {name:newFolderName}
		set theNewFolder to folder newFolderName of theParentFolder
		log "made new folder named " & theNewFolder
		return theNewFolder
	end tell
end makeNewFolder



on willFileFit(destFolderSize, srcFilesSize)
	--Input: One destination folder, one set of source files, the maximum size limitations (global variable)
	--Output: true or false answering the question: will the source files fit into the destination folder?
	log "testing size"
	set comboSize to destFolderSize + srcFilesSize
	log "combo size is " & comboSize
	log "maxSize is " & maxSize
	if comboSize < maxSize then
		return true
	else
		return false
	end if
end willFileFit

I hope this helps you in finding a solution. You should be able to adapt this for your purposes. If you have any questions please ask.

jON bEEEBE

thanks!
I will look and try to understand. Can I ask you to tell me HOW to change what i need to change (i think i might need to change more than just max size).
Also do you think one could create a folderattached script which just tells the folder it has 650MB SPACE. Would that not solve all our problems? then all the folders we use for picture would automatically not exceed cd/dvd capacity.
I was thinking of giving it a property and then tell it to calculate size and it reaghes over 649 display dialog “full” or something like that.
I tried it but could not make it work.

This folder action script might be suitable but I haven’t done much testing so it could stand further scrutiny. It uses code written by Nigel Garvey (Nigel’s code is likely the most efficient part of the script!).

on adding folder items to this_folder after receiving added_items
	set byteSize to size of (info for this_folder)
	set size_ to convertByteSize from byteSize
	set n to (word 1 of size_) as number
	set m to word 2 of size_
	
	if n > 649 and m is "MB" then
		display dialog "Folder: " & return & return & POSIX path of this_folder & return & ¬
			return & "Folder size has now reached " & size_
	end if
end adding folder items to

to convertByteSize from byteSize -- by Nigel Garvey
	if byteSize is greater than or equal to 1.099511627776E+12 then -- Terabytes (2 ^ 40) 
		((byteSize / 1.099511627776E+12 div 0.01 / 100.0) as string) & " TB"
	else if byteSize is greater than or equal to 1.073741824E+9 then -- Gigabytes (2 ^ 30) 
		((byteSize / 1.073741824E+9 div 0.01 / 100.0) as string) & " GB"
	else if byteSize is greater than or equal to 1048576 then -- Megabytes (2 ^ 20) 
		((byteSize / 1048576 div 0.01 / 100.0) as string) & " MB"
	else if byteSize is greater than or equal to 1024 then -- Kilobytes (2 ^ 10) 
		((byteSize div 1024) as string) & " K"
	else
		(byteSize as string) & " bytes"
	end if
end convertByteSize

– Rob

Hello Rob, and thank-you.
I copied the code you posted (copied the whole thing) pasted it into a new editor window and saved it in the folder actions scripts in the Library.
Then i created a new folder and attached the folder action to the folder.
Tried to put into this folder 1.3gb of images and it let me do it, no warning of full capacity or anything.
What did i do wrong?
Should have i copied only a portion of the script you posted? or save it in a special way? (i saved it as script)
thanks for your help, really

I downloaded the script as well and ran it - it works great.

alexroggero, I think your problem was that you added 1.3 GB, and the script is testing for sizes over 650 AND for the text “MB”. If you ad in any quantity over 999 MB the script will not activate the message. This code:

if n > 649 and m is "MB" then
		display dialog "Folder: " & return & return & POSIX path of this_folder & return & ¬
			return & "Folder size has now reached " & size_
	end if

Should be altered. For example:

if n > 649 and m is "MB" then
		display dialog "Folder: " & return & return & POSIX path of this_folder & return & ¬
			return & "Folder size has now reached " & size_
		
	else if m is "GB" or m is "TB" then
		display dialog "Folder: " & return & return & POSIX path of this_folder & return & ¬
			return & "Folder now contains  " & size_
	end if

This will check for sizes over 999 MB.

jON bEEBE

Note: As I was composing this reply, jON bEEBE offered some code which should be useful.

Here’s the modified, untested version of the script that I came up with to address the issue that might have caused the script to fail (the folder action was probably kicking in before the file duplication was complete). It also incorporates a variation of jON’s suggestion.

 on adding folder items to this_folder after receiving added_items
  repeat
   set check1 to size of (info for this_folder)
   do shell script "sleep 5"
   set check2 to size of (info for this_folder)
   if check1 = check2 then exit repeat
  end repeat
  
  set byteSize to check1
  set size_ to convertByteSize from byteSize
  
  set n to (word 1 of size_) as number
  set m to word 2 of size_
  
  if n > 649 and m is "MB" or m is "GB" or m is "TB" then
   display dialog "Folder: " & return & return & POSIX path of this_folder & return & ¬
    return & "Folder size has now reached " & size_
  end if
 end adding folder items to

 to convertByteSize from byteSize -- by Nigel Garvey
  if byteSize is greater than or equal to 1.099511627776E+12 then -- Terabytes (2 ^ 40) 
   ((byteSize / 1.099511627776E+12 div 0.01 / 100.0) as string) & " TB"
  else if byteSize is greater than or equal to 1.073741824E+9 then -- Gigabytes (2 ^ 30) 
   ((byteSize / 1.073741824E+9 div 0.01 / 100.0) as string) & " GB"
  else if byteSize is greater than or equal to 1048576 then -- Megabytes (2 ^ 20) 
   ((byteSize / 1048576 div 0.01 / 100.0) as string) & " MB"
  else if byteSize is greater than or equal to 1024 then -- Kilobytes (2 ^ 10) 
   ((byteSize div 1024) as string) & " K"
  else
   (byteSize as string) & " bytes"
  end if
 end convertByteSize

– Rob

Modified as per JON bEEBE directions (saw it before i saw Rob’s) and it works great. What is great is that it calculates the lot: files, folders and subfolders. Fab.
Now, what if one was to combine it with the script below, which is a lovely thing that takes ONE folder and devides the contents into as many 650Mb folders as needed. It has two problems.
a) it COPIES the original items into all the various folders. Would be much better for busy people if it MOVED them into the folders, ready for burning. This shoud be so simple, i tried by changing the script from duplicate to move (at the end) and then changing all mentions of copy_file to move_file. It starts running fine, but then after moving the items into the first or second 650Mb folder, it stops and says “I cannot calculate size of item number…” (which is always the first item of the would-be next folder). Any ideas? Excuse my ineptitude, I am VERY new to all this and feel quite embarassed by my ignorance. I thought that logically all can stay the same in the script and one could just tell it to “move” instead of “duplicate”.

b) It cannot calculate the contents of subfolders. This is why i was wondering if combining Rob’s script wth the one below might produce a script that allows you to take a folder (ex. Job A with subfolders 1, 2, 3, 4) dump it onto the action and let it sort it all out into 650Mb (or whatever) folders to be burned

This is the original (duplicates, does not move)

property default_path : path to desktop from user domain
property max_size : 650 (value of maximum folder size in Mb)
property max_bytes : max_size * 1024 * 1024
property folder_suffix : “Pt_” (suffix to distinguish sub-folders)

on open (these_folders)
repeat with aItem in these_folders
tell application “Finder”
if class of item aItem is folder then
if not (exists (some item in contents of aItem whose class is folder)) then
set output_folder to choose folder with prompt “Select folder to place sub-folders in:” default location default_path
set folder_list to {}
set folder_counter to 1
set total_size to 0
set current_name to name of aItem as string
repeat with aFile in contents of aItem
if (total_size + (size of aFile) ? max_bytes) then
my copy_files(output_folder, folder_counter, current_name, folder_list)
set total_size to size of aFile
set folder_list to {aFile as alias}
set folder_counter to folder_counter + 1
else
set total_size to total_size + (size of aFile)
set folder_list to folder_list & {aFile as alias}
end if
end repeat
if (total_size > 0) then
my copy_files(output_folder, folder_counter, current_name, folder_list)
end if
else
display dialog ("WARNING: Item name: " & name of aItem as string) & return & “Cannot process this item. Contains subfolders” with icon stop
end if
else
display dialog ("WARNING: Item name: " & name of aItem as string) & return & “Cannot process this item. It is not a folder” with icon stop
end if
end tell
end repeat
end open

on copy_files(out_folder, counter, folder_name, list_of_folders)
tell application “Finder”
set current_name to folder_name & folder_suffix & (counter as string)
set current_folder to make new folder at out_folder with properties {name:current_name}
duplicate list_of_folders to current_folder
end tell
end copy_files

One small final question to do with Rob’s code. Would it be possible to make the folder refuse any further item at the same time as


 return & "Folder size has now reached " & size_

I don’t know of a way to do this unless it can be done by changing the permissions of the folder. Maybe someone else will offer input on this.

– Rob