How to rename movie collection using text file contents?

Hello all, A friend of mine has a NAS with a movie collection on it. He has each movie separated by genre and movie title folders. Along with a movie.nfo containing all movie information. Example:

What he is wanting to do is rename Die.Hard.avi by the movie.nfo file. Among the movie information in the movie.nfo file, it has

I’m trying to figure out how to go about this.

(Movie extensions include avi, mkv, mp4, m4v, etc.)
(Movie files could span multiple discs i.e. Die.Hard.cd1, Die.Hard.cd2, etc.)

The first thing you need is to be able to get at each individual movie folder so you can do the rest of the tasks. Here’s a script for that. Just put in the path to the movies folder as text…

set moviesFolder to path to desktop folder as text

set movieFoldersPaths to {}
tell application "Finder"
	set genreFolders to every folder of folder moviesFolder
	repeat with aGenre in genreFolders
		set thisGenreMovies to every folder of aGenre
		repeat with aMovieFolder in thisGenreMovies
			-- do something with the movie folder such as...
			-- find the nfo file
			-- parse the nfo file for the originaltitle
			-- find the movie file
			-- rename the movie file from the parsed nfo file
			
			-- in this example I'll just compile a list of the movie folder paths
			set end of movieFoldersPaths to aMovieFolder as text
		end repeat
	end repeat
end tell
return movieFoldersPaths

This should get you started. Work on this and post what you can come up with. For now I’m just putting the individual movie folders into a list, but I gave directions as to the steps you’d need to take to address your task.

Well this is what I have been able to come up with.


set moviesFolder to (choose folder) as text

set movieFoldersPaths to {}

tell application "Finder"
	set genreFolders to every folder of folder moviesFolder
	
	repeat with aGenre in genreFolders
		set thisGenreMovies to every folder of aGenre
		
		repeat with aMovieFolder in thisGenreMovies
			-- do something with the movie folder such as...
			-- find the nfo file
			set movie_nfo to get (files of aMovieFolder whose name ends with ".nfo") as text
			set thisSubtitleMovies to every folder of aMovieFolder
			
			-- parse the nfo file for the originaltitle									
			set ASTID to text item delimiters of AppleScript
			try
				set theName to read (movie_nfo as alias)
				set text item delimiters of AppleScript to "<originaltitle>"
				set theTitle to text item 2 of theName
				set text item delimiters of AppleScript to "</originaltitle>"
				set theTitle to text item 1 of theTitle as text
				
				set text item delimiters of AppleScript to " "
				set theTitle to text items of theTitle
				set text item delimiters of AppleScript to "."
				set theTitle to "" & theTitle
				
				set theDate to read (movie_nfo as alias)
				set text item delimiters of AppleScript to "<year>"
				set theYear to text item 2 of theDate
				set text item delimiters of AppleScript to "</year>"
				set theYear to text item 1 of theYear as text
			end try
			set text item delimiters of AppleScript to ASTID
			
			-- find the movie file
			set AVISorted to sort {files of aMovieFolder whose name ends with ".avi"} by modification date
			set mp4Sorted to sort {files of aMovieFolder whose name ends with ".mp4"} by modification date
			set mkvSorted to sort {files of aMovieFolder whose name ends with ".mkv"} by modification date
			set m4vSorted to sort {files of aMovieFolder whose name ends with ".m4v"} by modification date
			
			set CAvi to count AVISorted
			set CMp4 to count mp4Sorted
			set CMkv to count mkvSorted
			set Cm4v to count m4vSorted
			
			set AVISortedR to reverse of AVISorted
			set MP4SortedR to reverse of mp4Sorted
			set MKVSortedR to reverse of mkvSorted
			set m4vSortedR to reverse of m4vSorted
			
			-- rename the movie file from the parsed nfo file					
			repeat with kavi from 1 to CAvi
				if (count of AVISorted) is greater than 1 then
					set name of item kavi of AVISortedR to theTitle & " (" & theYear & ")" & ".cd" & kavi & ".avi"
				else
					set name of item kavi of AVISortedR to theTitle & " (" & theYear & ")" & ".avi"
				end if
			end repeat --kavi from 1 to CAvi
			
			repeat with kmp4 from 1 to CMp4
				if (count of mp4Sorted) is greater than 1 then
					set name of item kmp4 of MP4SortedR to theTitle & " (" & theYear & ")" & ".cd" & kmp4 & ".mp4"
				else
					set name of item kmp4 of MP4SortedR to theTitle & " (" & theYear & ")" & ".mp4"
				end if
			end repeat --kmp4 from 1 to CMp4
			
			repeat with kmkv from 1 to CMkv
				if (count of mkvSorted) is greater than 1 then
					set name of item kmkv of MKVSortedR to theTitle & " (" & theYear & ")" & ".cd" & kmkv & ".mkv"
				else
					set name of item kmkv of MKVSortedR to theTitle & " (" & theYear & ")" & ".mkv"
				end if
			end repeat --kmkv from 1 to CMkv
			
			repeat with km4v from 1 to Cm4v
				if (count of m4vSorted) is greater than 1 then
					set name of item km4v of m4vSortedR to theTitle & " (" & theYear & ")" & ".cd" & km4v & ".m4v"
				else
					set name of item km4v of m4vSortedR to theTitle & " (" & theYear & ")" & ".m4v"
				end if
			end repeat --km4v from 1 to Cm4v
			
			--set name of movie folder to Title (Year)
			set name of aMovieFolder to theTitle & " (" & theYear & ")"
			
			
			--Goes into "Subs" Folder
			set thisMoviesSubtitle to every folder of thisGenreMovies
			repeat with aSubtitleFolder in thisSubtitleMovies
				set subSorted to sort {files of aSubtitleFolder whose name ends with ".sub"} by modification date
				set srtSorted to sort {files of aSubtitleFolder whose name ends with ".srt"} by modification date
				
				set Csub to count subSorted
				set Csrt to count srtSorted
				
				set subSortedR to reverse of subSorted
				set srtSortedR to reverse of srtSorted
				
				repeat with ksub from 1 to Csub
					if (count of subSorted) is greater than 1 then
						set name of item ksub of subSortedR to theTitle & " (" & theYear & ")" & ".cd" & ksub & ".sub"
					else
						set name of item ksub of subSortedR to theTitle & " (" & theYear & ")" & ".sub"
					end if
				end repeat --ksub from 1 to Csub
				
				repeat with ksrt from 1 to Csrt
					if (count of srtSorted) is greater than 1 then
						set name of item ksrt of srtSortedR to theTitle & " (" & theYear & ")" & ".cd" & ksrt & ".srt"
					else
						set name of item ksrt of srtSortedR to theTitle & " (" & theYear & ")" & ".srt"
					end if
				end repeat --ksrt from 1 to Csrt			
				
				
			end repeat --aSubtitleFolder in thisSubtitleMovies
		end repeat --aMovieFolder in thisGenreMovies
		
	end repeat --aGenre in genreFolders	
	
end tell --application "Finder"
return movieFoldersPaths

That’s pretty good Herb. I think you’re really close. I modified it so you don’t have to search for each file extension separately. You can do it all at once. Plus I modified your “text item delimiters” section a little so double-check that.

NOTE: This script is meant to be run on a single movie folder. I wrote it without the repeat loops so you can test it on just one folder to make sure it works properly before running it on every folder. I think it’s good to test it out first before running it on everything in case there’s a mistake. I did a preliminary test and it seemed to work, but you should test it more completely before letting it loose on all the movies.

When you have this script working properly add it to the other script. NOTE: one of the variables will have to be changed when you merge the two scripts. Just replace every instance of “folder moviesFolder” in this second script with “aMovieFolder”. So give this a try and see if it works on one movie folder…

set moviesFolder to (choose folder) as text

set movieExtensions to {"avi", "mp4", "mkv", "m4v"}
set subtitleExtensions to {"sub", "srt"}

tell application "Finder"
	try -- if nfo file is not found it errors, so we use a try block so that if it isn't found we skip the whole process
		-- find the nfo file
		set movie_nfo to (first file of folder moviesFolder whose name ends with ".nfo")
		set nfoText to read (movie_nfo as alias)
		
		-- parse nfo for title and year
		set {ASTID, AppleScript's text item delimiters} to {AppleScript's text item delimiters, "<originaltitle>"}
		set a to text item 2 of nfoText
		set AppleScript's text item delimiters to "</originaltitle>"
		set b to text item 1 of a
		set AppleScript's text item delimiters to "."
		set c to text items of b
		set AppleScript's text item delimiters to space
		set theTitle to c as text
		
		set AppleScript's text item delimiters to "<year>"
		set a to text item 2 of nfoText
		set AppleScript's text item delimiters to "</year>"
		set theYear to text item 1 of a
		set AppleScript's text item delimiters to ASTID
		
		-- find the movies and rename them
		set foundMovies to sort (every file of folder moviesFolder whose name extension is in movieExtensions) by modification date
		set movieCount to count of foundMovies
		if movieCount is greater than 1 then
			repeat with i from 1 to movieCount
				set thisMovie to item i of foundMovies
				set ext to name extension of thisMovie
				set name of thisMovie to theTitle & " (" & theYear & ")" & ".cd" & (i as text) & "." & ext
			end repeat
		else
			set thisMovie to item 1 of foundMovies
			set ext to name extension of thisMovie
			set name of thisMovie to theTitle & " (" & theYear & ")." & ext
		end if
		
		-- find the subtitles and rename them
		set subtitleFolders to every folder of folder moviesFolder
		repeat with aSubtitleFolder in subtitleFolders
			try -- if this folder doesn't have subtitles it errors, so the try block will make it skip that folder but the repeat loop continues with the next folder
				set subtitleFiles to sort (every file of aSubtitleFolder whose name extension is in subtitleExtensions) by modification date
				set subtitleFilesCount to count of subtitleFiles
				if subtitleFilesCount is greater than 1 then
					repeat with i from 1 to subtitleFilesCount
						set thisSubtitle to item i of subtitleFiles
						set ext to name extension of thisSubtitle
						set name of thisSubtitle to theTitle & " (" & theYear & ")" & ".cd" & (i as text) & "." & ext
					end repeat
				else
					set thisSubtitle to item 1 of subtitleFiles
					set ext to name extension of thisSubtitle
					set name of thisSubtitle to theTitle & " (" & theYear & ")." & ext
				end if
			end try
		end repeat
	end try
end tell

I believe I have merged the two scripts correctly. With the script you adjusted the Movie.cd1 & Movie.cd2 are not named in the correct order. (That’s why I had the “reverse” section. It was the only way I figured out how to rename multiple files correctly since the “Die.Hard.cd1” was timestamped before “Die.Hard.cd2”.) Thanks so much for your help so far.

set MasterMovieFolder to (choose folder) as text

set movieFoldersPaths to {}

set movieExtensions to {"avi", "mp4", "mkv", "m4v"}
set subtitleExtensions to {"sub", "srt"}

tell application "Finder"
	set genreFolders to every folder of folder MasterMovieFolder
	
	repeat with aGenre in genreFolders
		set SpecificGenre to every folder of aGenre
		
		repeat with aMovieFolder in SpecificGenre
			try -- if nfo file is not found it errors, so we use a try block so that if it isn't found we skip the whole process
				-- find the nfo file
				set movie_nfo to (first file of aMovieFolder whose name ends with ".nfo")
				set nfoText to read (movie_nfo as alias)
				
				-- parse the nfo file for the originaltitle	(replaces spaces with dots so result is "Movie.Title")						
				set {ASTID, AppleScript's text item delimiters} to {AppleScript's text item delimiters, "<originaltitle>"}
				set a to text item 2 of nfoText
				set AppleScript's text item delimiters to "</originaltitle>"
				set b to text item 1 of a
				set AppleScript's text item delimiters to space
				set c to text items of b
				set AppleScript's text item delimiters to "."
				set theTitle to c as text
				
				set AppleScript's text item delimiters to "<year>"
				set a to text item 2 of nfoText
				set AppleScript's text item delimiters to "</year>"
				set theYear to text item 1 of a
				set AppleScript's text item delimiters to ASTID
				
				-- find the movies and rename them
				set foundMovies to sort (every file of aMovieFolder whose name extension is in movieExtensions) by modification date
				set movieCount to count of foundMovies
				if movieCount is greater than 1 then
					repeat with i from 1 to movieCount
						set thisMovie to item i of foundMovies
						set ext to name extension of thisMovie
						set name of thisMovie to theTitle & " (" & theYear & ")" & ".cd" & (i as text) & "." & ext
					end repeat --i from 1 to movieCount
				else
					set thisMovie to item 1 of foundMovies
					set ext to name extension of thisMovie
					set name of thisMovie to theTitle & " (" & theYear & ")." & ext
				end if --movieCount is greater than 1 then
				
				-- find the subtitles and rename them
				set subtitleFolders to every folder of aMovieFolder
				repeat with aSubtitleFolder in subtitleFolders
					try -- if this folder doesn't have subtitles it errors, so the try block will make it skip that folder but the repeat loop continues with the next folder
						set subtitleFiles to sort (every file of aSubtitleFolder whose name extension is in subtitleExtensions) by modification date
						set subtitleFilesCount to count of subtitleFiles
						if subtitleFilesCount is greater than 1 then
							repeat with i from 1 to subtitleFilesCount
								set thisSubtitle to item i of subtitleFiles
								set ext to name extension of thisSubtitle
								set name of thisSubtitle to theTitle & " (" & theYear & ")" & ".cd" & (i as text) & "." & ext
							end repeat
						else
							set thisSubtitle to item 1 of subtitleFiles
							set ext to name extension of thisSubtitle
							set name of thisSubtitle to theTitle & " (" & theYear & ")." & ext
						end if --subtitleFilesCount is greater than 1 then				
					end try
				end repeat --aSubtitleFolder in subtitleFolders
				
				--set name of movie folder to Title (Year)
				set name of aMovieFolder to theTitle & " (" & theYear & ")"
				
			end try
		end repeat --aMovieFolder in SpecificGenre
		
	end repeat --aGenre in genreFolders	
	
end tell --application "Finder"
return movieFoldersPaths

Good Herb, I’m glad it’s working. I was wondering why you were sorting “by modification date”. I was thinking that you should be sorting “by name” instead. That might solve the “reverse order” situation that you mentioned. Anyway, good luck. NOTE: you can remove the following 2 lines from the script as they don’t do anything any longer…

set movieFoldersPaths to {}
return movieFoldersPaths

Awesome, sorting by name works. Thank you so much!

After running the script pretty successfully, I would like to change a few things

I would like to add in a skip if folders already have a year in the title:

Would this work for the above?

repeat with aMovieFolder in SpecificGenre
			if name of aMovieFolder does not contain "(" then

When reading from the movie.nfo, I would like to replace “accented latin characters” with plain english:

Is there a way to replace said characters in the movie.nfo at the same time?

This is what I have come up with so far, and it seems to be working pretty well. The next thing I would like to add in is:
Find all the folder names & paths which do not have a “” in the movie.nfo file and save said list to a text file

set MasterMovieFolder to (choose folder) as text
set movieExtensions to {"avi", "mp4", "mkv", "m4v"}
set subtitleExtensions to {"sub", "srt"}
set ActOnMovieName to {}

global _limitText
set vaild_text to "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890_-!#$%*()+& "
set _limitText to vaild_text

tell application "Finder"
	set genreFolders to every folder of folder MasterMovieFolder
	repeat with aGenre in genreFolders
		set MovieFolders to every folder of aGenre
		repeat with aMovieFolder in MovieFolders
			
			try -- if nfo file is not found skip the whole process
				-- find the nfo file
				set movie_nfo to (first file of aMovieFolder whose name ends with ".nfo")
				
				set XMLfile to movie_nfo as string
				tell application "System Events"
					tell XML element 1 of contents of XML file XMLfile
						set theTitle_A to (value of XML element "title")
						set theYear to (value of XML element "year")
					end tell
				end tell
				
				set stringToConvert to theTitle_A
				considering case but ignoring diacriticals
					set theTitle_B to my removeDiacriticalMarks(stringToConvert, _limitText)
				end considering
				
				set ASTID to AppleScript's text item delimiters
				set AppleScript's text item delimiters to space
				set title_A to text items of theTitle_B
				set AppleScript's text item delimiters to "."
				set title_B to title_A as text
				set theTitle to title_B
				set AppleScript's text item delimiters to ASTID
				
				
				--does movie folder have "DVDSCR" or "R5" in the title				
				if name of aMovieFolder contains "DVDSCR" then
					if name of aMovieFolder is not equal to theTitle & ".DVDSCR" & " (" & theYear & ")" then
						set ActOnMovieName to 1
					end if
				else if name of aMovieFolder contains "R5" then
					if name of aMovieFolder is not equal to theTitle & ".R5" & " (" & theYear & ")" then
						set ActOnMovieName to 1
					end if
				else if name of aMovieFolder is not equal to theTitle & " (" & theYear & ")" then
					set ActOnMovieName to 1
				end if
				
				--continue script if renaming needs to happen
				if ActOnMovieName is equal to 1 then
					-- find the movies and rename them
					set foundMovies to sort (every file of aMovieFolder whose name extension is in movieExtensions) by name
					set movieCount to count of foundMovies
					if movieCount is greater than 1 then
						repeat with moviecountA from 1 to movieCount
							set thisMovie to item moviecountA of foundMovies
							set ext to name extension of thisMovie
							if name of aMovieFolder contains "DVDSCR" then
								set name of thisMovie to theTitle & ".DVDSCR" & " (" & theYear & ")" & ".cd" & (moviecountA as text) & "." & ext
							else if name of aMovieFolder contains "R5" then
								set name of thisMovie to theTitle & ".R5" & " (" & theYear & ")" & ".cd" & (moviecountA as text) & "." & ext
							else
								set name of thisMovie to theTitle & " (" & theYear & ")" & ".cd" & (moviecountA as text) & "." & ext
							end if --name of aMovieFolder contains "DVDSCR"
						end repeat --i from 1 to movieCount
					else
						set thisMovie to item 1 of foundMovies
						set ext to name extension of thisMovie
						--					set name of thisMovie to theTitle & " (" & theYear & ")" & "." & ext
						if name of aMovieFolder contains "DVDSCR" then
							set name of thisMovie to theTitle & ".DVDSCR" & " (" & theYear & ")" & "." & ext
						else if name of aMovieFolder contains "R5" then
							set name of thisMovie to theTitle & ".R5" & " (" & theYear & ")" & "." & ext
						else
							set name of thisMovie to theTitle & " (" & theYear & ")" & "." & ext
						end if --name of aMovieFolder contains "DVDSCR"
					end if --movieCount is greater than 1 then
					
					
					-- find the subtitles and rename them
					set subtitleFolders to every folder of aMovieFolder
					repeat with aSubtitleFolder in subtitleFolders
						try -- if subs folder is not found skip the whole process
							set subtitleFiles to sort (every file of aSubtitleFolder whose name extension is in subtitleExtensions) by name
							set subtitleFilesCount to count of subtitleFiles
							if subtitleFilesCount is greater than 1 then
								repeat with subtitlecountA from 1 to subtitleFilesCount
									set thisSubtitle to item subtitlecountA of subtitleFiles
									set ext to name extension of thisSubtitle
									if name of aMovieFolder contains "DVDSCR" then
										set name of thisSubtitle to theTitle & ".DVDSCR" & " (" & theYear & ")" & ".cd" & (subtitlecountA as text) & "." & ext
									else if name of aMovieFolder contains "R5" then
										set name of thisSubtitle to theTitle & ".R5" & " (" & theYear & ")" & ".cd" & (subtitlecountA as text) & "." & ext
									else
										set name of thisSubtitle to theTitle & " (" & theYear & ")" & ".cd" & (subtitlecountA as text) & "." & ext
									end if --name of aMovieFolder contains "DVDSCR"
								end repeat
							else
								set thisSubtitle to item 1 of subtitleFiles
								set ext to name extension of thisSubtitle
								if name of aMovieFolder contains "DVDSCR" then
									set name of thisSubtitle to theTitle & ".DVDSCR" & " (" & theYear & ")" & "." & ext
								else if name of aMovieFolder contains "R5" then
									set name of thisSubtitle to theTitle & ".R5" & " (" & theYear & ")" & "." & ext
								else
									set name of thisSubtitle to theTitle & " (" & theYear & ")" & "." & ext
								end if --name of aMovieFolder contains "DVDSCR"
								
							end if --subtitleFilesCount is greater than 1 then				
						end try
					end repeat --aSubtitleFolder in subtitleFolders
					
					--set name of movie folder to Title (Year)
					if name of aMovieFolder contains "DVDSCR" then
						set name of aMovieFolder to theTitle & ".DVDSCR" & " (" & theYear & ")"
					else if name of aMovieFolder contains "R5" then
						set name of aMovieFolder to theTitle & ".R5" & " (" & theYear & ")"
					else
						set name of aMovieFolder to theTitle & " (" & theYear & ")"
					end if
					
				end if --ActOnMovieName is equal to 1
				
				
			end try
		end repeat --aMovieFolder in MovieFolders
	end repeat --aGenre in genreFolders	
end tell --application "Finder"


on removeDiacriticalMarks(stringToConvert, limit) -- UPPER and lower case
	set newString to ""
	repeat with i from 1 to count of characters in stringToConvert
		set _index to offset of (character i in stringToConvert) in _limitText
		if _index is not equal to 0 then -- 0=not found
			set newString to newString & character (_index) in _limitText
		else
			--			set newString to newString & character i in stringToConvert
		end if
	end repeat
	return newString
end removeDiacriticalMarks