Skip to content

Commit fa2a4f5

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 98320af commit fa2a4f5

File tree

2 files changed

+28
-19
lines changed

2 files changed

+28
-19
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 & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@
1212
import urllib2
1313
from mpyq import MPQArchive
1414

15+
1516
from sc2reader import utils
1617
from sc2reader import log_utils
1718
from sc2reader import readers
1819
from sc2reader.data import builds as datapacks
1920
from sc2reader.events import AbilityEvent, CameraEvent, HotkeyEvent, SelectionEvent
21+
from sc2reader.exceptions import SC2ReaderLocalizationError
2022
from sc2reader.objects import Player, Observer, Team, PlayerSummary, Graph, DepotFile
2123
from sc2reader.constants import REGIONS, LOCALIZED_RACES, GAME_SPEED_FACTOR, LOBBY_PROPERTIES
2224

@@ -659,17 +661,13 @@ def get_url(cls, gateway, map_hash):
659661
else:
660662
return None
661663

662-
class Localization(Resource):
664+
class Localization(Resource,dict):
663665

664666
def __init__(self, s2ml_file, **options):
665-
super(Localization, self).__init__(s2ml_file, **options)
666-
self.mapping = dict()
667+
Resource.__init__(self, s2ml_file, **options)
667668
xml = ElementTree.parse(s2ml_file)
668669
for entry in xml.findall('e'):
669-
self.mapping[int(entry.attrib['id'])] = entry.text
670-
671-
def __getitem__(self, key):
672-
return self.mapping[key]
670+
self[int(entry.attrib['id'])] = entry.text
673671

674672
class GameSummary(Resource):
675673

@@ -702,8 +700,8 @@ class GameSummary(Resource):
702700
#: Map localization urls
703701
localization_urls = dict()
704702

705-
def __init__(self, summary_file, filename=None, **options):
706-
super(GameSummary, self).__init__(summary_file, filename,**options)
703+
def __init__(self, summary_file, filename=None, lang='enUS', **options):
704+
super(GameSummary, self).__init__(summary_file, filename, lang=lang, **options)
707705

708706
#: A list of teams
709707
self.team = dict()
@@ -823,21 +821,25 @@ def load_translations(self):
823821
self.lang_sheets = dict()
824822
self.translations = dict()
825823
for lang, files in self.localization_urls.items():
826-
if lang != 'enUS': continue
824+
if lang != self.opt.lang: continue
827825

828826
sheets = list()
829827
for depot_file in files:
830828
sheets.append(self.factory.load_localization(depot_file, **self.opt))
831829

832830
translation = dict()
833831
for uid, (sheet, item) in self.id_map.items():
834-
translation[uid] = sheets[sheet][item]
832+
if sheet < len(sheets) and item in sheets[sheet]:
833+
translation[uid] = sheets[sheet][item]
834+
else:
835+
msg = "No {0} translation for sheet {1}, item {2}"
836+
raise SC2ReaderLocalizationError(msg.format(self.opt.lang,sheet,item))
835837

836838
self.lang_sheets[lang] = sheets
837839
self.translations[lang] = translation
838840

839841
def load_map_info(self):
840-
map_strings = self.lang_sheets['enUS'][-1]
842+
map_strings = self.lang_sheets[self.opt.lang][-1]
841843
self.map_name = map_strings[1]
842844
self.map_description = map_strings[2]
843845
self.map_tileset = map_strings[3]
@@ -895,20 +897,22 @@ def use_property(prop, player=None):
895897
activated[(prop.id,player)] = use
896898
return use
897899

900+
translation = self.translations[self.opt.lang]
898901
for uid, prop in properties.items():
899-
name = self.translations['enUS'][uid]
902+
name = self.translations[self.opt.lang][uid]
900903
if prop.is_lobby:
901904
if use_property(prop):
902905
value = prop.values[settings[uid]][0]
903-
self.settings[name] = self.translations['enUS'][(uid,value)]
906+
self.settings[name] = translation[(uid,value)]
904907
else:
905908
for index, player_setting in enumerate(settings[uid]):
906909
if use_property(prop, index):
907910
value = prop.values[player_setting][0]
908-
self.player_settings[index][name] = self.translations['enUS'][(uid, value)]
911+
self.player_settings[index][name] = translation[(uid, value)]
909912

910913
def load_player_stats(self):
911914
if len(self.parts) < 4: return
915+
translation = self.translations[self.opt.lang]
912916

913917
# Part[3][0][:] and Part[4][0][1] are filled with summary stats
914918
# for the players in the game. Each stat item is laid out as follows
@@ -921,7 +925,7 @@ def load_player_stats(self):
921925
stats_items.append(self.parts[4][0][0])
922926

923927
for item in stats_items:
924-
stat_name = self.translations['enUS'][item[0][1]]
928+
stat_name = translation[item[0][1]]
925929
for index, value in enumerate(item[1]):
926930
if value:
927931
self.player_stats[index][stat_name] = value[0][0]
@@ -946,6 +950,7 @@ def load_player_stats(self):
946950
def load_player_builds(self):
947951
# Parse build orders only if it looks like we have build items
948952
if len(self.parts) < 5: return
953+
translation = self.translations[self.opt.lang]
949954

950955
# All the parts after part 5 appear to be designated for
951956
# build order entries with a max of 10 per part
@@ -957,8 +962,9 @@ def load_player_builds(self):
957962
# up to the first 64 successful actions in the game.
958963
BuildEntry = namedtuple('BuildEntry',['supply','total_supply','time','order','build_index'])
959964
for build_item in build_items:
960-
if build_item[0][1] in self.translations['enUS']:
961-
order_name = self.translations['enUS'][build_item[0][1]]
965+
translation_key = build_item[0][1]
966+
if translation_key in translation:
967+
order_name = translation[translation_key]
962968
for pindex, commands in enumerate(build_item[1]):
963969
for command in commands:
964970
self.build_orders[pindex].append(BuildEntry(
@@ -969,7 +975,7 @@ def load_player_builds(self):
969975
build_index=command[1] >> 16
970976
))
971977
else:
972-
self.logger.warn("Unknown item in build order, key = {}".format(build_item[0][1]))
978+
self.logger.warn("Unknown item in build order, key = {}".format(translation_key))
973979

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

0 commit comments

Comments
 (0)