Archived from groups: alt.games.mame (
More info?)
This is a pretty good suggestion, but what I finally
ended up doing is writing a Python script to make subsets for me.
All I needed was the game list XML dump from MAME:
xmame -listxml
My script reads the XML list and creates an index of file names
and sizes sorted by the year the game was published.
Then the script copies the ROMs and extra files (snap, flyers,
samples, etc) to a target directory until all of the file sizes add up
to the given target size. In my case, I choose 600 MB since that
will fit on a 650MB CDR with plenty of extra for MAME32.
In case anyone else finds themselves needing to do something similar
I am attaching the script here. If you know Python it should be
easy to modify to do other MAME housekeeping chores.
Thanks for the help!
Yours,
Noah Spurrier
<pre>
#######################################################################
# This script scans a ROM path and copies ROMs based on rules.
# In this case, we select ROMs ordered by year util
# a given total target size is filled.
# Noah Spurrier 2005
# No copyright. Public Domain.
from xml.dom import pulldom
import csv, stat, os, shutil
MEGABYTE = 1048576
TARGET_SIZE = 600 * MEGABYTE
GAMELIST_XML = "gamelist.xml"
SOURCE_ROM_PATH = r"C:\roms"
SOURCE_SAMPLE_PATH = r"C:\mame_extras_95\samples"
SOURCE_SNAP_PATH = r"C:\mame_extras_95\snap"
SOURCE_ARTWORK_PATH = r"C:\mame_extras_95\artwork"
SOURCE_CABINETS_PATH = r"C:\mame_extras_95\cabinets"
SOURCE_FLYERS_PATH = r"C:\mame_extras_95\flyers"
TARGET_ROM_PATH = r"C:\mame\roms"
TARGET_SAMPLE_PATH = r"C:\mame\samples"
TARGET_SNAP_PATH = r"C:\mame\snap"
TARGET_ARTWORK_PATH = r"C:\mame\artwork"
TARGET_CABINETS_PATH = r"C:\mame\cabinets"
TARGET_FLYERS_PATH = r"C:\mame\flyers"
#######################################################################
def get_text (nodelist):
"""This returns all the text data from an XML element."""
rc = ""
for node in nodelist:
if node.nodeType == node.TEXT_NODE:
rc = rc + node.data
return rc
def file_size (filepath):
"""This returns the size of the file. This is a wrapper
around os.stat. Any OS error returns -1."""
try:
return os.stat (filepath)[stat.ST_SIZE]
except OSError:
return -1
def dir_size (top):
"""This returns the size of a directory and all files in it."""
size = 0
for (dirpath, dirnames, filenames) in os.walk (top):
for filename in filenames:
size = size + file_size (os.path.join (dirpath, filename))
return size
#######################################################################
# The real work starts here.
#
# Parse the gamelist XML to build up a database of rom names and sizes.
# Also build an index of games by year.
#
db = {}
year_index = {}
xml_file = open(GAMELIST_XML, "rb")
events = pulldom.parse(xml_file)
count = 0
for (event, node) in events:
if event == pulldom.START_ELEMENT:
if node.tagName == "game":
count = count + 1
name = node.getAttribute("name")
romof = node.getAttribute("romof")
size = file_size (os.path.join (SOURCE_ROM_PATH, name +
".zip"))
events.expandNode(node)
try:
year =
get_text(node.getElementsByTagName("year")[0].childNodes)
except:
# Some game nodes don't have <year> for some reason...
year = None
db[name] = dict (romof=romof, year=year, size=size)
if year is not None:
if year not in year_index:
year_index[year] = [name]
else:
year_index[year].append(name)
#
# Copy each game in order of year until the target size is reached.
# This copies roms, samples, artwork, cabinets, flyers, and snaps.
#
total_size = 0
count = 0
years = year_index.keys()
years.sort()
for year in years:
if total_size >= TARGET_SIZE:
break
for name in year_index[year]:
if db[name]['size'] > 0 and total_size <= TARGET_SIZE:
# Copy the ROM and all the extras.
total_size = total_size + db[name]['size']
shutil.copyfile (os.path.join (SOURCE_ROM_PATH, name +
".zip"), os.path.join (TARGET_ROM_PATH, name + ".zip"))
if os.path.isdir(os.path.join (SOURCE_SAMPLE_PATH, name)):
shutil.copytree(os.path.join (SOURCE_SAMPLE_PATH,
name), os.path.join (TARGET_SAMPLE_PATH, name))
total_size = total_size + dir_size (os.path.join
(SOURCE_SAMPLE_PATH, name))
if os.path.isdir(os.path.join (SOURCE_ARTWORK_PATH, name)):
shutil.copytree(os.path.join (SOURCE_ARTWORK_PATH,
name), os.path.join (TARGET_ARTWORK_PATH, name))
total_size = total_size + dir_size (os.path.join
(SOURCE_ARTWORK_PATH, name))
if os.path.isfile(os.path.join (SOURCE_CABINETS_PATH, name
+ ".png")):
shutil.copyfile (os.path.join (SOURCE_CABINETS_PATH,
name + ".png"), os.path.join (TARGET_CABINETS_PATH, name + ".png"))
total_size = total_size + file_size (os.path.join
(SOURCE_CABINETS_PATH, name + ".png"))
if os.path.isfile(os.path.join (SOURCE_FLYERS_PATH, name +
".png")):
shutil.copyfile (os.path.join (SOURCE_FLYERS_PATH, name
+ ".png"), os.path.join (TARGET_FLYERS_PATH, name + ".png"))
total_size = total_size + file_size (os.path.join
(SOURCE_FLYERS_PATH, name + ".png"))
if os.path.isfile(os.path.join (SOURCE_SNAP_PATH, name +
".png")):
shutil.copyfile (os.path.join (SOURCE_SNAP_PATH, name +
".png"), os.path.join (TARGET_SNAP_PATH, name + ".png"))
total_size = total_size + file_size (os.path.join
(SOURCE_SNAP_PATH, name + ".png"))
print name, "-", year, "-", total_size, "BYTES - ",
total_size/float(MEGABYTE), "MB"
count = count + 1
print "Total ROMs copied:", count
### END OF SCRIPT #####################################################
</pre>