Become a member of the iLounge Forums. Register Now!
To start viewing messages, select the forum that you want to visit from the selection below.
If this is your first visit, be sure to check out the Forum FAQ and Forum Policy.
If this is your first visit, be sure to check out the Forum FAQ and Forum Policy.
Topic: Finding Albums With Missing Tracks?
|
|
#1
|
||
|
Freshman Lounger
Join Date: Jan 2009
Posts: 14
|
I have several albums that are incomplete, i.e., the number of tracks in the album is less than the "of x" number.
As I import new songs, I have begun to flag incomplete albums by adding a "*" to the end of each album name. I'd like to go back and apply this same flag to all the incomplete albums that were in my library beforehand. Is there a script - even a combination of scripts - or some other way that will be easier than having to eyeball my way through my albums? Thanks, Peter Sherman |
||
|
|
|
Join the iLounge Community and the ad above will disappear.
|
|
#2
|
||
|
Veteran Lounger
Join Date: Oct 2006
Location: About 3 feet in front of the monitor
Posts: 4,878
|
I'm not aware of anything(s) that would fit your bill.
You can try this, provided you don't blame me if it blows up in your face ;-) No but seriously -- I wasn't about to muck with my whole library while whipping this up, so I built it to look at only a few tracks in a specific playlist (right now that's a playlist named "test") instead of looking at the whole library. And in my testing, it worked fine: my "test" playlist had 11 tracks in it -- 6 tracks were from 4 different incomplete albums and 5 tracks were from 3 different complete albums; after running, every track from each of the 4 different incomplete albums had the Album tag changed to "<albumName>*" and every track from every complete album was left alone. So, it worked for me. But it may not work for you...and if it doesn't, it's not my fault. By using this script you agree that your use is entirely at your own risk. This script will change ID3 tags in tracks.... Try it out by creating a playlist named "test" and adding a few tracks to "test" -- a few tracks that you know are from incomplete albums, and a few that you know are from complete albums. Run the script and see how things look.... If you're willing to take the risk, make the change that's noted up near the top (commenting one line, uncommenting another), save the script, and turn it loose on your entire Music playlist. Oh, and did I mention? Use this solely at your own risk: Code:
tell application "iTunes"
set music_playlist_ref to a reference to playlist "Music"
-- to mangle your Music playlist (i.e. ALL your music) directly,
-- comment out this next line, and uncomment the line that follows it
set target_playlist_ref to a reference to playlist "test"
--set target_playlist_ref to music_playlist_ref
set album_list to {} -- every unique album name we see gets added to this list
set ofi to fixed indexing
set fixed indexing to true
with timeout of 60 * 60 seconds -- not sure if this is needed, but can't hurt
-- work on every track of a playlist
repeat with c from 1 to count of every track in target_playlist_ref
set trak_ref to (a reference to track c of target_playlist_ref)
set incomplete_album_name to album of trak_ref
if incomplete_album_name is not "" then -- only work on tracks that have an Album name
-- get a "complete album" name and an "incomplete album" name for this album
if last character of incomplete_album_name is "*" then
set complete_album_name to text 1 thru -2 of incomplete_album_name
else
set complete_album_name to incomplete_album_name
set incomplete_album_name to incomplete_album_name & "*"
end if
-- now figure out if we've already seen this album
set havent_seen_this_album_yet to true
set havent_seen_this_album_yet to ((complete_album_name is not in album_list) or (incomplete_album_name is not in album_list))
-- only work on albums we haven't seen yet....
if havent_seen_this_album_yet then
-- get whatever tracks each album has
set complete_album_trax to {}
set incomplete_album_trax to {}
if complete_album_name is not in album_list then
set complete_album_trax to (every track of music_playlist_ref whose album is complete_album_name)
end if
if incomplete_album_name is not in album_list then
set incomplete_album_trax to (every track of music_playlist_ref whose album is incomplete_album_name)
end if
-- mark these albums as having been seen
set end of album_list to complete_album_name
set end of album_list to incomplete_album_name
-- set up to run through the album's tracks...
set trax to (complete_album_trax & incomplete_album_trax)
set number_of_tracks to 0
set track_nums to {}
-- get total tracks for album; get track number for each track
repeat with trak in trax
try
set track_count to track count of trak
on error
set track_count to 0
end try
if track_count > number_of_tracks then set number_of_tracks to track_count
set end of track_nums to track number of trak
end repeat
-- flag will wind up being true if we can account for every track number we think the album has
set flag to false
if number_of_tracks > 0 then
repeat with i from 1 to number_of_tracks -- test 1, 2, 3, 4, etc. to see if...
set flag to false
repeat with j from 1 to count of track_nums
if item j of track_nums = i then -- ...we have a track with that track number
set flag to true
exit repeat
end if
end repeat
if not flag then exit repeat -- any failures means incomplete album
end repeat
end if
-- if the combined tracks of complete and incomplete aren't enough to complete
-- the album, rename each "complete" track's Album to the incomplete name
if not flag then
repeat with trak in complete_album_trax
set album of trak to incomplete_album_name
end repeat
end if
(* haven't tried this; seems like it should work...
-- check to see if maybe an incomplete album has been completed
if flag then
if complete_album_trax is not {} then
repeat with trak in incomplete_album_trax
set album of trak to complete_album_name
end repeat
end if
end if
*)
end if
end if
end repeat
end timeout
set fixed indexing to ofi
end tell
|
||
|
|
|
|
|
#3
|
||
|
Freshman Lounger
Join Date: Jan 2009
Posts: 14
|
S2_Mac - thanks for putting this script together. I'll put it to the test and let you know what happens. Baby steps first, of course, but if it works well on a small playlist, I'll give it a larger playlist, and if it still works well, then I think I'll feel ok running it through the rest of my library.
|
||
|
|
|
|
|
#4
|
||
|
Veteran Lounger
Join Date: Aug 2004
Location: Greenville, SC
Posts: 4,289
|
J. River Media Center for Windows has a built-in smart playlist that will find incomplete albums. Try the demo at jrmediacenter.com.
|
||
|
|
|
|
|
#5
|
||
|
Veteran Lounger
Join Date: Oct 2006
Location: About 3 feet in front of the monitor
Posts: 4,878
|
Hmm...might not be an option for someone in the "AppleScripts for iTunes (Mac)" forum ;-)
|
||
|
|
|
|
|
#6
|
||
|
Freshman Lounger
Join Date: Jan 2009
Posts: 14
|
S2_Mac:
I've tried running this script from the iTunes Script menu, but it hangs when processing the first track in the test playlist when I get to this line of code: set incomplete_album_trax to (every track of music_playlist_ref whose album is incomplete_album_name) I ran it from Script Editor with the same results. It seems to hang when (every track of music_playlist_ref whose album is incomplete_album_name) = 0. To test this, I added a * to the album name of the first track in the playlist - sure enough, this time the script hung on the if/end clause immediately above: set complete_album_trax to (every track of music_playlist_ref whose album is complete_album_name) I'm not looking to drag you into the pit of my obsessiveness, but my AppleScript skills are negligible, and I sense you're someone who likes a challenge. :-) If you're up for another looksee at this, I'll sure appreciate it, but I'll understand if it's back on me. Thanks, Peter Sherman |
||
|
|
|
|
|
#7
|
||
|
Freshman Lounger
Join Date: Jan 2009
Posts: 14
|
Thanks for the tip, Galley - but I am running a Mac, so this one won't work for me.
All the best, Peter Sherman |
||
|
|
|
|
|
#8
|
||
![]() Join Date: May 2003
Location: Tiskilwa, IL
Posts: 10,131
|
Ah. Too bad it isn't working for the OP.
You have named the "test" playlist "test" as the code relies on their being a playlist with that name it appears. I may have to grab this code and perhaps try to change it to append comment information to wrangle albums around. I currently just try to add [complete] to the comment tags of all complete albums I add to iTunes so I can wrangle the completes into a smartplaylist. Lack of iTunes ability to really identify a complete set of albums is a disappointing missing feature, even the "album rating" feature is poorly implemented to capture complete albums in a specific subset.
__________________
![]() 5G 80GB iPod / iPhone 4 / MacBook Pro / Last.fm / Links to common ?'s FAQS | Artist missing songs | iPod not Recognized Mac or PC | disable auto-sync temp. | Disk mode How to | iPod has Folder/! |
||
|
|
|
|
|
#9
|
||
|
Veteran Lounger
Join Date: Oct 2006
Location: About 3 feet in front of the monitor
Posts: 4,878
|
The only way I can replicate your error is by not having a playlist named "test"..so I'm thinkin' that's the problem ;-)
But just try this. It's the "real" script (runs through your entire music library), but instead of changing album names it just puts the names of all incomplete albums into a text file. Takes a long time to run (as in, takes a long time to run). I'll work on a faster Perl version when I get some time.... Code:
tell application "iTunes"
set music_playlist_ref to a reference to playlist "Music"
set target_playlist_ref to a reference to playlist "Music"
set album_list to {}
set ofi to fixed indexing
set fixed indexing to true
set incomplete_album_list to {}
set dest_file to ((get path to desktop) & "Incomplete Albums.txt") as string
with timeout of 60 * 60 seconds
repeat with c from 1 to count of every track in target_playlist_ref
set trak_ref to (a reference to track c of target_playlist_ref)
set incomplete_album_name to album of trak_ref
if incomplete_album_name is not "" then
if last character of incomplete_album_name is "*" then
set complete_album_name to text 1 thru -2 of incomplete_album_name
else
set complete_album_name to incomplete_album_name
set incomplete_album_name to incomplete_album_name & "*"
end if
set havent_seen_this_album_yet to true
set havent_seen_this_album_yet to ((complete_album_name is not in album_list) or (incomplete_album_name is not in album_list))
if havent_seen_this_album_yet then
set complete_album_trax to {}
set incomplete_album_trax to {}
if complete_album_name is not in album_list then
set complete_album_trax to (every track of music_playlist_ref whose album is complete_album_name)
end if
if incomplete_album_name is not in album_list then
set incomplete_album_trax to (every track of music_playlist_ref whose album is incomplete_album_name)
end if
set end of album_list to complete_album_name
set end of album_list to incomplete_album_name
set trax to (complete_album_trax & incomplete_album_trax)
set number_of_tracks to 0
set track_nums to {}
repeat with trak in trax
try
set track_count to track count of trak
on error
set track_count to 0
end try
if track_count > number_of_tracks then set number_of_tracks to track_count
set end of track_nums to track number of trak
end repeat
set flag to false
if number_of_tracks > 0 then
repeat with i from 1 to number_of_tracks
set flag to false
repeat with j from 1 to count of track_nums
if item j of track_nums = i then
set flag to true
exit repeat
end if
end repeat
if not flag then exit repeat
end repeat
end if
if not flag then
repeat with trak in complete_album_trax
if not (incomplete_album_name is in incomplete_album_list) then
set end of incomplete_album_list to incomplete_album_name
end if
end repeat
end if
end if
end if
end repeat
end timeout
set fixed indexing to ofi
set file_ref to open for access dest_file with write permission
try
write my list_to_lines(incomplete_album_list) to file_ref starting at 1
close access file_ref
on error
close access file_ref
end try
display dialog "Done!" buttons {"•"} default button 1 giving up after 15
end tell
on list_to_lines(in_list)
set {TID, text item delimiters} to {text item delimiters, return}
set str to in_list as text
set text item delimiters to TID
return str
end list_to_lines
|
||
|
|
|
|
|
#10
|
|||
|
Freshman Lounger
Join Date: Jan 2009
Posts: 14
|
Quote:
Many thanks, and I'll post back with results when I can. All the best, Peter Sherman |
|||
|
|
|
|
|
#11
|
||
|
Veteran Lounger
Join Date: Oct 2006
Location: About 3 feet in front of the monitor
Posts: 4,878
|
So here's a quickie that simply lists all incomplete albums; it writes the list out to a text file on the desktop. (There's enough here to finish an Incomplete Album name-changing script, but I'd like another night to make the iTunes part faster.) This one will run in just a couple of seconds.
Code:
-- "List Incomplete Albums" script
-- Saves the names of all incomplete albums as a list of lines to a text file.
-- "Incomplete album" means that there are not enough "Track Number"s to fill the
-- range of 1 to the highest "Track Total" number of all the tracks that share an "Album" name.
-- from numerous Doug Adams scripts
global path_to_xml
set path_to_xml to (escape_spaces(text 3 through -3 of (do shell script "defaults read com.apple.iapps iTunesRecentDatabasePaths"))) as string
set incomplete_album_list to my find_incs()
set dest_file to ((get path to desktop) & "Incomplete Albums.txt") as string
set file_ref to open for access dest_file with write permission
try
set eof file_ref to 0
write incomplete_album_list to file_ref
close access file_ref
on error
close access file_ref
end try
set d_title to number of paragraphs of incomplete_album_list & " Incomplete Albums" as string
display dialog "View the list of incomplete albums in TextEdit?" buttons {"Cancel", "OK"} default button 2 with title d_title
tell application "TextEdit"
open dest_file
activate
end tell
to find_incs()
set the_cmd to "perl -e 'local $/ = undef;
my $s=<>;my @out=();my $str;my $n=\"\\n\";my $flag;
$track_num_label = \"track_num\"; $track_tot_label = \"track_tot\"; $track_id_label = \"id\";
while ($s=~m:<key>(\\d+)</key>.*?<dict>(.*?)</dict>:sg ) {
($id,$str) = ($1,$2); $str=~s/&/&/sg;
$album=$str=~m:<key>Album</key><string>(.*?)\\*?</string>:sg?$1:\"Unknown Album\";
$album=~s/^(the) (.+)/$2, $1/i;
$track_num=$str =~m:<key>Track Number</key><integer>(\\d*)</integer>:sg?$1:\"0\";
$track_tot =$str =~m:<key>Track Count</key><integer>(\\d*)</integer>:sg?$1:\"0\";
$h{$album}{$track_num_label}[$track_num]++;
$track_tot > $h{$album}{$track_tot_label} and $h{$album}{$track_tot_label} = $track_tot;
push(@{$h{$album}{$track_id_label}},$id);
}
foreach $album (sort {lc $a cmp lc $b} keys %h) {
$track_tot = $h{$album}{$track_tot_label}; $flag = 1;
for ($i=1;$i<$track_tot;$i++) {
$flag = $h{$album}{$track_num_label}[$i];
$flag or last;
}
$album=~s/^(.+), (the)/$2 $1/i;
!$flag and push(@out,$album.$n);
}
print @out;' " & path_to_xml
return do shell script the_cmd
end find_incs
on escape_spaces(txt)
set {TID, text item delimiters} to {text item delimiters, " "}
set {txt_items, text item delimiters} to {every text item of txt, "\\ "}
set {txt, text item delimiters} to {txt_items as string, TID}
return txt
end escape_spaces
Paste this code into a new Script Editor window; save as a script, no options. |
||
|
|
|
|
|
#12
|
||
|
Veteran Lounger
Join Date: Oct 2006
Location: About 3 feet in front of the monitor
Posts: 4,878
|
So this seems to work just fine. This script identifies incomplete albums and either adds them to a playlist or appends “*” to their Album tag. This will run quickly; easily under minute for most libraries.
Code:
-- “Find Incomplete Albums” script v0.82
-- This script identifies incomplete albums; their tracks can then be added to
-- a playlist, or their Album tags can have a "*" appended.
-- OPTIONAL USER CONFIGURATION -----
--
-- incomplete albums can be added to this playlist; name it to suit your tastes
-- the default value is: "Incomplete Albums"
property incomplete_album_playlist_name : "Incomplete Albums"
--
----- END CONFIGURATION -----
(* - - - - - - - - - Here's the code - - - - - - - - - *)
if incomplete_album_playlist_name is "" then set incomplete_album_playlist_name to "Incomplete Albums"
display dialog "Should incomplete albums be renamed with a trailing “*”, or added to a playlist?" buttons {"Cancel", "Rename", "Playlist"} default button 3 with title "Find Incomplete Albums"
set playlist_or_rename to button returned of the result
global path_to_xml
set path_to_xml to (escape_spaces(text 3 through -3 of (do shell script "defaults read com.apple.iapps iTunesRecentDatabasePaths"))) as string
set incomplete_album_list to nested_list_from_lines(find_incs())
if incomplete_album_list is {} then return
tell application "iTunes"
if playlist_or_rename is "Playlist" then -- get an empty playlist
if (exists user playlist incomplete_album_playlist_name) then
set incomplete_album_playlist to user playlist incomplete_album_playlist_name
delete every track of incomplete_album_playlist
else
set incomplete_album_playlist to (make user playlist with properties {name:incomplete_album_playlist_name})
end if
end if
repeat with an_album in incomplete_album_list
set inc_album_name to ((item 1 of an_album) & "*")
repeat with j from 2 to count of an_album
if playlist_or_rename is "Playlist" then -- assign each track to a playlist
duplicate (some track whose database ID is item j of an_album) to incomplete_album_playlist
else if playlist_or_rename is "Rename" then -- change each track's Album tag
set the album of (some track whose database ID is item j of an_album) to inc_album_name
end if
end repeat
end repeat
end tell
to find_incs()
set the_cmd to "perl -e 'local $/ = undef;
my $s=<>;my @out=();my $str;my $n=\"\\n\";my $flag;
$track_num_label = \"track_num\"; $track_tot_label = \"track_tot\"; $track_id_label = \"id\";
while ($s=~m:<key>(\\d+)</key>.*?<dict>(.*?)</dict>:sg ) {
($id,$str) = ($1,$2); $str=~s/&/&/sg;
$str=~m:<key>Kind</key><string>.*?(audio).*?</string>: or next;
$album=$str=~m:<key>Album</key><string>(.*?)\\*?</string>:?$1:next;
$track_num=$str =~m:<key>Track Number</key><integer>(\\d+)</integer>:?$1:0;
$track_tot =$str =~m:<key>Track Count</key><integer>(\\d+)</integer>:?$1:1;
$h{$album}{$track_num_label}[$track_num]++;
$track_tot > $h{$album}{$track_tot_label} and $h{$album}{$track_tot_label} = $track_tot;
push(@{$h{$album}{$track_id_label}},$id);
}
foreach $album (sort {lc $a cmp lc $b} keys %h) {
$track_tot = $h{$album}{$track_tot_label}; $flag = 1;
for ($i=1;$i<$track_tot;$i++) {
$flag = $h{$album}{$track_num_label}[$i];
$flag or last;
}
if (!$flag) {
push(@out,$album.$n);
foreach $id (@{$h{$album}{$track_id_label}}) {
$id and push(@out,$id.$n);
}
push(@out,$n);
}
}
push(@out,$n);
print @out;' " & path_to_xml
return do shell script the_cmd
end find_incs
on escape_spaces(txt)
set {TID, text item delimiters} to {text item delimiters, " "}
set {txt_items, text item delimiters} to {every text item of txt, "\\ "}
set {txt, text item delimiters} to {txt_items as string, TID}
return txt
end escape_spaces
on lines_to_list(str)
set {TID, text item delimiters} to {text item delimiters, return}
set lst to every text item of str
set text item delimiters to TID
return lst
end lines_to_list
on nested_list_from_lines(txt)
set out_list to {}
set ind1 to 1
set len to length of txt
repeat
if ind1 > len then exit repeat
set o to offset of (return & return) in (text ind1 through -1 of txt)
if o is 0 then exit repeat
set t to text ind1 through (ind1 + o - 2) of txt
set end of out_list to my lines_to_list(t)
set ind1 to (ind1 + o + 1)
end repeat
return out_list
end nested_list_from_lines
|
||
|
|
|
|
|
#13
|
||
|
Veteran Lounger
Join Date: Oct 2006
Location: About 3 feet in front of the monitor
Posts: 4,878
|
Wups -- slight error in that script ;-) It misses the last track of every album, so don't use it.
Use this one instead! Works a treat; cleaner code than above; more options. (Plus, includes a script named "Remove Appended Astersks" that...wait for it...removes appended asterisks from Album tags ;-) |
||
|
|
|
|
|
#14
|
|||
|
Freshman Lounger
Join Date: Jan 2009
Posts: 14
|
Did I say I'd be away from my computer for a few days? I didn't expect it would be over a week. :-)
S2_Mac - thanks for keeping up the work on this script. I downloaded the most recent version (2/3) and am getting this error message: "A descriptor mismatch occurred." This was while running the script to create an "Incomplete Albums" playlist with the "Normal" setting. It came up after about three minutes of the script running. When I dismissed the error message, the playlist was there, but empty. I do like the playlist option - giving me/you/anyone who wants to do this a chance to review which albums will be renamed if/when the script is re-run with that option. Thanks again, Peter Sherman Quote:
Last edited by Peter Sherman; 02-05-2009 at 06:09 AM. |
|||
|
|
|
|
|
#15
|
||
|
Veteran Lounger
Join Date: Oct 2006
Location: About 3 feet in front of the monitor
Posts: 4,878
|
If you're running Tiger, this version works a treat; fast! For Leopard, it's in the works...en route ot a Leopard machine right now.
|
||
|
|
|
Topic: Finding Albums With Missing Tracks?
Become a member of the iLounge Forums. Register Now!
To start viewing messages, select the forum that you want to visit from the selection below.
If this is your first visit, be sure to check out the Forum FAQ and Forum Policy.
If this is your first visit, be sure to check out the Forum FAQ and Forum Policy.
| Thread Tools | Search this Thread |
| Display Modes | Rate This Thread |
|
|
View iLounge History. Read our old Forums Archive (2001-2003)
All times are GMT -4. The time now is 05:53 PM.
All times are GMT -4. The time now is 05:53 PM.













Linear Mode


