| Home > Dive Into Python > An Object-Oriented Framework | << >> |
| diveintopython.org | |
| Python for experienced programmers | |
Table of Contents
This chapter, and pretty much every chapter after this, deals with object-oriented Python programming. Remember when I said you should know an object-oriented language to read this book? Well, I wasn't kidding.
Here is a complete, working Python program. Read the doc strings to get an overview of what it does and how it works. As usual, don't worry about the stuff you don't understand; that's what the rest of the chapter is for.
"""Framework for getting file information, including filetype-specific metadata.
Instantiate appropriate class with filename to get metadata. Returned object
acts just like a dictionary, with key-value pairs for each piece of metadata.
import fileinfo
info = fileinfo.MP3FileInfo("/music/ap/mahadeva.mp3")
print "\\n".join(["%s=%s" % (k, info[k]) for k in info.keys()])
Or use listDirectory function to get info on all files in a directory.
infoList = fileinfo.listDirectory("/music/ap/", [".mp3"])
for info in infoList:
...
Framework can be extended by adding classes for particular file types, e.g.
HTMLFileInfo, MPGFileInfo, DOCFileInfo. Each class is completely responsible for
parsing its files appropriately; see MP3FileInfo for example.
"""
import os
from UserDict import UserDict
class FileInfo(UserDict):
"base class for file info"
def __init__(self, filename=None):
UserDict.__init__(self)
self["name"] = filename
class MP3FileInfo(FileInfo):
"class for MP3 file info, including ID3v1.0 tags if found"
def __normalize(self, data):
"strip whitespace and nulls"
return data.replace("\00", " ").strip()
def __parse(self, filename):
"parse ID3v1.0 tags from MP3 file"
self.clear()
try:
fsock = open(filename, "rb", 0)
try:
fsock.seek(-128, 2)
tagdata = fsock.read(128)
finally:
fsock.close()
if tagdata[:3] == 'TAG':
self["title"] = self.__normalize(tagdata[3:33])
self["artist"] = self.__normalize(tagdata[33:63])
self["album"] = self.__normalize(tagdata[63:93])
self["year"] = self.__normalize(tagdata[93:97])
self["comment"] = self.__normalize(tagdata[97:126])
self["genre"] = ord(tagdata[127])
except IOError:
pass
def __setitem__(self, key, item):
if key == "name" and item:
self.__parse(item)
FileInfo.__setitem__(self, key, item)
def __getFileInfoObjectClass(filename):
"get file info class from filename extension, returns class"
subclass = "%sFileInfo" % os.path.splitext(filename)[1].upper()[1:]
if globals().has_key(subclass):
return eval(subclass)
else:
return FileInfo
def listDirectory(directory, fileExtList):
"return list of file info objects for files of particular extensions"
fileExtList = [ext.upper() for ext in fileExtList]
fileList = [os.path.join(directory, f) for f in os.listdir(directory) \
if os.path.splitext(f)[1].upper() in fileExtList]
return [__getFileInfoObjectClass(f)(f) for f in fileList]
if __name__ == "__main__":
for info in listDirectory("/music/_singles/", [".mp3"]):
for key, value in info.items():
print "%s=%s" % (key, value)
print| This program's output depends on the files on your hard drive. To get meaningful output, you'll have to change the directory path to point to a directory of MP3 files on your own machine. |
Example 3.2. Output of fileinfo.py
This was the output I got on my machine. Your output will be different, unless, by some startling coincidence, you share my exact taste in music.
album= artist=Ghost in the Machine title=A Time Long Forgotten (Concept genre=31 name=/music/_singles/a_time_long_forgotten_con.mp3 year=1999 comment=http://mp3.com/ghostmachine album=Rave Mix artist=***DJ MARY-JANE*** title=HELLRAISER****Trance from Hell genre=31 name=/music/_singles/hellraiser.mp3 year=2000 comment=http://mp3.com/DJMARYJANE album=Rave Mix artist=***DJ MARY-JANE*** title=KAIRO****THE BEST GOA genre=31 name=/music/_singles/kairo.mp3 year=2000 comment=http://mp3.com/DJMARYJANE album=Journeys artist=Masters of Balance title=Long Way Home genre=31 name=/music/_singles/long_way_home1.mp3 year=2000 comment=http://mp3.com/MastersofBalan album= artist=The Cynic Project title=Sidewinder genre=18 name=/music/_singles/sidewinder.mp3 year=2000 comment=http://mp3.com/cynicproject album=Digitosis@128k artist=VXpanded title=Spinning genre=255 name=/music/_singles/spinning.mp3 year=2000 comment=http://mp3.com/artists/95/vxp
| « Summary | A brief review » |