Skip to content

Commit d71a73f

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 9c02c39 commit d71a73f

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

@@ -628,17 +627,13 @@ def get_url(cls, gateway, map_hash):
628627
else:
629628
return None
630629

631-
class Localization(Resource):
630+
class Localization(Resource,dict):
632631

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

643638
class GameSummary(Resource):
644639

@@ -671,8 +666,8 @@ class GameSummary(Resource):
671666
#: Map localization urls
672667
localization_urls = dict()
673668

674-
def __init__(self, summary_file, filename=None, **options):
675-
super(GameSummary, self).__init__(summary_file, filename,**options)
669+
def __init__(self, summary_file, filename=None, lang='enUS', **options):
670+
super(GameSummary, self).__init__(summary_file, filename, lang=lang, **options)
676671

677672
#: A list of teams
678673
self.team = dict()
@@ -792,21 +787,25 @@ def load_translations(self):
792787
self.lang_sheets = dict()
793788
self.translations = dict()
794789
for lang, files in self.localization_urls.items():
795-
if lang != 'enUS': continue
790+
if lang != self.opt.lang: continue
796791

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

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

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

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

866+
translation = self.translations[self.opt.lang]
867867
for uid, prop in properties.items():
868-
name = self.translations['enUS'][uid]
868+
name = self.translations[self.opt.lang][uid]
869869
if prop.is_lobby:
870870
if use_property(prop):
871871
value = prop.values[settings[uid]][0]
872-
self.settings[name] = self.translations['enUS'][(uid,value)]
872+
self.settings[name] = translation[(uid,value)]
873873
else:
874874
for index, player_setting in enumerate(settings[uid]):
875875
if use_property(prop, index):
876876
value = prop.values[player_setting][0]
877-
self.player_settings[index][name] = self.translations['enUS'][(uid, value)]
877+
self.player_settings[index][name] = translation[(uid, value)]
878878

879879
def load_player_stats(self):
880880
if len(self.parts) < 4: return
881+
translation = self.translations[self.opt.lang]
881882

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

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

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

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

0 commit comments

Comments
 (0)