Skip to content

Commit 453027a

Browse files
committed
Better handling of localization issues for s2gs
Throw a SC2ReaderLocalizationError when the translation table tells us to use a sheet or key that doesn't exist for the localization specified by the user.
1 parent 5cf0bd7 commit 453027a

File tree

2 files changed

+28
-22
lines changed

2 files changed

+28
-22
lines changed

sc2reader/exceptions.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
class SC2ReaderError(Exception):
22
pass
33

4+
class SC2ReaderLocalizationError(SC2ReaderError):
5+
pass
6+
47
class MPQError(SC2ReaderError):
58
pass
69

sc2reader/resources.py

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,8 @@
1212
import urllib2
1313
from mpyq import MPQArchive
1414

15-
from sc2reader import utils
16-
from sc2reader import log_utils
17-
from sc2reader import readers, data
15+
from sc2reader import utils, log_utils, readers, data
16+
from sc2reader.exceptions import SC2ReaderLocalizationError
1817
from sc2reader.objects import Player, Observer, Team, PlayerSummary, Graph, DepotFile
1918
from sc2reader.constants import REGIONS, LOCALIZED_RACES, GAME_SPEED_FACTOR, GAME_SPEED_CODES, RACE_CODES, PLAYER_TYPE_CODES, TEAM_COLOR_CODES, GAME_FORMAT_CODES, GAME_TYPE_CODES, DIFFICULTY_CODES
2019
from sc2reader.utils import Color
@@ -629,17 +628,13 @@ def get_url(cls, gateway, map_hash):
629628
else:
630629
return None
631630

632-
class Localization(Resource):
631+
class Localization(Resource,dict):
633632

634633
def __init__(self, s2ml_file, **options):
635-
super(Localization, self).__init__(s2ml_file, **options)
636-
self.mapping = dict()
634+
Resource.__init__(self, s2ml_file, **options)
637635
xml = ElementTree.parse(s2ml_file)
638636
for entry in xml.findall('e'):
639-
self.mapping[int(entry.attrib['id'])] = entry.text
640-
641-
def __getitem__(self, key):
642-
return self.mapping[key]
637+
self[int(entry.attrib['id'])] = entry.text
643638

644639
class GameSummary(Resource):
645640

@@ -672,8 +667,8 @@ class GameSummary(Resource):
672667
#: Map localization urls
673668
localization_urls = dict()
674669

675-
def __init__(self, summary_file, filename=None, **options):
676-
super(GameSummary, self).__init__(summary_file, filename,**options)
670+
def __init__(self, summary_file, filename=None, lang='enUS', **options):
671+
super(GameSummary, self).__init__(summary_file, filename, lang=lang, **options)
677672

678673
#: A list of teams
679674
self.team = dict()
@@ -793,21 +788,25 @@ def load_translations(self):
793788
self.lang_sheets = dict()
794789
self.translations = dict()
795790
for lang, files in self.localization_urls.items():
796-
if lang != 'enUS': continue
791+
if lang != self.opt.lang: continue
797792

798793
sheets = list()
799794
for depot_file in files:
800795
sheets.append(self.factory.load_localization(depot_file, **self.opt))
801796

802797
translation = dict()
803798
for uid, (sheet, item) in self.id_map.items():
804-
translation[uid] = sheets[sheet][item]
799+
if sheet < len(sheets) and item in sheets[sheet]:
800+
translation[uid] = sheets[sheet][item]
801+
else:
802+
msg = "No {0} translation for sheet {1}, item {2}"
803+
raise SC2ReaderLocalizationError(msg.format(self.opt.lang,sheet,item))
805804

806805
self.lang_sheets[lang] = sheets
807806
self.translations[lang] = translation
808807

809808
def load_map_info(self):
810-
map_strings = self.lang_sheets['enUS'][-1]
809+
map_strings = self.lang_sheets[self.opt.lang][-1]
811810
self.map_name = map_strings[1]
812811
self.map_description = map_strings[2]
813812
self.map_tileset = map_strings[3]
@@ -865,20 +864,22 @@ def use_property(prop, player=None):
865864
activated[(prop.id,player)] = use
866865
return use
867866

867+
translation = self.translations[self.opt.lang]
868868
for uid, prop in properties.items():
869-
name = self.translations['enUS'][uid]
869+
name = self.translations[self.opt.lang][uid]
870870
if prop.is_lobby:
871871
if use_property(prop):
872872
value = prop.values[settings[uid]][0]
873-
self.settings[name] = self.translations['enUS'][(uid,value)]
873+
self.settings[name] = translation[(uid,value)]
874874
else:
875875
for index, player_setting in enumerate(settings[uid]):
876876
if use_property(prop, index):
877877
value = prop.values[player_setting][0]
878-
self.player_settings[index][name] = self.translations['enUS'][(uid, value)]
878+
self.player_settings[index][name] = translation[(uid, value)]
879879

880880
def load_player_stats(self):
881881
if len(self.parts) < 4: return
882+
translation = self.translations[self.opt.lang]
882883

883884
# Part[3][0][:] and Part[4][0][1] are filled with summary stats
884885
# for the players in the game. Each stat item is laid out as follows
@@ -891,7 +892,7 @@ def load_player_stats(self):
891892
stats_items.append(self.parts[4][0][0])
892893

893894
for item in stats_items:
894-
stat_name = self.translations['enUS'][item[0][1]]
895+
stat_name = translation[item[0][1]]
895896
for index, value in enumerate(item[1]):
896897
if value:
897898
self.player_stats[index][stat_name] = value[0][0]
@@ -916,6 +917,7 @@ def load_player_stats(self):
916917
def load_player_builds(self):
917918
# Parse build orders only if it looks like we have build items
918919
if len(self.parts) < 5: return
920+
translation = self.translations[self.opt.lang]
919921

920922
# All the parts after part 5 appear to be designated for
921923
# build order entries with a max of 10 per part
@@ -927,8 +929,9 @@ def load_player_builds(self):
927929
# up to the first 64 successful actions in the game.
928930
BuildEntry = namedtuple('BuildEntry',['supply','total_supply','time','order','build_index'])
929931
for build_item in build_items:
930-
if build_item[0][1] in self.translations['enUS']:
931-
order_name = self.translations['enUS'][build_item[0][1]]
932+
translation_key = build_item[0][1]
933+
if translation_key in translation:
934+
order_name = translation[translation_key]
932935
for pindex, commands in enumerate(build_item[1]):
933936
for command in commands:
934937
self.build_orders[pindex].append(BuildEntry(
@@ -939,7 +942,7 @@ def load_player_builds(self):
939942
build_index=command[1] >> 16
940943
))
941944
else:
942-
self.logger.warn("Unknown item in build order, key = {}".format(build_item[0][1]))
945+
self.logger.warn("Unknown item in build order, key = {}".format(translation_key))
943946

944947
# Once we've compiled all the build commands we need to make
945948
# sure they are properly sorted for presentation.

0 commit comments

Comments
 (0)