~zanneth/smsongpackinfo

dd70dcb065856459c2ddfd0a206d675607dc49e5 — Charles Magahern 10 years ago
Initial commit
1 files changed, 139 insertions(+), 0 deletions(-)

A smsongpackinfo.py
A  => smsongpackinfo.py +139 -0
@@ 1,139 @@
#!/usr/bin/env python
import os
import re
import sys

class SMSong(object):
    path = None

    title = None
    subtitle = None
    artist = None
    genre = None
    origin = None
    credit = None
    songfile = None
    bpms = None
    version = None

    def __init__(self, songfile_path=None):
        super(SMSong, self).__init__()
        if (songfile_path != None):
            self.path = songfile_path
            self.parse_songfile(songfile_path)

    def __str__(self):
        return "<{} {} title={}, artist={}>".format(
            self.__class__.__name__,
            hex(id(self)),
            self.title,
            self.artist
        )

    @classmethod
    def csv_header(self, delim=','):
        return delim.join([
            "title",
            "subtitle",
            "artist",
            "genre",
            "songfile"
        ])

    def parse_songfile(self, path):
        field_re = re.compile(r"#(?P<property>.+):(?P<value>.*);")
        songfile = open(path, "r")
        charbuf = ""

        while True:
            char = songfile.read(1)
            if (not char):
                break

            if (char not in ['\r', '\n']):
                charbuf += char

            if (char == ';'):
                match = field_re.search(charbuf)
                if (match):
                    prop = match.group("property")
                    value = match.group("value")
                    self._store_property(prop, value)

                charbuf = ""

        songfile.close()
        return True

    def csv(self, delim=','):
        values = [
            self.title,
            self.subtitle,
            self.artist,
            self.genre,
            self.songfile
        ]
        return delim.join([v if v else "" for v in values])

    def _store_property(self, prop, value):
        prop_to_attr = {
            "TITLE" : "title",
            "SUBTITLE" : "subtitle",
            "ARTIST" : "artist",
            "GENRE" : "genre",
            "ORIGIN" : "origin",
            "CREDIT" : "credit",
            "MUSIC" : "songfile",
            "BPMS" : "bpms",
            "VERSION" : "version"
        }
        prop_key = prop.upper()
        if (prop_key in prop_to_attr):
            attr = prop_to_attr[prop_key]
            if (attr == "version"):
                value = float(value)
            elif (attr == "songfile"):
                value = os.path.join(self.path, value)
            elif (attr == "bpms"):
                bpms = []
                bpm_pairs = value.split(",")
                for bpm_pair in bpm_pairs:
                    bpm_strs = bpm_pair.split("=")
                    bpms += [float(bpm_str) for bpm_str in bpm_strs]

                value = bpms

            setattr(self, attr, value)

        return True

def generate_csv(songs):
    csvstr = SMSong.csv_header() + '\n'
    for song in songs:
        csvstr += song.csv() + '\n'
    return csvstr

def main(argv):
    if (len(argv) > 1):
        path = argv[1]

        songs = []
        songfile_exts = [".sm", ".ssc", ".dwi"]
        parsed_songfiles = []
        for root, subdirs, files in os.walk(path):
            songfiles = [f for f in files if os.path.splitext(f)[1] in songfile_exts]
            for songfile in songfiles:
                songfile_name = os.path.splitext(songfile)[0]
                if (songfile_name not in parsed_songfiles):
                    songfile_path = os.path.join(root, songfile)
                    song = SMSong(songfile_path)
                    songs.append(song)
                    parsed_songfiles.append(songfile_name)

        csv = generate_csv(songs)
        print >> sys.stdout, csv
    else:
        print("Usage: {} <path_to_songpack>".format(os.path.basename(argv[0])))

if (__name__ == "__main__"):
    sys.exit(main(sys.argv))