Create years worth of folders

I am trying to modify a script that created daily publication folders based on a selected month. I would now like to create a years worth of monthly folders and daily subfolders based on a selected year.

And here is what I have created thus far for my new script.

property theMonths : {"JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"}
property theWeekdays : {"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"}

set destinationFolder to choose folder with prompt "Choose destination folder"
(* Choose destination folder for script to create folders inside of *)
tell (current date) to set thisMonth to (it - (its day) * days + days - (its time))
(* Set variable thismonth to first day of month *)
tell (current date) to set thisyear to its year
(* set variable this year to current year *)

set yearlist to {} (* Create empty year list *)
repeat with i from 1 to 11
	set end of yearlist to (thisyear + i - 6) as string
end repeat
(* Fill year list with the previous 5 years followed by the next 5 *)

set chosenyear to (choose from list yearlist with prompt "choose a year") as string
if chosenyear is "false" then return
(* set vaiable choosenyear to year picked from menu*)

set FMonth to January as integer
(* set variable thismonth to January as integer*)
set curFmonth to January of chosenyear
(* set variable thismonth to January of selected year*)

display dialog curFmonth as string buttons {"OK"} default button 1

repeat with eachmonth from 0 to 11
	if FMonth ≤ 12 then
		set m to item (FMonth) of theMonths
		set folderName1 to text -2 thru -1 of ("0" & FMonth) & space & m
		try
			tell application "Finder"
				set folderName1 to make new folder at destinationFolder with properties {name:folderName1}
				(* Create folder for each month in year *)
				
				tell curFmonth to tell it + 32 * days to set lastDate to day of (it - (its day) * days + 86399)
				
				repeat with oneDay from 0 to lastDate - 1
					tell (curFmonth + oneDay * days) to set {wk, dy} to {its weekday as integer, its day}
					if wk > 2 then
						set folderName2 to text -2 thru -1 of ("0" & dy) & space & item wk of theWeekdays
						try
							tell application "Finder"
								set folderName2 to make new folder at folderName1 as string as alias with properties {name:folderName2}
							end tell
							(* Create subfolder for each pub day in that month *)
							
							
						end try
					end if
					
				end repeat
			end tell
		end try
		set FMonth to FMonth + 1
		set curFmonth to curFmonth + 1
		(* Up the month by 1*)
		
	end if
end repeat

I have I am unclear how to take the selected year and covert it back to a date so that the script will create the correct daily folders for that year. I know that what I have here is wrong but I am at an impasse till I can learn more about AS.

Model: MBP
AppleScript: 2.3
Browser: Safari 533.18.5
Operating System: Mac OS X (10.6)

Hi,

for speed reasons this script uses the shell mkdir command, which is able to create multiple folders at the same time (thanks to Nigel Garvey for his tiny daysInMonth handler).


property theMonths : {"JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"}
property theWeekdays : {"SAT", "SUN", "MON", "TUE", "WED", "THU", "FRI"}

set destinationFolder to choose folder with prompt "Choose destination folder"
(* Choose destination folder for script to create folders inside of *)
tell (current date) to set referenceDate to (it - (its day) * days + days - (its time))
(* Set variable thismonth to first day of month *)
set thisyear to year of referenceDate
(* set variable this year to current year *)

set yearlist to {} (* Create empty year list *)
repeat with i from 1 to 11
	set end of yearlist to (thisyear + i - 6) as string
end repeat
(* Fill year list with the previous 5 years followed by the next 5 *)

set chosenyear to (choose from list yearlist with prompt "choose a year") as string
if chosenyear is "false" then return
(* set variable choosenyear to year picked from menu*)
set year of referenceDate to chosenyear
repeat with aMonth from 1 to 12
	set month of referenceDate to aMonth
	set monthFolderName to text -2 thru -1 of ("0" & aMonth) & space & item aMonth of theMonths
	do shell script "/bin/mkdir -p " & quoted form of (POSIX path of destinationFolder & chosenyear & "/" & monthFolderName)
	(* set the weekday of the first day in month *)
	set currentWeekDay to weekday of referenceDate as integer
	set dayList to {}
	repeat with aDay from 1 to (daysInMonth for referenceDate)
		set end of dayList to quoted form of (text -2 thru -1 of ("0" & aDay) & space & item ((currentWeekDay mod 7) + 1) of theWeekdays)
		set currentWeekDay to currentWeekDay + 1
	end repeat
	set {TID, text item delimiters} to {text item delimiters, ","}
	set dayList to dayList as text
	set text item delimiters to TID
	do shell script "/bin/mkdir -p " & quoted form of (POSIX path of destinationFolder & chosenyear & "/" & monthFolderName) & "/{" & dayList & "}"
end repeat

on daysInMonth for theDate -- returns an integer
	copy theDate to d
	set d's day to 32
	32 - (d's day)
end daysInMonth


I couldn’t resist trying to speed it up even more. :slight_smile:

In fact, there’s no measurable difference in speed between Stefan’s version and my own ” but it’s enough to know that mine’s theoretically faster. :wink:


property theMonths : {" JAN", " FEB", " MAR", " APR", " MAY", " JUN", " JUL", " AUG", " SEP", " OCT", " NOV", " DEC"}
property monthLengths : {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
property theWeekdays : {" SAT", " SUN", " MON", " TUE", " WED", " THU", " FRI"}

(* Choose destination folder for script to create folders inside of *)
set destinationFolder to choose folder with prompt "Choose destination folder"

(* Set a reference date to the 1st January this year. *)
tell (current date) to set {its day, its month, referenceDate, thisYear} to {1, January, it, its year}

(* Make a list of the years from 5 before this year to 5 after. *)
set yearList to {}
repeat with i from thisYear - 5 to thisYear + 5
	set end of yearList to i
end repeat

(* set variable choosenYear to year picked from menu and get the weekday of 1st January in that year. *)
set chosenYear to (choose from list yearList with prompt "choose a year")
if (chosenYear is false) then return
set year of referenceDate to chosenYear
set currentWeekDay to referenceDate's weekday as integer

(* Create a hierarchy path structure for 'mkdir'. *)
set astid to AppleScript's text item delimiters
set AppleScript's text item delimiters to ","
set monthList to {}
repeat with aMonth from 1 to 12
	set dayList to {}
	repeat with aDay from 1 to (item aMonth of monthLengths) + (((aMonth is 2) and (chosenYear mod 4 is 0) and ((chosenYear mod 100 > 0) or (chosenYear mod 400 is 0))) as integer)
		set end of dayList to quoted form of (text -2 thru -1 of (100 + aDay as string) & item ((currentWeekDay mod 7) + 1) of theWeekdays)
		set currentWeekDay to currentWeekDay + 1
	end repeat
	set end of monthList to quoted form of (text -2 thru -1 of (100 + aMonth as string) & item aMonth of theMonths) & "/{" & dayList & "}"
end repeat
set hierarchy to quoted form of (POSIX path of destinationFolder) & chosenYear & "/{" & monthList & "}"
set AppleScript's text item delimiters to astid

(* Create the entire hierarchy of folders. *)
do shell script "/bin/mkdir -p " & hierarchy

I ended up using Stefan’s script until people started filing things under days we don’t publish. I tried to modify it and really screwed it up. How would I manage that?

Since this script really helped me out (thank you) I’d like at add a modification. This creates folders for each month then each week in the month, followed by the each day in the month, and it creates a dummy file in each, which helps if you are trying to upload the folders to a platform like SharePoint:

property monthAbbrevs : {"JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"}
property monthLengths : {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
property weekdayAbbrevs : {"MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN"}
property monthEnums : {January, February, March, April, May, June, July, August, September, October, November, December}

(* Choose destination folder for script to create folders inside of *)
set destinationFolder to choose folder with prompt "Choose destination folder"

(* Set a reference date to the 1st January this year. *)
tell (current date) to set {its day, its month, referenceDate, thisYear} to {1, January, it, its year}

(* Make a list of the years from 5 before this year to 5 after. *)
set yearList to {}
repeat with i from thisYear - 5 to thisYear + 5
	set end of yearList to i
end repeat

(* set variable chosenYear to year picked from menu and coerce it to integer *)
set chosenYear to (choose from list yearList with prompt "Choose a year")
if (chosenYear is false) then return
if class of chosenYear is list then set chosenYear to item 1 of chosenYear
set chosenYear to chosenYear as integer
set year of referenceDate to chosenYear

(* Build nested hierarchy: for each month, build week folders (Week 01 ...) that begin on Monday.
   Inside each week folder create weekday folders for the days that fall in that week (e.g. "01 MON"). *)

-- Preserve and set text item delimiters for list->text coercions
set astid to AppleScript's text item delimiters
set AppleScript's text item delimiters to ","

set monthList to {}
repeat with aMonth from 1 to 12
	-- compute number of days in month (account for leap year)
	set daysInMonth to item aMonth of monthLengths
	if (aMonth is 2) and (chosenYear mod 4 is 0) and ((chosenYear mod 100 > 0) or (chosenYear mod 400 is 0)) then
		set daysInMonth to daysInMonth + 1
	end if
	
	set weekList to {} -- will hold week entries for this month
	set weekNum to 1
	set tmpWeekDays to {} -- will accumulate day folders for current week
	
	repeat with aDay from 1 to daysInMonth
		-- build a date for this specific day so we can get the exact weekday
		set theDate to referenceDate
		set year of theDate to chosenYear
		set month of theDate to item aMonth of monthEnums
		set day of theDate to aDay
		
		set wdName to (weekday of theDate) as string
		-- map weekday string to our 3-letter abbrev
		if wdName is "Monday" then
			set wdAbbrev to "MON"
		else if wdName is "Tuesday" then
			set wdAbbrev to "TUE"
		else if wdName is "Wednesday" then
			set wdAbbrev to "WED"
		else if wdName is "Thursday" then
			set wdAbbrev to "THU"
		else if wdName is "Friday" then
			set wdAbbrev to "FRI"
		else if wdName is "Saturday" then
			set wdAbbrev to "SAT"
		else
			set wdAbbrev to "SUN"
		end if
		
		-- weekday folder label with two-digit day + space + weekday abbrev, quoted for shell
		set dayLabel to quoted form of (text -2 thru -1 of (100 + aDay as string) & " " & wdAbbrev)
		
		if aDay is 1 then
			-- start the first week of the month
			set tmpWeekDays to {dayLabel}
		else if wdAbbrev is "MON" then
			-- new week starts on Monday: finish previous week and start a new one
			set end of weekList to (quoted form of ("Week " & text -2 thru -1 of (100 + weekNum as string))) & "/{" & tmpWeekDays & "}"
			set weekNum to weekNum + 1
			set tmpWeekDays to {dayLabel}
		else
			-- continue accumulating days for current week
			set end of tmpWeekDays to dayLabel
		end if
	end repeat
	
	-- finish the last week for this month
	if tmpWeekDays is not {} then
		set end of weekList to (quoted form of ("Week " & text -2 thru -1 of (100 + weekNum as string))) & "/{" & tmpWeekDays & "}"
	end if
	
	-- join the week's entries and add the month entry
	set monthFolderName to quoted form of (text -2 thru -1 of (100 + aMonth as string) & " " & item aMonth of monthAbbrevs)
	set end of monthList to monthFolderName & "/{" & weekList & "}"
end repeat

set hierarchy to quoted form of (POSIX path of destinationFolder) & chosenYear & "/{" & monthList & "}"
set AppleScript's text item delimiters to astid

(* Create the entire hierarchy of folders. *)
do shell script "/bin/mkdir -p " & hierarchy

(* Create a blank file named "dummy" inside every folder created under the chosen year *)
set rootPOSIX to POSIX path of destinationFolder & chosenYear & "/"
set quotedRoot to quoted form of rootPOSIX
do shell script "find " & quotedRoot & " -type d -exec touch '{}/dummy' \\;"