Selected Items Size AppleScript

Hello, I made this script because sometimes I need to copy some folders and files to a removable media drive, USB, FireWire, etc, and I want to know exactly how much is the free space required at the target/destination drive before to start the copy task, with this script I only have to select all the desired items to copy and run it, it will show you the total size of all the selected items in human readable units the same as finder does, it supposes to be able to handle sizes from bytes up to PB but I only have been able to test it with few TB :smiley: so if someone else can verify that and let me know it would be great, you can localize the text on dialogs/buttons and make it match with your system language.


#Selected Items Size AppleScript
#2018 (ɔ) jraulc at gmail dot com

set localeString to user locale of (get system info)

#you can localize to your language here
if localeString starts with "es" then
	set okButton to "Aceptar"
	set noSelectionString to "Por favor seleccione al menos dos items para calcular su tamaño."
	set totalSizeString to "Tamaño total seleccionado: "
	set selectedItemsString to " items seleccionados en: " & return
	set reallyString to "Es en serio?" & return
	set tooBigString to "Es en serio?" & return & return & "Solo puedo decir esto 'El tamaño total de los items seleccionados es mayor a 1 ExaByte.'"
else #default if not match with the localized language
	set okButton to "OK"
	set noSelectionString to "Please select at least two items to calculate it size."
	set totalSizeString to "Total selected size is: "
	set selectedItemsString to " items selected at: " & return
	set reallyString to "Really?" & return
	set tooBigString to "Really?" & return & return & "I only can say this 'The total size of selected items is bigger than 1 ExaByte.'"
end if

set allItemsSize to ""
set itemsCount to 0

tell application "Finder"
	with timeout of 3600 seconds
		set selectedItems to selection as list
		if selectedItems is {} then
			display dialog noSelectionString buttons {okButton} default button okButton with icon stop
			error number -128
		else
			set itemsPath to POSIX path of (folder of the front window as alias)
			set itemsCount to 0
			repeat with iCount in selectedItems
				set itemsCount to itemsCount + 1
				set lastItemSize to size of (info for (iCount as alias))
				set allItemsSize to allItemsSize + lastItemSize
			end repeat
		end if
	end timeout
end tell

set {sizeInUnits, stringUnits} to converSize(allItemsSize)

if itemsCount > 1 then
	set summaryAlert to (itemsCount as string) & selectedItemsString & itemsPath & return & totalSizeString & return & sizeInUnits & " " & stringUnits
else
	set summaryAlert to reallyString & (itemsCount as string) & selectedItemsString & itemsPath & return & totalSizeString & return & sizeInUnits & " " & stringUnits
end if

tell application "Finder" to display alert summaryAlert

on converSize(allBytesSize)
	#convert bytes size to human readable memory size and return it with the correct unit.
	
	if allBytesSize > 1.15292150460685E+18 then
		display dialog tooBigString buttons {okButton} default button okButton with icon caution
		error number -128
	end if
	
	if allBytesSize < 1.15292150460685E+18 and allBytesSize > 1.12589990684262E+15 then
		set totalSize to (round (100 * (allBytesSize / 1.0E+15))) / 100
		set Units to "PB"
	end if
	
	if allBytesSize < 1.12589990684262E+15 and allBytesSize > 1.099511627776E+12 then
		set totalSize to (round (100 * (allBytesSize / 1.0E+12))) / 100
		set Units to "TB"
	end if
	
	if allBytesSize < 1.099511627776E+12 and allBytesSize > 1.073741824E+9 then
		set totalSize to (round (100 * (allBytesSize / 1.0E+9))) / 100
		set Units to "GB"
	end if
	
	if allBytesSize < 1.073741824E+9 and allBytesSize > 1048576 then
		set totalSize to (round (100 * (allBytesSize / 1000000))) / 100
		set Units to "MB"
	end if
	
	if allBytesSize < 1048576 and allBytesSize > 1024 then
		set totalSize to (round (100 * (allBytesSize / 1000))) / 100
		set Units to "KB"
	end if
	
	if allBytesSize < 1024 then
		set totalSize to allBytesSize
		set Units to "bytes"
	end if
	
	return {totalSize, Units}
	
end converSize

The function converSize() take the bytes as input and returns an array {size, units} with the size as human-readable memory and the corresponding units.
The link of the script exported to an app (10.11.6) with an icon and ready to add to the finder toolbar:
https://drive.google.com/open?id=1Y65j4Qxf0AZjBJ3-KsRCKIK8Rd-vujTB
Greetings from the Cayman Islands.

I tweaked the code a bit here. Removed all unnecessary while fully preserving all the functionality:


property theUnitsList : {"bytes", "KB", "MB", "GB", "TB", "PB"}

set localeString to user locale of (get system info)

-- User can localize to his language here
if localeString starts with "es" then
	set okButton to "Aceptar"
	set noSelectionString to "Por favor seleccione al menos dos items para calcular su tamaño."
	set totalSizeString to "Tamaño total seleccionado: "
	set selectedItemsString to " items seleccionados en: " & return
	set reallyString to "Es en serio?" & return
	set tooBigString to "Es en serio?" & return & return & "Solo puedo decir esto 'El tamaño total de los items seleccionados es mayor a 1 ExaByte.'"
else  -- default if not match with the localized language
	set okButton to "OK"
	set noSelectionString to "Please select at least two items to calculate it size."
	set totalSizeString to "Total selected size is: "
	set selectedItemsString to " items selected at: " & return
	set reallyString to "Really?" & return
	set tooBigString to "Really?" & return & return & "I only can say this 'The total size of selected items is bigger than 1 ExaByte.'"
end if

-- Get total size of selected in Finder window items (in bytes)
tell application "Finder"
	with timeout of 3600 seconds
		set selectedItems to selection as alias list
		if selectedItems is {} then
			display dialog noSelectionString buttons {okButton} default button okButton with icon stop
			error number -128
		else
			set itemsPath to POSIX path of (folder of the front window as alias)
			set {allItemsSize, itemsCount} to {0, count selectedItems}
			repeat with anItem in selectedItems
				set allItemsSize to allItemsSize + (size of anItem)
			end repeat
		end if
	end timeout
end tell

-- Convert total size to human readable units
set {aCounter, sizeInUnits} to {1, allItemsSize}
repeat until sizeInUnits < 1024
	set aCounter to aCounter + 1
	set sizeInUnits to sizeInUnits / 1024
end repeat
set sizeInUnits to (100 * sizeInUnits as integer) / 100
set stringUnits to item aCounter of theUnitsList

-- Show result
set summaryAlert to (itemsCount as string) & selectedItemsString & itemsPath & return & totalSizeString & return & sizeInUnits & " " & stringUnits
if itemsCount > 1 then set summaryAlert to reallyString & summaryAlert
tell application "Finder" to display alert summaryAlert

A convenient alternative is Foundation’s NSByteCountFormatter

use AppleScript version "2.5"
use framework "Foundation"
use scripting additions

set fileSize to 1.15292150460685E+16
set fileSizeString to current application's NSByteCountFormatter's stringFromByteCount:fileSize countStyle:0

--> 11.53 PB

Thanks for this improvement. Very nice. So, the all code becomes like this:


use AppleScript version "2.5"
use framework "Foundation"
use scripting additions

set localeString to user locale of (get system info)

-- User can localize to his language here
if localeString starts with "es" then
	set okButton to "Aceptar"
	set noSelectionString to "Por favor seleccione al menos dos items para calcular su tamaño."
	set totalSizeString to "Tamaño total seleccionado: "
	set selectedItemsString to " items seleccionados en: " & return
	set reallyString to "Es en serio?" & return
	set tooBigString to "Es en serio?" & return & return & "Solo puedo decir esto 'El tamaño total de los items seleccionados es mayor a 1 ExaByte.'"
else -- default if not match with the localized language
	set okButton to "OK"
	set noSelectionString to "Please select at least two items to calculate it size."
	set totalSizeString to "Total selected size is: "
	set selectedItemsString to " items selected at: " & return
	set reallyString to "Really?" & return
	set tooBigString to "Really?" & return & return & "I only can say this 'The total size of selected items is bigger than 1 ExaByte.'"
end if

-- Get total size of selected in Finder window items (in bytes)
tell application "Finder"
	with timeout of 3600 seconds
		set selectedItems to selection as alias list
		if selectedItems is {} then
			display dialog noSelectionString buttons {okButton} default button okButton with icon stop
			error number -128
		else
			set itemsPath to POSIX path of (folder of the front window as alias)
			set {allItemsSize, itemsCount} to {0, count selectedItems}
			repeat with anItem in selectedItems
				set allItemsSize to allItemsSize + (size of anItem))
			end repeat
		end if
	end timeout
end tell

-- Convert total size to human readable units (1024 base)
set fileSizeString to current application's NSByteCountFormatter's stringFromByteCount:allItemsSize countStyle:0

-- Show result
set summaryAlert to (itemsCount as string) & selectedItemsString & itemsPath & return & totalSizeString & return & fileSizeString
if itemsCount < 2 then set summaryAlert to reallyString & summaryAlert -- EDITED, see post bellow
tell application "Finder" to display alert summaryAlert

Hey folks, thank you for the improvements, the only thing is now the code shows the message “Really?” when there is more than one items selected and it should be the opposite, so I just changed the if condition to this:

if itemsCount < 2 then set summaryAlert to reallyString & summaryAlert

and it works like I intended since begin, just “trying to be joking” like saying “Do you really need a script to calculate the total size for one single item?”

Have great weekend…