Skip to content

Commit 8532538

Browse files
committed
Readers now return the data and are documented.
Instead of building the replay structure, readers now return the data to the caller. This is a more practical and traditional approach. Now readers don't currently use the replay that gets passed in. Perhaps they will still need the replay options in the future but the call signature might need changing. Addtionally, the commenting is mostly complete for the readers file as well. Now that __init__.py and readers.py are more or less complete (aside from the ever pressent TODO's) work will focus on finishing up and documenting the processors layer of sc2reader.
1 parent feea037 commit 8532538

File tree

2 files changed

+132
-61
lines changed

2 files changed

+132
-61
lines changed

sc2reader/__init__.py

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import config
3030
import objects
3131
import utils
32+
import exceptions
3233

3334

3435
class Reader(object):
@@ -38,16 +39,16 @@ class accepts a key=value list of options to override defaults (see
3839
orchestrates the replay build process.
3940
"""
4041

41-
4242
def __init__(self, **user_options):
4343
""" The constructor makes a copy of the default_options to make sure the
4444
option configuration doesn't propogate back to the default_options.
4545
It should support any arbitrary number of different Reader objects.
4646
"""
4747
self.options = config.default_options.copy()
48+
self.sys = utils.AttributeDict()
4849
self.configure(**user_options)
4950

50-
def configure(self,**options):
51+
def configure(self, **options):
5152
self.options.update(options)
5253

5354
# Depending on the options choosen, the system needs to update related
@@ -68,7 +69,7 @@ def read(self, location, **user_options):
6869
# to a location other than the present working directory by joining the
6970
# location with the directory of their choice.
7071
if options.directory:
71-
location = os.path.join(options.directory,location)
72+
location = os.path.join(options.directory, location)
7273

7374
# When passed a directory as the location, the Reader recursively builds
7475
# a list of replays to return using the utils.get_files function. This
@@ -79,12 +80,12 @@ def read(self, location, **user_options):
7980
# * incldue_regex: A regular expression rule which all returned file
8081
# names must match. Defaults to None
8182
#
82-
replays, files = list(), utils.get_files(location,**options)
83+
replays, files = list(), utils.get_files(location, **options)
8384

8485
# If no files are found, it could be for a variety of reasons
8586
# raise a NoMatchingFilesError to alert them to the situation
8687
if not files:
87-
raise NoMatchingFilesError()
88+
raise exceptions.NoMatchingFilesError()
8889

8990
for location in files:
9091
if options.verbose: print "Reading: %s" % location
@@ -93,7 +94,7 @@ def read(self, location, **user_options):
9394
# The Replay constructor scans the header of the replay file for
9495
# the build number and stores the options for later use. The
9596
# options are copied so subsequent option changes are isolated.
96-
replay = objects.Replay(replay_file,**options.copy())
97+
replay = objects.Replay(replay_file, **options.copy())
9798

9899
# .SC2Replay files are written in Blizzard's MPQ Archive format.
99100
# The format stores a header which contains a block table that
@@ -103,7 +104,7 @@ def read(self, location, **user_options):
103104
# add messages promoting their sites without updating the header
104105
# correctly. The listfile option(hack) lets us bypass this issue
105106
# by specifying the files we want instead of generating a list.
106-
archive = mpyq.MPQArchive(location,listfile=False)
107+
archive = mpyq.MPQArchive(location, listfile=False)
107108

108109
# These files are configured for either full or partial parsing
109110
for file in self.sys.files:
@@ -123,10 +124,13 @@ def read(self, location, **user_options):
123124
# Readers use the type agnostic __call__ interface so that
124125
# they can be implemented as functions or classes as needed.
125126
#
126-
# Readers store the extracted information into the replay
127-
# object for post processing because correct interpretation
128-
# of the information often requires data from other files.
129-
config.readers[replay.build][file].__call__(buffer,replay)
127+
# Readers return the extracted information from the buffer
128+
# object which gets stored into the raw data dict for later
129+
# use in post processing because correct interpretation of
130+
# the information often requires data from other files.
131+
reader = config.readers[replay.build][file]
132+
reference_name = '_'.join(file.split('.')[1:])
133+
replay.raw[reference_name] = reader(buffer, replay)
130134

131135
# Now that the replay has been loaded with the "raw" data from
132136
# the archive files we run the system level post processors to
@@ -146,13 +150,13 @@ def read(self, location, **user_options):
146150

147151
return replays
148152

149-
def read_file(file,**options):
150-
replays = self.read(file,**options)
153+
def read_file(self, file, **options):
154+
replays = self.read(file, **options)
151155

152156
# While normal usage would suggest passing in only filenames, it is
153157
# possible that directories could be passed in. Don't fail silently!
154158
if len(replays) > 1:
155-
raise MultipleMatchError(replays)
159+
raise exceptions.MultipleMatchingFilesError(replays)
156160

157161
# Propogate the replay in a singular context
158162
return replays[0] if len(replays) > 0 else None
@@ -164,7 +168,7 @@ def read_file(file,**options):
164168
__defaultReader = Reader()
165169

166170
def read(location, **user_options):
167-
return __defaultReader.read(location,**user_options)
171+
return __defaultReader.read(location, **user_options)
168172

169173
def configure(**options):
170174
config.default_options.update(options)

0 commit comments

Comments
 (0)