diff --git a/scripts/music-duplicates.py b/scripts/music-duplicates.py index 5db55772..1afc79eb 100755 --- a/scripts/music-duplicates.py +++ b/scripts/music-duplicates.py @@ -4,6 +4,7 @@ # that the project needs. from glob import glob +import hashlib import os import re import sys @@ -12,41 +13,22 @@ PHASE1_MATCH_RE = re.compile(r'(e\dm\d)', re.I) PHASE2_MATCH_RE = re.compile(r'(map\d\d)', re.I) FREEDM_MATCH_RE = re.compile(r'(dm\d\d)', re.I) -DOOM2_TRACKS = ( - 'runnin', 'stalks', 'countd', 'betwee', 'doom', 'the_da', 'shawn', - 'ddtblu', 'in_cit', 'dead', 'stlks2', 'theda2', 'doom2', 'ddtbl2', - 'runni2', 'dead2', 'stlks3', 'romero', 'shawn2', 'messag', 'count2', - 'ddtbl3', 'ampie', 'theda3', 'adrian', 'messg2', 'romer2', 'tense', - 'shawn3', 'openin', 'evil', 'ultima', -) - def get_music_tracks(): - """Returns a dictionary mapping from MIDI name (subpath of musics/) + """Returns a dictionary mapping from MIDI file SHA1 to a list of game tracks that use that MIDI.""" result = {} musics_path = os.path.join(os.path.dirname(sys.argv[0]), '../musics') for mus in glob('%s/*.mus' % musics_path): - try: - symlink = os.readlink(mus) - if symlink not in result: - result[symlink] = [] - result[symlink].append(os.path.basename(mus)) - except OSError: - pass + with open(mus) as f: + contents = f.read() + m = hashlib.sha1() + m.update(contents) + digest = m.digest() + basename = os.path.basename(mus) + result.setdefault(digest, []).append(basename) return result -def doom2_level_for_file(filename): - """Given a filename that may be named like a Doom 2 music name - (eg. d_stalks.mid), get the level number it corresponds to - or 0 if it doesn't match.""" - filename = os.path.basename(filename) - for i, doom2_name in enumerate(DOOM2_TRACKS): - if filename.startswith('d_%s.' % doom2_name): - return i + 1 - else: - return 0 - -def get_prime_track(midi, tracks): +def get_prime_track(tracks): """Given a list of tracks that all use the same MIDI, find the "prime" one (the one that isn't a reuse/duplicate).""" # We have almost all Phase 2 tracks fulfilled. So if the same @@ -56,25 +38,15 @@ def get_prime_track(midi, tracks): if len(phase2_tracks) == 1: return phase2_tracks[0] - level = doom2_level_for_file(midi) - if level: - for track in phase2_tracks: - if ('map%02i' % level) in track: - return track - - # If the filename of the MIDI file (symlink target) describes a - # level, then that level is the leader. - m = PHASE1_MATCH_RE.search(os.path.basename(midi)) - if m: - level = m.group(1) - for track in tracks: - if level in track: - return track + # FreeDM music has been hand-picked. So if it is used for both + # Phase 1 and FreeDM, assume it's probably a FreeDM track. + freedm_tracks = [x for x in tracks if FREEDM_MATCH_RE.search(x)] + if len(freedm_tracks) == 1: + return freedm_tracks[0] # We're out of options. Pick the first one in the list. - #print 'Warning: Don't know which of %s is the leader for %s.' % ( - # tracks, midi) - return tracks[0] + #print "Warning: Don't know which of %s is the leader." % tracks + return sorted(tracks)[0] def find_missing_tracks(tracks): """Given a dictionary of tracks, get a list of "missing" tracks.""" @@ -82,7 +54,7 @@ def find_missing_tracks(tracks): for midi, tracks in tracks.items(): if len(tracks) < 2: continue - prime_track = get_prime_track(midi, tracks) + prime_track = get_prime_track(tracks) result.extend(x for x in tracks if x != prime_track) return result