Make almost identical if else statement into something smart

Hi all!

I guess you’ve all had it at some point. A lot of almost identical “if else” codes after each other.
Is it possible to make this into a short, smart other code? I don’t have a clue how to do it, but i guess you should use repeat with x in y.

Any way. The script i have moves, based on the file extension, to one or another folder. at this moment i have all these variables called Ext (VideoExt, MusicExt) which all are a list of file types that are respectively A video and a music file.
Example:

if ext is in VideoExt then
				wTf_("Detected file type: Video")
				do shell script "mv " & quoted form of i & space & quoted form of VideoPath
				wTf_(fileName & " moved to Video")
				userLog_("Detected a " & ext & " file, move to " & VideoPath & " succesful")
			else if (MusicExt contains ext) = true then
				wTf_("Detected file type: Music")
				do shell script "mv " & quoted form of i & space & quoted form of MusicPath
				wTf_(fileName & " moved to Music")
				userLog_("Detected a " & ext & " file, move to " & MusicPath & " succesful")
			else if (DocumentExt contains ext) = true then
				wTf_("Detected file type: Document")
				do shell script "mv " & quoted form of i & space & quoted form of DocumentPath
				wTf_(fileName & " moved to Documents")
				userLog_("Detected a " & ext & " file, move to " & DocumentPath & " succesful")
			else if ext is in TorrentExt then
				wTf_("Detected file type: Torrent")
				do shell script "mv " & quoted form of i & space & quoted form of TorrentPath
				wTf_(fileName & " moved to Torrents")
				userLog_("Detected a " & ext & " file, move to " & TorrentPath & " succesful")
			else if (PictureExt contains ext) = true then
				wTf_("Detected file type: Picture")
				do shell script "mv " & quoted form of i & space & quoted form of PicturePath
				wTf_(fileName & " moved to Pictures")
				userLog_("Detected a " & ext & " file, move to " & PicturePath & " succesful")
			else
				wTf_("Detected file type: Other")
				tell application "System Events" to set filesize to (size of ii)
				if filesize is greater than "524288000" then
					wTf_("File is larger than 500mb (" & filesize & " bytes)")
					do shell script "mv " & quoted form of i & space & quoted form of LargeDataPath
					wTf_(fileName & " moved to Large Files")
					userLog_("Detected a large file (" & filesize & " bytes), move to " & LargeDataPath & " succesful")
				else
					wTf_("File is small")
					do shell script "mv " & quoted form of i & space & quoted form of OtherPath
					wTf_(fileName & " moved to Other files")
					userLog_("Detected a " & ext & " file, move to " & OtherPath & " succesful")
				end if
			end if
			

Is it possible to slim this down to just a few lines?

Also, for when needed, here is the rest of the script:

on adding folder items to this_folder after receiving added_items
	wTf_("----------------")
	wTf_("Beginning of debug log file")
	wTf_("$t")
	userLog_("===========")
	userLog_("Beginning of user log file")
	try
		display notification "New file(s) detected!"
		set VideoPath to POSIX path of (POSIX file "/Volumes/Macintosh HD/Movies")
		set VideoExt to {"mp4", "avi", "mkv"}
		set DocumentPath to POSIX path of (POSIX file "/Volumes/Macintosh HD/Documents/")
		set DocumentExt to {"doc", "docx", "xlsx", "xls", "pages"}
		set MusicPath to POSIX path of (POSIX file "/Volumes/Macintosh HD/Music/")
		set MusicExt to {"mp3", "aac", "AIFF", "m4a", "ogg", "wav"}
		set PicturePath to POSIX path of (POSIX file "/Volumes/Macintosh HD/Pictures/")
		set PictureExt to {"jpg", "bmp", "tiff", "png"}
		set LargeDataPath to (POSIX file "/Volumes/Macintosh HD/Downloads/Large/")
		set OtherPath to POSIX path of (POSIX file "/Volumes/Macintosh HD/Downloads/Others/")
		set TorrentPath to POSIX path of (POSIX file "/Volumes/Macintosh HD/Torrents/")
		set TorrentExt to {"torrent", "TORRENT"}
		set y to {"VideoExt", "MusicExt", "TorrentExt"}
		set Filecount to 0
		repeat with i in added_items
			userLog_("Added file: " & i)
		end repeat
		repeat with i in added_items
			set Filecount to Filecount + 1
			wTf_(("File with: " & i) as text)
			set filepath to i as text
			tell application "Finder"
				set fileName to name of i
				set ext to name extension of i
				set ext1 to ("File Extension: " & (ext as text)) as text
			end tell
			wTf_(ext1)
			set ii to i
			set i to POSIX path of i
			if ext is in VideoExt then
				wTf_("Detected file type: Video")
				do shell script "mv " & quoted form of i & space & quoted form of VideoPath
				wTf_(fileName & " moved to Video")
				userLog_("Detected a " & ext & " file, move to " & VideoPath & " succesful")
			else if (MusicExt contains ext) = true then
				wTf_("Detected file type: Music")
				do shell script "mv " & quoted form of i & space & quoted form of MusicPath
				wTf_(fileName & " moved to Music")
				userLog_("Detected a " & ext & " file, move to " & MusicPath & " succesful")
			else if (DocumentExt contains ext) = true then
				wTf_("Detected file type: Document")
				do shell script "mv " & quoted form of i & space & quoted form of DocumentPath
				wTf_(fileName & " moved to Documents")
				userLog_("Detected a " & ext & " file, move to " & DocumentPath & " succesful")
			else if ext is in TorrentExt then
				wTf_("Detected file type: Torrent")
				do shell script "mv " & quoted form of i & space & quoted form of TorrentPath
				wTf_(fileName & " moved to Torrents")
				userLog_("Detected a " & ext & " file, move to " & TorrentPath & " succesful")
			else if (PictureExt contains ext) = true then
				wTf_("Detected file type: Picture")
				do shell script "mv " & quoted form of i & space & quoted form of PicturePath
				wTf_(fileName & " moved to Pictures")
				userLog_("Detected a " & ext & " file, move to " & PicturePath & " succesful")
			else
				wTf_("Detected file type: Other")
				tell application "System Events" to set filesize to (size of ii)
				if filesize is greater than "524288000" then
					wTf_("File is larger than 500mb (" & filesize & " bytes)")
					do shell script "mv " & quoted form of i & space & quoted form of LargeDataPath
					wTf_(fileName & " moved to Large Files")
					userLog_("Detected a large file (" & filesize & " bytes), move to " & LargeDataPath & " succesful")
				else
					wTf_("File is small")
					do shell script "mv " & quoted form of i & space & quoted form of OtherPath
					wTf_(fileName & " moved to Other files")
					userLog_("Detected a " & ext & " file, move to " & OtherPath & " succesful")
				end if
			end if
			
		end repeat
	on error x
		set logsynctime to (current date) as text
		wTf_("[" & (current date) & "]" & " - Error: " & x)
		userLog_("One or more files were not moved succesfully, open debuglog.txt and search for: \"" & logsynctime & "\"")
		display notification x with title "File not moved:"
	end try
	userLog_()
	wTf_("End of log")
end adding folder items to

on userLog:x
	set filepath to (path to desktop as string) & "Log.txt"
	try
		set fileRef to open for access file filepath with write permission
		write (x & return) to fileRef starting at eof
		close access fileRef
	on error
		try
			close access file filepath
		end try
	end try
end userLog:

on wTf:(theActionExecuted)
	if theActionExecuted contains "moved to" then
		display notification theActionExecuted with title "File Move Complete!"
	end if
	if theActionExecuted = "$t" then
		set theActionExecuted to "[" & (current date) & "]"
	end if
	set filepath to (path to desktop as string) & "debugLog.txt"
	try
		set fileRef to open for access file filepath with write permission
		write (theActionExecuted & return) to fileRef starting at eof
		close access fileRef
	on error
		try
			close access file filepath
		end try
	end try
end wTf:

Model: MacbookPro9.1
AppleScript: 10.9
Browser: Safari 537.71
Operating System: Mac OS X (10.8)

Here his my proposal :

if ext is in VideoExt then
	my newHandler("Video", i, VideoPath, filename, ext)
else if ext is in MusicExt then
	my newHandler("Music", i, MusicPath, filename, ext)
else if ext is in DocumentExt then
	my newHandler("Document", i, DocumentPath, filename, ext)
else if ext is in TorrentExt then
	my newHandler("Torrent", i, TorrentPath, filename, ext)
else if ext is in PictureExt then
	my newHandler("Picture", i, PicturePath, filename, ext)
else
	wTf_("Detected file type: Other")
	tell application "System Events" to set filesize to (size of ii) as text # I added "as text" for the test to come
	if filesize is greater than "524288000" then
		wTf_("File is larger than 500mb (" & filesize & " bytes)")
		do shell script "mv " & quoted form of i & space & quoted form of LargeDataPath
		wTf_(filename & " moved to Large Files")
		userLog_("Detected a large file (" & filesize & " bytes), move to " & LargeDataPath & " succesful")
	else
		wTf_("File is small")
		do shell script "mv " & quoted form of i & space & quoted form of OtherPath
		wTf_(filename & " moved to Other files")
		userLog_("Detected a " & ext & " file, move to " & OtherPath & " succesful")
	end if
end if

on newHandler(detected_file_type, i_, the_path, file_name, ext_)
	wTf_("Detected file type: " & detected_file_type)
	do shell script "mv " & quoted form of i_ & space & quoted form of the_path
	wTf_(file_name & " moved to " & detected_file_type & "s")
	userLog_("Detected a " & ext_ & " file, move to " & the_path & " succesful")
end newHandler

Yvan KOENIG (VALLAURIS, France) lundi 2 décembre 2013 20:49:07

I thought about that as well. However, this is not what i meant by a smarter way. Yes, it is smarter. But it’s a better improvement of what happens after some statement is correct. What i seek is to replace “If else” al together. So that i would make a list of file types:
set possible_types to {“Video”,“Pictures”,“Music”}
set VideoExt to {“mp4”}
set Video path to
etc.

Now that i think of it. maybe i can approach it on a whole other way. For example a text/xml file telling the script what extension should be called what and where everything should be moved.

I’ll see…

Hello.

Yvan’s approach is a whole lot better than yours, as it doesn’t repeat the same code.

You can really just have two code-paths in your script, one for when the extension is known, where you can execute accordingly to a line in a file you read in. (The lines can be indexed, so you know what “rule” from the file to use when it is the size that is the primary classification scheme of the file.

You can even have table headings in the file to make it easy to edit. :slight_smile:

Here is some handlers to help you out with my proposition.

Example command file:


set mypars to ttxtPars()

set mylist to explode from mypars by ","
log item 2 of mylist
-- > (*Music, MusicPath,  musicext*)
log item 2 of item 1 of mylist
--> (* Videopath*)

set thisRule to foundext for " videoext" by mylist
log thisRule
--> (*Video, Videopath, videoext*)

set thisRule to foundext for "scriptext" by mylist
log thisRule
--> false


(* This handler must be replaced with something that takes text from a file *)

on ttxtPars()
	tell application "TextEdit" to tell its front document
		set theText to text of it
	end tell
	return theText
end ttxtPars

on foundext for theEXt by theList
	script o
		property theRules : theList
	end script
	set {found, theEXt} to {0, first word of theEXt}
	repeat with i from 1 to (length of o's theRules)
		if theEXt is in item i of o's theRules then
			set found to i
			exit repeat
		end if
	end repeat
	if found > 0 then
		return item i of o's theRules
	else
		return false
	end if
end foundext

on explode from theData by aDelim
	--takes  an initial chunck of text, turns it into paragraphs, and then turns 
	-- the paragraphs into lists with items. Any leading/trailing 
	-- whitespace  around the list separator is removed with it.
	script o
		property theContents : theData
	end script
	if class of theData is list then
		-- we have been broken into paragraphs and must create
		-- a list of list for each paragraph.
		repeat with i from 1 to (length of o's theContents)
			set item i of o's theContents to explode from item i of o's theContents by aDelim
		end repeat
	else if (offset of linefeed in theData) > 0 ¬
		or (offset of return in theData) > 0 then
		-- We got an initial chunk of text we'll turn into paragraphs
		tell (a reference to text item delimiters)
			local tids
			set {tids, contents of it} to {contents of it, {linefeed, return}}
			set o's theContents to text items of o's theContents
			set contents of it to tids
		end tell
		-- And pass it onto ourself for processing each paragraph.
		set o's theContents to explode from o's theContents by aDelim
	else
		-- We must turn a paragraph into a list of ists.
		tell (a reference to text item delimiters)
			local tids
			set {tids, contents of it} to {contents of it, (space & aDelim)}
			-- removes any leading spaces from list separator.
			set o's theContents to text items of theData
			set contents of it to aDelim
			set o's theContents to o's theContents as text
			set contents of it to (aDelim & space)
			-- removes any trailing spaces from the list separator.
			set o's theContents to text items of theData
			set contents of it to aDelim
			set o's theContents to o's theContents as text
			-- breaks the string into a list by list separator.
			set o's theContents to text items of o's theContents
			set contents of it to tids
		end tell
	end if
	return o's theContents
end explode

Edit

I simplyfied the explode handler a little bit.

Added a substitute for a line if there are spaces in filenames in the explode handler.

Improved the removal of whitespace around the list separator, you should be able to spot a tab, or two or more spaces, and remove those from the line manually.

Rewrote the explode handler, to handle an initial chunck of text, turn it into paragraphs, and then turn the paragraphs into lists with items.

Corrected comments.

Thank you very much! That’s what i was looking for!

I installed ssd as my main drive, the script i was working on was needed to let it move files to my hdd. Which, naturally, has more space to save large files. However, i wanted to make it easily expandable (maybe for other with the same setup as me). But wasn’t sure how to go about it without editing the entire script.

Anyway, i’ll make some final changes (like a read sub) and post it here tomorrow or so.

Thank you McUsrII!