2006-04-25

실습 - iTunes 제목, 앨범 정리 (대소문자 처리)

갖고 있는 CD에서 MP3로 추출한다거나, 친구들에게 선물을 받는 등 다양한 경로로 MP3 등의 음원을 보유하게 됩니다. 일부 음원은 ID3 tag에 맞춰 깔끔하게 정리되어 있기도 하고, 또 어떤 음원은 영어로 된 제목과 앨범이 전부 소문자로 되어 있거나 반대로 대문자로만 되어있는 경우도 있습니다. 갖고 있는 음원의 수가 많지 않다면 일일이 손으로 고칠 수도 있지만, 그 수가 매우 많다면 곤란해집니다.
이런 경우를 위해 다양한 유틸리티들이 개발되어 있지만, 이 블로그의 실습 코너들이 그렇듯이 실용성보다는 애플스크립트로도 가능하다는 것을 보이기 위해 iTunes에 등록된 음원의 제목과 앨범을 정리하는 스크립트를 짜보겠습니다.
iTunes에서 선택된 음원들만을 대상으로 정리 작업을 수행합니다. 자주 사용하실 것 같다면 스크립트 편집기에서 응용프로그램 포맷으로 저장하면 편리하게 쓰실 수 있을 것입니다. 소문자로 처리해야 하는 전치사, 접속사 등의 목록과 대문자로 표시해야 하는 목록 등은 직접 추가하거나 수정하실 수 있습니다.
property theCheckList : {"a", "after", "against", "an", "and", "at", "before", "but", "by", "down", "for", "from", "in", "into", "of", "on", "or", "under", "up", "upon", "the", "to", "with"}
-- 소문자로 표시될 전치사, 접속사, 관사의 목록입니다.
property theUpperList : {"(CD)", "CD", "UK", "BBC", "U.S.S.R.", "EP", "ABBA", "DNC:", "A.M.", "P.M."}
-- 대문자로 나타내야 할 단어들의 목록입니다.
property theSkipList : {"Mercedes-Benz"}
-- 대소문자 처리가 필요없는 단어들의 목록입니다.

try
tell application "iTunes"
set theseTracks to the selection of browser window 1
-- 현재 선택된 음원의 목록을 list로 가져옵니다.
if theseTracks is {} then error "선택된 트랙이 없습니다."
-- 선택된 음원이 하나도 없을 경우 나타낼 문장입니다.

repeat with thisTrack in theseTracks
set thisName to (name of thisTrack) as Unicode text
set thisAlbum to (album of thisTrack) as Unicode text

tell me
-- 일부 AppleScript의 기능이 iTunes 내부적으로 지원이 안되는 것 같습니다. 스크립트 편집기 혹은 컴파일될 응용프로그램에서 처리하도록 했습니다.
set newName to thisName as Unicode text
-- 제목입니다.
set newAlbum to thisAlbum as Unicode text
-- 앨범입니다.

if thisName is not "" then
set newName to orthographize(thisName)
end if

if thisAlbum is not "" then
set newAlbum to orthographize(thisAlbum)
end if
-- 제목이나 앨범이 비어있지 않은 경우에만 계속 진행합니다.
end tell

considering case
-- considering을 사용할 기회가 왔습니다. 애플스크립트에서 apple과 Apple을 같은 것으로 인식하기 때문에, 대소문자를 구별하라고 기별을 넣습니다.
if thisName is not newName then
--display dialog (thisName & " / " & newName) as string
-- iTunes에서 제대로 변환되는지 미리 테스트하려면 display dialog를 활성화시킵니다.(주석을 제거)
set the name of thisTrack to newName
-- iTunes에서는 undo가 되지 않기 때문에 display dialog를 이용해 테스트하실 때에는 이 줄의 스크립트는 주석처리하십시오. 아래 앨범의 경우도 마찬가지 입니다.
end if

if thisAlbum is not newAlbum then
--display dialog (thisAlbum & " / " & newAlbum) as string
set the album of thisTrack to newAlbum
end if
end considering
end repeat

beep
-- 작업이 완료되면 소리로 알려줍니다.
end tell

on error errMsg number errNum
log (errNum & " : " & errMsg) as string
end try

on orthographize(thisText)
-- 대소문자 처리를 담당한 핸들러입니다.
set oldDelimiter to AppleScript's text item delimiters
set AppleScript's text item delimiters to space
-- 문자열 내부의 구분을 공백(space)로 합니다. 기본값이 space이지만 혹시 다른 것으로 지정되어 있을 수도 있기 때문에 작업 완료 후 원상복구를 위해 oldDelimiter에 저장해놓습니다.

try
set theseWords to every text item of thisText as list
-- 단어들을 list에 담습니다.
set newText to ""
-- 대소문자 처리가 완료된 제목과 앨범 정보가 담길 변수입니다.

repeat with m from 1 to (count of items of theseWords)
set thisWord to item m of theseWords
set newWord to ""

if theCheckList contains thisWord then
-- 소문자 목록에 들어있는 경우입니다.
if m is 1 then
-- 첫번째 단어라면 첫글자는 대문자로 만듭니다.
set theseCharacters to every character of thisWord
set newWord to changeCase(first item of theseCharacters, 1)

repeat with n from 2 to (count of items of theseCharacters)
-- 나머지 글자는 소문자로 바꿉니다.
set newWord to (newWord & changeCase((item n of theseCharacters), 0)) as string
end repeat
else
set newWord to changeCase(thisWord, 0)
end if
else
-- 소문자로 바꿀 필요가 없는 단어의 경우입니다.
if thisWord is in theUpperList then
-- 대문자로 만들어야 하는 경우입니다.
set newWord to changeCase(thisWord, 1)

else if thisWord is in theSkipList then
-- 처리할 필요가 없는 경우입니다.
set newWord to thisWord

else
-- 일반적인 경우입니다. 첫글자는 대문자이고 나머지는 소문자입니다.
set theseCharacters to every character of thisWord

set newWord to ""
set theFirst to 1
set theSecond to 2

if first item of theseCharacters is in {"(", "\""} then
-- ()나 ""로 둘러쌓인 경우입니다.
set newWord to first item of theseCharacters
set theFirst to 2
set theSecond to 3
end if

set newWord to (newWord & changeCase(item theFirst of theseCharacters, 1)) as string

repeat with n from theSecond to (count of items of theseCharacters)
set newWord to (newWord & changeCase((item n of theseCharacters), 0)) as string
end repeat
end if
end if

set newText to (newText & newWord & space) as string

end repeat
on error errMsg number errNum
log ("error on orthographizing : " & errMsg) as string
end try

set AppleScript's text item delimiters to oldDelimiter
set finalText to trim(newText)
-- 단어들을 합치는 과정에서 마지막에 공백이 포함됩니다. 이 공백을 제거하기 위한 핸들러입니다.

return finalText
end orthographize

on trim(theText)
set trimmedText to ""

if (ASCII number (last character of theText)) is 32 then
-- 공백의 ascii number가 32입니다.
set n to 1
repeat with c in (every character of theText)
-- 마지막 글자만 제외하고 한글자씩 합치는 방식입니다.
set trimmedText to (trimmedText & c) as string

if n is (count of items of every character of theText) - 1 then exit repeat
set n to n + 1
end repeat
else
set trimmedText to theText
end if

return trimmedText
end trim

on changeCase(thisText, thisCase)
-- 대소문자 변환 핸들러입니다. 블로그 오른쪽에 있는 링크 중 essential sub-routine에 나와있는 것입니다.
-- 1 : to upper case
-- 0 : to lower case
set the upperCases to "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
set the lowerCases to "abcdefghijklmnopqrstuvwxyz"

if thisCase is 0 then
set the comparisonString to upperCases
set the sourceString to lowerCases
else
set the comparisonString to lowerCases
set the sourceString to upperCases
end if

set the newText to ""
repeat with thisChar in thisText
set x to the offset of thisChar in the comparisonString
if x is not 0 then
set the newText to (the newText & character x of the sourceString) as string
else
set the newText to (the newText & thisChar) as string
end if
end repeat

return the newText
end changeCase

0 Comments:

댓글 쓰기

<< Home