11import os
22
33from mpyq import MPQArchive
4- from config import DefaultConfig
4+ import config
5+ from objects import Replay
56from utils import ReplayBuffer , LITTLE_ENDIAN
67
78def read_header (file ):
@@ -22,42 +23,73 @@ def read_header(file):
2223
2324 #return the release and frames information
2425 return data [1 ],data [3 ]
26+
27+ class SC2Reader (object ):
28+
29+ def __init__ (self , parse = config .FULL , directory = "" , processors = [], debug = False , files = None ):
30+ #Check that arguments are consistent with expectations up front
31+ #Easier to debug issues this way
32+ if parse == config .FULL :
33+ files = config .FILES_FULL
34+ processors = config .PROCESSORS_FULL + processors
35+ elif parse == config .PARTIAL :
36+ files = config .FILES_PARTIAL
37+ processors = config .PROCESSORS_PARTIAL + processors
38+ elif parse == config .CUSTOM :
39+ if not files :
40+ raise ValueError ("Custom parsing requires specification the files arguments" )
41+ else :
42+ raise ValueError ("parse must be either FULL, PARTIAL, or CUSTOM" )
43+
44+ #Update the class configuration
45+ self .__dict__ .update (locals ())
2546
26- def read (location ,config = DefaultConfig ()):
27- if not os .path .exists (location ):
28- raise ValueError ("Location must exist" )
29-
30- if os .path .isdir (location ):
31- replays = list ()
32- for location in os .list_files (location ):
33- replays .extend (read (location ,config ))
34- return replays
35- else :
36- return read_file (location ,config )
37-
38- def read_file (filename ,config = DefaultConfig ()):
39- if (os .path .splitext (filename )[1 ].lower () != '.sc2replay' ):
40- raise TypeError ("Target file must of the SC2Replay file extension" )
41-
42- with open (filename ) as replay_file :
43- release ,frames = read_header (replay_file )
44- replay = config .ReplayClass (filename ,release ,frames )
45- archive = MPQArchive (filename ,listfile = False )
47+ def read (self , location ):
48+ #account for the directory option
49+ location = os .path .join (self .directory ,location )
4650
47- #Extract and Parse the relevant files
48- for file ,readers in config .readers .iteritems ():
49- for reader in readers :
50- if reader .reads (replay .build ):
51- reader .read (ReplayBuffer (archive .read_file (file )),replay )
52- break
53- else :
54- raise NotYetImplementedError ("No parser was found that accepted the replay file;check configuration" )
55-
56- #Do cleanup and post processing
57- for processor in config .processors :
58- replay = processor .process (replay )
51+ if not os .path .exists (location ):
52+ raise ValueError ("Location must exist" )
53+
54+ #If its a directory, read each subfile/directory and combine the lists
55+ if os .path .isdir (location ):
56+ return sum (map (self .read , os .list_files (location )),[])
5957
60- return replay
58+ #The primary replay reading routine
59+ else :
60+ if (os .path .splitext (location )[1 ].lower () != '.sc2replay' ):
61+ raise TypeError ("Target file must of the SC2Replay file extension" )
62+
63+ with open (location ) as replay_file :
64+ #Use the MPQ Header information to initialize the replay
65+ release ,frames = read_header (replay_file )
66+ replay = Replay (location ,release ,frames )
67+ archive = MPQArchive (location ,listfile = False )
68+
69+ #Extract and Parse the relevant files based on parse level
70+ for file ,readers in config .READERS .iteritems ():
71+ if file in self .files :
72+ for reader in readers :
73+ if reader .reads (replay .build ):
74+ reader .read (ReplayBuffer (archive .read_file (file )),replay )
75+ break
76+ else :
77+ raise NotYetImplementedError ("No parser was found that accepted the replay file;check configuration" )
78+
79+ #Do cleanup and post processing
80+ for processor in self .processors :
81+ replay = processor .process (replay )
82+
83+ return replay
84+
85+ #Prepare the lightweight interface
86+ __defaultSC2Reader = SC2Reader ()
87+
88+ def configure (parse = config .FULL , directory = None , processors = [], debug = False , files = None ):
89+ __defaultSC2Reader .__dict__ .update (locals ())
90+
91+ def read (location ):
92+ return __defaultSC2Reader .read (location )
6193
62- __all__ = [DefaultConfig , read ,read_file ]
63- __version__ = "0.1 .0"
94+ __all__ = [read ,config , SC2Reader ]
95+ __version__ = "0.3 .0"
0 commit comments