def test_datetimes(): # Ignore seconds in comparisons, because they are off by one what is reported by Windows. # This might be a little nuance worth investigating at some point. # Played at 20 Feb 2011 22:44:48 UTC+2 replay = sc2reader.read_file("test_replays/1.2.2.17811/1.SC2Replay") assert replay.utc_date == datetime.datetime(2011, 2, 20, 20, 44, 47) # Played at 21 Feb 2011 00:42:13 UTC+2 replay = sc2reader.read_file("test_replays/1.2.2.17811/2.SC2Replay") assert replay.utc_date == datetime.datetime(2011, 2, 20, 22, 42, 12) # Played at 25 Feb 2011 16:36:28 UTC+2 replay = sc2reader.read_file("test_replays/1.2.2.17811/3.SC2Replay") assert replay.utc_date == datetime.datetime(2011, 2, 25, 14, 36, 26)
def test_3v3(): replay = sc2reader.read_file("test_replays/1.2.2.17811/3.SC2Replay") assert replay.type == "3v3" # Because it's a 3v3 and all of the members of Team 2 quit, we should know the winner. assert replay.team[1].result == "Win" assert replay.team[2].result == "Loss"
def test_ffa(): replay = sc2reader.read_file("test_replays/1.2.2.17811/8.SC2Replay") assert replay.type == "FFA" # Player 'Boom' won because the last building of the last player was destroyed, # but the winner cannot be parsed because "Player has left" event isn't generated. # Unknown result is the best we can do. assert replay.winner_known == False
def replay_detail(replay_url): # download replay # tempRep = urllib.urlretrieve(replay_url) # shutil.move(tempRep[0], tempRep[0] + ".sc2replay") # md5 = hashlib.md5() # f = open(tempRep[0] + ".sc2replay", 'rb') f = open(replay_url + ".sc2replay", "rb") for chunk in iter(lambda: f.read(8192), ""): md5.update(chunk) replay_key = str(md5.hexdigest()) replay = sc2reader.read_file(replay_url + ".sc2replay") # determine which map we're on chksum = "" for entry in replay.raw["initData"]["map_data"]: chksum = chksum + str(entry)[52 : len(str(entry)) - 2] maps = open("static/maps.json") all_maps = json.load(maps) for m in all_maps: if all_maps[m]["checksum"] == chksum: replay_map = m # Build event lists p1locations = list() p2locations = list() for event in replay.events: try: if str(event.player)[7] == str(1): p1locations.append(event.location) if str(event.player)[7] == "2": p2locations.append(event.location) except: pass mediapath = "./static/img" # grab minimap minimap = Image.open(mediapath + all_maps[replay_map]["filename"]) minimap = minimap.convert("RGBA") # run heatmap code hm = heatmap.Heatmap() hm.heatmap( p1locations, mediapath + replay_key + ".tmp.png", range=(replay_map.sizeX, replay_map.sizeY), dotsize=50, size=minimap.size, ) heat = Image.open(mediapath + replay_key + ".tmp.png") # heat = heat.resize(minimap.size) out = Image.blend(minimap, heat, 0.5) out.save(mediapath + replay_key + ".jpg")
def doFile(filename, arguments): '''Prints summary information about SC2 replay file''' try: replay = sc2reader.read_file(filename, debug=True) except ReadError as e: prev = e.game_events[-1] print "\nVersion {0} replay:\n\t{1}".format(e.replay.release_string, e.replay.filename) print "\t{0}, Type={1:X}, Code={2:X}".format(e.msg, e.type, e.code) print "\tPrevious Event: {0}".format(prev.name) print "\t\t" + prev.bytes.encode('hex') print "\tFollowing Bytes:" print "\t\t" + e.buffer.read_range(e.location, e.location + 30).encode('hex') print "Error with '{0}': ".format(filename) print e return except TypeError as e: print "Error with '%s': " % filename, print e return except ValueError as e: print "Error with '%s': " % filename, print e return if arguments.map: print " Map: {0}".format(replay.map) if arguments.length: print " Length: {0}".format(replay.length) if arguments.date: print " Date: {0}".format(replay.date) if arguments.teams: races = list() for team in replay.teams: races.append(''.join( [player.pick_race[0] for player in team.players])) print " Teams: {0}".format("v".join(races)) for team in replay.teams: print " Team {0}\t{1} ({2})".format( team.number, team.players[0].name, team.players[0].pick_race[0]) for player in team.players[1:]: print " \t{0} ({1})".format( player.name, player.pick_race[0]) if arguments.messages: print " Messages:" for message in replay.messages: print " {0}".format(message) if arguments.version: print " Version: {0}".format(replay.release_string) print
def doFile(filename, arguments): '''Prints summary information about SC2 replay file''' try: replay = sc2reader.read_file(filename, debug=True, processors=[Macro]) except ReadError as e: prev = e.game_events[-1] print "\nVersion {0} replay:\n\t{1}".format(e.replay.release_string, e.replay.filename) print "\t{0}, Type={1:X}, Code={2:X}".format(e.msg, e.type,e.code) print "\tPrevious Event: {0}".format(prev.name) print "\t\t"+prev.bytes.encode('hex') print "\tFollowing Bytes:" print "\t\t"+e.buffer.read_range(e.location,e.location+30).encode('hex') print "Error with '{0}': ".format(filename) print e return except TypeError as e: print "Error with '%s': " % filename, print e return except ValueError as e: print "Error with '%s': " % filename, print e return if arguments.map: print " Map: {0}".format(replay.map) print " Ladder: {0}".format(replay.is_ladder) print " Length: {0}".format(replay.length) if arguments.date: print " Date: {0}".format(replay.date) if arguments.teams: races = list() for team in replay.teams: races.append(''.join([player.pick_race[0] for player in team.players])) print " Teams: {0}".format("v".join(races)) for team in replay.teams: print " Team {0}\t{1} ({2}, apm {3:.1f} wpm {4:.1f} {5})".format(team.number,team.players[0].name,team.players[0].pick_race[0],team.players[0].avg_apm,team.players[0].wpm,team.result) for player in team.players[1:]: print " \t{0} ({1}, apm {2:.1f} wpm {3:.1f})".format(player.name,player.pick_race[0],player.avg_apm,player.wpm) for player in team.players: print player.result if arguments.messages: print " Messages:" for message in replay.messages: print " {0}".format(message) if arguments.version: print " Version: {0}".format(replay.release_string) # print replay.results # for event in replay.events: # print event print
def replay_detail(): # download replay replay_url = request.form["replay"] tempRep = urllib.urlretrieve(replay_url) shutil.move(tempRep[0], tempRep[0] + ".sc2replay") md5 = hashlib.md5() f = open(tempRep[0] + ".sc2replay", 'rb') for chunk in iter(lambda: f.read(8192), ''): md5.update(chunk) replay_key = str(md5.hexdigest()) replay = sc2reader.read_file(tempRep[0] + ".sc2replay") # determine which map we're on chksum = "" for entry in replay.raw["initData"]["map_data"]: chksum = chksum + str(entry)[52:len(str(entry))-2] maps = open('static/maps.json') all_maps = json.load(maps) for m in all_maps: if(all_maps[m]['checksum'] == chksum): replay_map = m # Build event lists p1locations = list() p2locations = list() for event in replay.events: try: if (str(event.player)[7] == str(1)): p1locations.append(event.location) if (str(event.player)[7] == '2'): p2locations.append(event.location) except: pass mediapath = './static/img' # grab minimap minimap = Image.open(mediapath + replay_map.minimap) minimap = minimap.convert("RGBA") # run heatmap code hm = heatmap.Heatmap() hm.heatmap(p1locations, mediapath + replay_key + '.tmp.png', range=(replay_map.sizeX, replay_map.sizeY), dotsize=50, size=minimap.size) heat = Image.open(mediapath + replay_key + '.tmp.png') # heat = heat.resize(minimap.size) out = Image.blend(minimap, heat, 0.5) out.save( mediapath + replay_key + '.jpg') return render_template('heatmap/replay.html', {'map': replay_map, 'replay_key': replay_key})
def main(): args = parse_args() db = load_session(args) for path in args.paths: for file_name in sc2reader.utils.get_files(path, depth=0): print "CREATING: {0}".format(file_name) db.add(Game(sc2reader.read_file(file_name), db)) db.commit() print list(db.query(distinct(Person.name)).all())
def main(): args = parse_args() db = load_session(args) for path in args.paths: for file_name in sc2reader.utils.get_files(path, depth=0): print("CREATING: {0}".format(file_name)) db.add(Game(sc2reader.read_file(file_name), db)) db.commit() print(list(db.query(distinct(Person.name)).all()))
def test_kr_realm_and_tampered_messages(): replay = sc2reader.read_file("test_replays/1.1.3.16939/11.SC2Replay") assert replay.person['명지대학교'].url == "http://kr.battle.net/sc2/en/profile/258945/1/명지대학교/" assert replay.person['티에스엘사기수'].url == "http://kr.battle.net/sc2/en/profile/102472/1/티에스엘사기수/" assert replay.messages[0].text == "sc2.replays.net" assert replay.messages[5].text == "sc2.replays.net" print replay.players[1].pick_race print replay.players[1].play_race print replay.players[0].pick_race print replay.players[0].play_race print replay.map
def main(): args = get_args() for filename in sc2reader.utils.get_files(args.FILE): replay = sc2reader.read_file(filename, debug=True) print "Release {0}".format(replay.release_string) print "{0} on {1}".format(replay.type, replay.map) for player in replay.players: print player print "\n--------------------------\n\n" # Allow picking of the player to 'watch' if args.player: events = replay.player[args.player].events else: events = replay.events # Loop through the events data = sc2reader.config.build_data[replay.build] for event in events: try: event.apply(data) except ValueError as e: if str(e) == "Using invalid abilitiy matchup.": myGetch() else: raise e # Use their options to filter the event stream if ( isinstance(event, AbilityEvent) or isinstance(event, SelectionEvent) or isinstance(event, PlayerJoinEvent) or isinstance(event, PlayerLeaveEvent) or isinstance(event, GameStartEvent) or (args.hotkeys and isinstance(event, HotkeyEvent)) or (args.cameras and isinstance(event, CameraEvent)) ): """ if isinstance(event, SelectionEvent) or isinstance(event, HotkeyEvent): """ print event # myGetch() if args.bytes: print "\t" + event.bytes.encode("hex") if re.search("UNKNOWN|ERROR", str(event)): myGetch()
def replay(request): replay_query = Replays.objects.filter(id__icontains=id) replay_file = replay_query.id sc2reader_file = sc2reader.read_file(replay_file) gametime = r.length gamedate = r.date gamemap = r.map player1 = r.player[1].name player2 = r.player[2].name p1bneturl = r.player[1].url p2bneturl = r.player[2].url p1race = r.player[1].play_race p2race = r.player[2].play_race p1result = r.player[1].result p2result = r.player[2].result
def main(): args = get_args() for filename in sc2reader.utils.get_files(args.FILE): replay = sc2reader.read_file(filename,debug=True) print "Release {0}".format(replay.release_string) print "{0} on {1}".format(replay.type,replay.map) for player in replay.players: print player print "\n--------------------------\n\n" # Allow picking of the player to 'watch' if args.player: events = replay.player[args.player].events else: events = replay.events # Loop through the events data = sc2reader.config.build_data[replay.build] for event in events: try: event.apply(data) except ValueError as e: if str(e) == "Using invalid ability matchup.": myGetch() else: raise e # Use their options to filter the event stream if isinstance(event,AbilityEvent) or\ isinstance(event,SelectionEvent) or\ isinstance(event,PlayerJoinEvent) or\ isinstance(event, PlayerLeaveEvent) or\ isinstance(event,GameStartEvent) or\ (args.hotkeys and isinstance(event,HotkeyEvent)) or\ (args.cameras and isinstance(event,CameraEvent)): ''' if isinstance(event, SelectionEvent) or isinstance(event, HotkeyEvent): ''' print event #myGetch() if args.bytes: print "\t"+event.bytes.encode('hex') if re.search('UNKNOWN|ERROR', str(event)): myGetch()
def doFile(filename, arguments): '''Prints all events in SC2 replay file''' try: replay = sc2reader.read_file(filename, debug=True) # replay = sc2reader.read_file(filename, debug=True, apply=True) except ReadError as e: prev = e.game_events[-1] print "\nVersion {0} replay:\n\t{1}".format(e.replay.release_string, e.replay.filename) print "\t{0}, Type={1:X}, Code={2:X}".format(e.msg, e.type,e.code) print "\tPrevious Event: {0}".format(prev.name) print "\t\t"+prev.bytes.encode('hex') print "\tFollowing Bytes:" print "\t\t"+e.buffer.read_range(e.location,e.location+30).encode('hex') print "Error with '{0}': ".format(filename) print e return except TypeError as e: print "Error with '%s': " % filename, print e return except ValueError as e: print "Error with '%s': " % filename, print e return data = sc2reader.config.build_data[replay.build] print data if hasattr(arguments, "n"): events_to_print = replay.events[1:arguments.n] else: events_to_print = replay.events for event in events_to_print: event.apply(data) print event, binascii.hexlify(event.bytes) print
def doFile(filename, arguments): """Prints all events in SC2 replay file""" try: replay = sc2reader.read_file(filename, debug=True) # replay = sc2reader.read_file(filename, debug=True, apply=True) except ReadError as e: prev = e.game_events[-1] print "\nVersion {0} replay:\n\t{1}".format(e.replay.release_string, e.replay.filename) print "\t{0}, Type={1:X}, Code={2:X}".format(e.msg, e.type, e.code) print "\tPrevious Event: {0}".format(prev.name) print "\t\t" + prev.bytes.encode("hex") print "\tFollowing Bytes:" print "\t\t" + e.buffer.read_range(e.location, e.location + 30).encode("hex") print "Error with '{0}': ".format(filename) print e return except TypeError as e: print "Error with '%s': " % filename, print e return except ValueError as e: print "Error with '%s': " % filename, print e return data = sc2reader.config.build_data[replay.build] print data if hasattr(arguments, "n"): events_to_print = replay.events[1 : arguments.n] else: events_to_print = replay.events for event in events_to_print: event.apply(data) print event, binascii.hexlify(event.bytes) print
def buildjson(): checksums = list() files = os.listdir(".") print "{" for f in files: n = f.split(".") if len(n) > 1 and n[1] == "sc2replay": replay = sc2reader.read_file(f) chksum = "" for entry in replay.raw["initData"]["map_data"]: chksum = chksum + str(entry)[52 : len(str(entry)) - 2] md5 = hashlib.md5() md5.update(chksum) chksum = md5.hexdigest() if chksum not in checksums: checksums.append(chksum) print "\t" + "'" + replay.map + '":' print "\t" "{" print "\t\t" + '"size" : ' + '"xxx.xxx",' print "\t\t" + " : " + '"' + chksum + '",' print "\t" + "}," print "" print "}"
def replay_details(request, id): page_name = request.path try: id = int(id) except ValueError: replays_list = Replays.objects.all() return render_to_response('replays_list.html', {'replays_list': replays_list, 'page_name': page_name}) replay_query = Replays.objects.get(id=id) replay_file = replay_query.file r = sc2reader.read_file(replay_file) gametime = replay_query.game_length # gamedate = r.date gamemap = replay_query.map_name player1 = r.player[1].name player2 = r.player[2].name p1bneturl = r.player[1].url p2bneturl = r.player[2].url p1race = r.player[1].play_race p2race = r.player[2].play_race p1result = r.player[1].result p2result = r.player[2].result return render_to_response('replay_details.html', locals())
#! /usr/bin/env python import MySQLdb import sc2reader # import os replay_array = sc2reader.read_file("/home/mbedford/replays/AutoMM/test", verbose=True) num_replays = len(replay_array) filename = replay_file.filename # filename = filename.replace(' ', '-') #filename = "1" player1 = replay_file.players[0].name p1_race = replay_file.players[0].play_race player2 = replay_file.players[1].name p2_race = replay_file.players[1].play_race map = replay_file.map date_played = replay_file.date # Format game length if replay_file.length.hours: game_hours = "%sh" % replay_file.length.hours else: game_hours = "" if replay_file.length.mins: game_mins = "%sm" % replay_file.length.mins else: game_mins = "" if replay_file.length.secs: game_secs = "%ss" % replay_file.length.secs
def parse_replay(session, DBPlayer, replay_id): r = session.query(DBReplay).get(replay_id) print "Parsing " + str(r.id) if r: base_path = "../files/replays/" file_path = base_path + r.file try: print "Opening replay file" replay = sc2reader.read_file(file_path) if replay is None: print "None :()" raise print "Done opening replay file" r.saved_at = replay.utc_date r.map_name = unicode(replay.map, "utf-8") r.game_format = replay.type.lower() r.gateway = replay.gateway.upper() r.version = replay.release_string r.game_speed = replay.speed r.game_length = str(to_real_time(r.game_speed, replay.seconds)) r.game_type = replay.category r.zergs = r.protosses = r.terrans = 0 if r.gateway != "XX": for player in replay.players: if player.type == "Human": p = find_or_create_player(session, DBPlayer, player, replay.utc_date) play = DBPlay() play.player_id = p.id play.replay_id = r.id play.pid = player.pid play.chosen_race = player.pick_race[0].upper() play.race = player.play_race[0].upper() if play.race == 'Z': r.zergs = r.zergs + 1 if play.race == 'T': r.terrans = r.terrans + 1 if play.race == 'P': r.protosses = r.protosses + 1 play.color = "#" + player.color.hex play.avg_apm = to_real_time(r.game_speed, player.avg_apm) play.won = (player.result == "Win") if play.won: r.winner_known = True play.team = player.team.number play.player_type = player.type play.difficulty = player.difficulty # apm = dict() # for i in range(0, replay.seconds/60): # apm[i] = "0" # for minute, actions in player.apm.iteritems(): # apm[minute] = str(actions) # # play.apm = ','.join(apm.values()) session.add(play) msg_number = 0 for message in replay.messages: # TODO: use a more general url regexp instead # Filter certain messages if message.text == "sc2.replays.net": continue m = DBMessage() m.replay_id = r.id m.msg_order = msg_number m.sender = message.sender.name m.sender_color = "#" + message.sender.color.hex m.msg = message.text m.target = message.target m.time = message.time.seconds m.pid = message.sender.pid msg_number += 1 session.add(m) # new_file_name = "" # if replay.type == "1v1": # new_file_name = "%s_vs_%s_%s.SC2Replay" % (replay.players[0].name, replay.players[1].name, r.id) # else: # new_file_name = "%s_%s_%s.SC2Replay" % (replay.type, replay.map, r.id) # print "Renaming file" # os.rename(file_path, base_path + new_file_name) # print "Done renaming file" # print "Processing..." # r.file = unicode(new_file_name, "utf-8") r.state = 'success' session.add(r) session.commit() print "Done processing" except: print "EXCEPT" # Enable for debugging!!! raise r.state = 'failed' session.add(r) session.commit() print "Parser ended"
def test_random_player(): replay = sc2reader.read_file("test_replays/1.2.2.17811/3.SC2Replay") gogeta = replay.person['Gogeta'] assert gogeta.pick_race == "Random" assert gogeta.play_race == "Terran"
def test_us_realm(): replay = sc2reader.read_file("test_replays/1.2.2.17811/5.SC2Replay") assert replay.person['ShadesofGray'].url == "http://us.battle.net/sc2/en/profile/2358439/1/ShadesofGray/" assert replay.person['reddawn'].url == "http://us.battle.net/sc2/en/profile/2198663/1/reddawn/"
def run(args): # Reset wipes the destination clean so we can start over. if args.reset: reset(args) # Set up validates the destination and source directories. # It also loads the previous state or creates one as necessary. state = setup(args) # We break out of this loop in batch mode and on KeyboardInterrupt while True: # The file scan uses the arguments and the state to filter down to # only new (since the last sync time) files. for path in scan(args, state): try: # Read the file and expose useful aspects for renaming/filtering replay = sc2reader.read_file(path) except KeyboardInterrupt as e: raise except: # Failure to parse file_name = os.path.basename(path) directory = make_directory(args, ("parse_error",)) new_path = os.path.join(directory, file_name) source_path = path[len(args.source) :] args.log.write("Error parsing replay: {0}".format(source_path)) if not args.dryrun: args.action.run(path, new_path) # Skip to the next replay continue aspects = generate_aspects(args, replay) # Use the filter args to select files based on replay attributes if filter_out_replay(args, replay): continue # Apply the aspects to the rename formatting. #'/' is a special character for creation of subdirectories. # TODO: Handle duplicate replay names, its possible.. path_parts = args.rename.format(**aspects).split("/") filename = path_parts.pop() + ".SC2Replay" # Construct the directory and file paths; create needed directories directory = make_directory(args, path_parts) new_path = os.path.join(directory, filename) # Find the source relative to the source directory for reporting dest_path = new_path[len(args.dest) :] source_path = path[len(args.source) :] # Log the action and run it if we are live msg = "{0}:\n\tSource: {1}\n\tDest: {2}\n" args.log.write(msg.format(args.action.type, source_path, dest_path)) if not args.dryrun: args.action.run(path, new_path) # After every batch completes, save the state and flush the log # TODO: modify the state to include a list of remaining files args.log.flush() save_state(state, args) # We only run once in batch mode! if args.mode == "BATCH": break # Since new replays come in fairly infrequently, reduce system load # by sleeping for an acceptable response time before the next scan. time.sleep(args.period) args.log.write("Batch Completed")
def test_private_category(): replay = sc2reader.read_file("test_replays/1.2.2.17811/2.SC2Replay") assert replay.is_private == True assert replay.is_ladder == False
def test_observers(): replay = sc2reader.read_file("test_replays/1.2.2.17811/13.SC2Replay",debug=True)
def test_encrypted(): replay = sc2reader.read_file("test_replays/1.2.2.17811/4.SC2Replay")
def test_referee(): replay = sc2reader.read_file("test_replays/1.2.2.17811/14.SC2Replay")
def test_standard_1v1(): replay = sc2reader.read_file("test_replays/1.2.2.17811/1.SC2Replay") assert str(replay.length) == "32.47" assert replay.map == "Lost Temple" assert replay.build == 17811 assert replay.release_string == "1.2.2.17811" assert replay.speed == "Faster" assert replay.type == "1v1" assert replay.is_ladder == True assert replay.is_private == False assert len(replay.players) == 2 assert replay.person[1].name == "Emperor" assert replay.person[2].name == "Boom" emperor = replay.person['Emperor'] assert emperor.team.number == 1 assert emperor.pick_race == "Protoss" assert emperor.play_race == "Protoss" assert emperor.recorder == False boom = replay.person['Boom'] assert boom.team.number == 2 assert boom.pick_race == "Terran" assert boom.play_race == "Terran" assert boom.recorder == True for player in replay.players: assert player.type == "Human" # Because it is a 1v1 and the recording player quit, we should know the winner. assert emperor.result == "Win" assert boom.result == "Loss" assert emperor.url == "http://eu.battle.net/sc2/en/profile/520049/1/Emperor/" assert boom.url == "http://eu.battle.net/sc2/en/profile/1694745/1/Boom/" assert len(replay.messages) == 12 assert replay.messages[0].text == "hf" assert replay.messages[0].sender.name == "Emperor" assert replay.messages[1].text == "HEYA" assert replay.messages[1].sender.name == "Boom" assert replay.messages[2].text == "gl hf" assert replay.messages[2].sender.name == "Boom" assert replay.messages[3].text == "sry for caps" assert replay.messages[3].sender.name == "Boom" assert replay.messages[4].text == "^^" assert replay.messages[4].sender.name == "Emperor" assert replay.messages[5].text == "noppe" assert replay.messages[5].sender.name == "Emperor" assert replay.messages[6].text == "you greedy bastard" assert replay.messages[6].sender.name == "Boom" assert replay.messages[7].text == "ggg" assert replay.messages[7].sender.name == "Boom" assert replay.messages[8].text == "WG" assert replay.messages[8].sender.name == "Emperor" assert replay.messages[9].text == "wg? :)" assert replay.messages[9].sender.name == "Boom" assert replay.messages[10].text == "wipe" assert replay.messages[10].sender.name == "Emperor" assert replay.messages[11].text == "huh?" assert replay.messages[11].sender.name == "Boom" for msg in replay.messages: assert msg.to_all == True
def test_random_player2(): replay = sc2reader.read_file("test_replays/1.2.2.17811/6.SC2Replay") permafrost = replay.person["Permafrost"] assert permafrost.pick_race == "Random" assert permafrost.play_race == "Protoss"
def run(args): #Reset wipes the destination clean so we can start over. if args.reset: reset(args) #Set up validates the destination and source directories. #It also loads the previous state or creates one as necessary. state = setup(args) #We break out of this loop in batch mode and on KeyboardInterrupt while True: #The file scan uses the arguments and the state to filter down to #only new (since the last sync time) files. for path in scan(args, state): try: #Read the file and expose useful aspects for renaming/filtering replay = sc2reader.read_file(path) except KeyboardInterrupt as e: raise except: #Failure to parse file_name = os.path.basename(path) directory = make_directory(args, ('parse_error', )) new_path = os.path.join(directory, file_name) source_path = path[len(args.source):] args.log.write("Error parsing replay: {0}".format(source_path)) if not args.dryrun: args.action.run(path, new_path) #Skip to the next replay continue aspects = generate_aspects(args, replay) #Use the filter args to select files based on replay attributes if filter_out_replay(args, replay): continue #Apply the aspects to the rename formatting. #'/' is a special character for creation of subdirectories. #TODO: Handle duplicate replay names, its possible.. path_parts = args.rename.format(**aspects).split('/') filename = path_parts.pop() + '.SC2Replay' #Construct the directory and file paths; create needed directories directory = make_directory(args, path_parts) new_path = os.path.join(directory, filename) #Find the source relative to the source directory for reporting dest_path = new_path[len(args.dest):] source_path = path[len(args.source):] #Log the action and run it if we are live msg = "{0}:\n\tSource: {1}\n\tDest: {2}\n" args.log.write(msg.format(args.action.type, source_path, dest_path)) if not args.dryrun: args.action.run(path, new_path) #After every batch completes, save the state and flush the log #TODO: modify the state to include a list of remaining files args.log.flush() save_state(state, args) #We only run once in batch mode! if args.mode == 'BATCH': break #Since new replays come in fairly infrequently, reduce system load #by sleeping for an acceptable response time before the next scan. time.sleep(args.period) args.log.write('Batch Completed')
def test_4v4(): replay = sc2reader.read_file("test_replays/1.2.0.17326/9.SC2Replay") assert replay.type == "4v4"
def test_2v2(): replay = sc2reader.read_file("test_replays/1.2.2.17811/7.SC2Replay") assert replay.type == "2v2"
def test_unknown_winner(): replay = sc2reader.read_file("test_replays/1.2.2.17811/10.SC2Replay") # Recording player (Boom) left second in a 4v4, so the winner shouldn't be known assert replay.winner_known == False