#encoding: utf8 import os, gettext, time, copy, sys, re import unit_tree.helpers as helpers import wesnoth.wmlparser2 as wmlparser2 pics_location = "../../pics" html_header = ''' %(title)s
'''.strip() top_bar = '''
Wesnoth logo
Wesnoth Units database
'''.strip() html_footer = '''
'''.strip() all_written_html_files = [] error_only_once = {} def error_message(message): if message in error_only_once: return error_only_once[message] = 1 write_error(message) helpers.error_message = error_message def reset_errors(): error_only_once = {} class MyFile: """ Python 2 is a bit weird with encodings, really should switch this to Python 3. """ def __init__(self, filename, mode): self.filename = filename self.f = open(filename, mode) def write(self, x): x = x.encode("utf8") self.f.write(x) def close(self): self.f.close() class Translation: def __init__(self, localedir, langcode): self.catalog = {} self.localedir = localedir self.langcode = langcode class Dummy: def ugettext(self, x): if not x: return "" caret = x.find("^") if caret < 0: return x return x[caret + 1:] self.dummy = Dummy() def translate(self, string, textdomain): if textdomain not in self.catalog: try: self.catalog[textdomain] = gettext.translation( textdomain, self.localedir, [self.langcode]) self.catalog[textdomain].add_fallback(self.dummy) except IOError: self.catalog[textdomain] = self.dummy except AttributeError: self.catalog[textdomain] = self.dummy except IndexError: # not sure why, but this happens within the # gettext.translation call sometimes self.catalog[textdomain] = self.dummy r = self.catalog[textdomain].ugettext(string) return r class GroupByRace: def __init__(self, wesnoth, campaign): self.wesnoth = wesnoth self.campaign = campaign def unitfilter(self, unit): if not self.campaign: return True return unit.campaigns and self.campaign == unit.campaigns[0] def groups(self, unit): return [T(unit.race, "plural_name")] def group_name(self, group): if not group: return "None" return group class GroupByNothing: def __init__(self): pass def unitfilter(self, unit): return True def groups(self, unit): return ["units"] def group_name(self, group): return "units" class GroupByFaction: def __init__(self, wesnoth, era): self.wesnoth = wesnoth self.era = era def unitfilter(self, unit): return self.era in unit.eras def groups(self, unit): return [x for x in unit.factions if x[0] == self.era] def group_name(self, group): era = self.wesnoth.era_lookup[group[0]] if group[1]: faction = era.faction_lookup[group[1]] name = T(faction, "name") name = name[name.rfind("=") + 1:] else: name = "factionless" return name global_htmlout = None def T(tag, att): if not tag: return "none" return tag.get_text_val(att, translation = global_htmlout.translate) class HTMLOutput: def __init__(self, isocode, output, addon, campaign, is_era, wesnoth, verbose = False): global global_htmlout self.output = output self.addon = addon self.campaign = campaign self.is_era = is_era self.verbose = verbose self.target = "index.html" self.wesnoth = wesnoth self.forest = None self.translation = Translation(options.transdir, isocode) self.isocode = isocode global_htmlout = self def translate(self, string, domain): return self.translation.translate(string, domain) def analyze_units(self, grouper): """ This takes all units belonging to a campaign, then groups them either by race or faction, and creates an advancements tree out of it. """ # Build an advancement tree forest of all units. forest = self.forest = helpers.UnitForest() units_added = {} for uid, u in self.wesnoth.unit_lookup.items(): if u.hidden: continue if grouper.unitfilter(u): forest.add_node(helpers.UnitNode(u)) units_added[uid] = u #print(" %d/%d units" % (len(units_added), len(self.wesnoth.unit_lookup))) # Always add any child units, even if they have been filtered out.. while units_added: new_units_added = {} for uid, u in units_added.items(): for auid in u.advance: if not auid in units_added: try: au = self.wesnoth.unit_lookup[auid] except KeyError: error_message( "Warning: Unit %s not found as advancement of %s\n" % (auid, repr(uid))) continue forest.add_node(helpers.UnitNode(au)) new_units_added[auid] = au units_added = new_units_added # Also add parent units added = True while added: added = False for uid, u in self.wesnoth.unit_lookup.items(): if uid in forest.lookup: continue for auid in u.advance: if auid in forest.lookup: forest.add_node(helpers.UnitNode(u)) added = True break forest.update() # Partition trees by race/faction of first unit. groups = {} breadth = 0 for tree in forest.trees.values(): u = tree.unit ugroups = grouper.groups(u) for group in ugroups: groups[group] = groups.get(group, []) + [tree] breadth += tree.breadth thelist = groups.keys() thelist.sort(key = lambda x: grouper.group_name(x)) rows_count = breadth + len(thelist) # Create empty grid. rows = [] for j in range(rows_count): column = [] for i in range(6): column.append((1, 1, None)) rows.append(column) # Sort advancement trees by name of first unit and place into the grid. def by_name(t1, t2): u1 = t1.unit u2 = t2.unit u1name = T(u1, "name") u2name = T(u2, "name") return cmp(u1name, u2name) def grid_place(nodes, x): nodes.sort(by_name) for node in nodes: level = node.unit.level if level < 0: level = 0 if level > 5: level = 5 rows[x][level] = (1, node.breadth, node) for i in range(1, node.breadth): rows[x + i][level] = (0, 0, node) grid_place(node.children, x) x += node.breadth return x x = 0 for group in thelist: node = helpers.GroupNode(group) node.name = grouper.group_name(group) rows[x][0] = (6, 1, node) for i in range(1, 6): rows[x][i] = (0, 0, None) nodes = groups[group] x += 1 x = grid_place(nodes, x) self.unitgrid = rows return len(forest.lookup) def write_navbar(self, report_type): def write(x): self.output.write(x) all_written_html_files.append((self.isocode, self.output.filename)) languages = self.wesnoth.languages_found langlist = languages.keys() langlist.sort() write(top_bar % {"path" : "../../"}) write(""" \n") # Races / Factions if not self.is_era: x = self.translate("Race", "wesnoth-lib") add_menu("races_menu", x) write("%s
\n" % ( self.translate("all", "wesnoth-editor"))) r = {}, {} for u in self.wesnoth.unit_lookup.values(): race = u.race racename = T(race, "plural_name") m = 1 if u: m = 0 r[m][racename] = race.get_text_val("id") if race else "none" racenames = sorted(r[0].items()) if r[1].items(): racenames += [("-", "-")] + sorted(r[1].items()) for racename, rid in racenames: if racename == "-": write(" -
") else: write(" %s
" % ( self.target, racename, racename)) write("\n") else: x = self.translate("Factions", "wesnoth-help") add_menu("races_menu", x) for row in self.unitgrid: for column in range(6): hspan, vspan, un = row[column] if not un: continue if isinstance(un, helpers.GroupNode): html = "../%s/%s.html" % ( self.isocode, self.campaign) write(" %s
" % ( html, un.name, un.name)) write("\n") # Add entries for the races also to the navbar itself. if not self.is_era: class Entry: pass races = {} for uid, u in self.wesnoth.unit_lookup.items(): if self.campaign != "units": if self.campaign not in u.campaigns: continue if u.race: racename = T(u.race, "plural_name") else: racename = "none" runits = races.get(racename, []) runits.append(uid) races[racename] = runits racelist = sorted(races.keys()) got_menu = False menuid = 0 for r in racelist: if not r: continue if got_menu: write("\n") add_menu("units_menu" + str(menuid), r, "unitmenu") menuid += 1 got_menu = True c = self.campaign if c == "units": c = "mainline" write("%s
" % ( self.target, r, r)) for uid in races[r]: un = self.wesnoth.unit_lookup[uid] if "mainline" in un.campaigns: addon = "mainline" else: addon = self.addon link = "../../%s/%s/%s.html" % (addon, self.isocode, uid) name = self.wesnoth.get_unit_value(un, "name", translation=self.translation.translate) if not name: error_message("Warning: Unit uid=" + uid + " has no name.\n") name = uid write("" + name + "
") if got_menu: write("\n") # Languages x = self.translate("Language", "wesnoth") add_menu("languages_menu", x) col = 0 maxcol = len(langlist) - 1 write("") write("") for lang in langlist: col += 1 write("") if col % 5 == 0: if col < maxcol: write("") write("") write("
") labb = lang underscore = labb.find("_") if underscore > 0: labb = labb[:underscore] if self.addon == "mainline": write(" %s
\n" % ( languages[lang], lang, self.target, labb)) else: write(" %s
\n" % ( languages[lang], lang, "mainline.html", labb)) write("
") write("\n") write("
  •  
  • ") write("
  •  
  • ") write('
  • Overview
  • ') write("\n") write("\n") def pic(self, u, x, recursion = 0): if recursion >= 4: error_message( "Warning: Cannot find image for unit %s(%s).\n" % ( u.get_text_val("id"), x.name)) return None, None image = self.wesnoth.get_unit_value(x, "image") portrait = x.get_all(tag="portrait") if not portrait: bu = self.wesnoth.get_base_unit(u) if bu: portrait = bu.get_all(tag="portrait") if portrait: portrait = portrait[0].get_text_val("image") if not image: if x.name == "female": baseunit = self.wesnoth.get_base_unit(u) if baseunit: female = baseunit.get_all(tag="female") return self.pic(u, female[0], recursion = recursion + 1) else: return self.pic(u, u, recursion = recursion + 1) error_message( "Warning: Missing image for unit %s(%s).\n" % ( u.get_text_val("id"), x.name)) return None, None icpic = image_collector.add_image_check(self.addon, image) if not icpic.ipath: error_message("Warning: No picture %s for unit %s.\n" % (image, u.get_text_val("id"))) picname = icpic.id_name image = os.path.join(pics_location, picname) if portrait: picname = image_collector.add_image(self.addon, portrait, no_tc=True) portrait = os.path.join(pics_location, picname) return image, portrait def get_abilities(self, u): anames = [] already = {} for abilities in u.get_all(tag="abilities"): try: c = abilities.get_all() except AttributeError: c = [] for ability in c: id = ability.get_text_val("id") if id in already: continue already[id] = True name = T(ability, "name") if not name: name = id if not name: name = ability.name anames.append(name) return anames def get_recursive_attacks(self, this_unit): def copy_attributes(copy_from, copy_to): for c in copy_from.data: if isinstance(c, wmlparser2.AttributeNode): copy_to.data.append(c) # Use attacks of base_units as base, if we have one. base_unit = self.wesnoth.get_base_unit(this_unit) attacks = [] if base_unit: attacks = copy.deepcopy(self.get_recursive_attacks(base_unit)) base_attacks_count = len(attacks) for i, attack in enumerate(this_unit.get_all(tag="attack")): # Attack merging is order based. if i < base_attacks_count: copy_attributes(attack, attacks[i]) else: attacks.append(attack) return attacks def write_units(self): def write(x): self.output.write(x) def _(x, c="wesnoth"): return self.translate(x, c) rows = self.unitgrid write("\n") write("") for i in range(6): write("" % i) write("") pic = image_collector.add_image("general", "../../../images/misc/leader-crown.png", no_tc=True) crownimage = os.path.join(pics_location, pic) ms = None for row in range(len(rows)): write("\n") for column in range(6): hspan, vspan, un = rows[row][column] if vspan: attributes = "" if hspan == 1 and vspan == 1: pass elif hspan == 1: attributes += " rowspan=\"%d\"" % vspan elif vspan == 1: attributes += " colspan=\"%d\"" % hspan if un and isinstance(un, helpers.GroupNode): # Find the current multiplayer side so we can show the # little crowns.. ms = None if self.is_era: try: eid, fid = un.data era = self.wesnoth.era_lookup[eid] if fid: ms = era.faction_lookup[fid] except TypeError: pass racename = un.name attributes += " class=\"raceheader\"" write("" % attributes) write("%s" % (racename, racename)) write("\n") elif un: u = un.unit attributes += " class=\"unitcell\"" write("" % attributes) uid = u.get_text_val("id") def uval(name): return self.wesnoth.get_unit_value(u, name, translation=self.translation.translate) name = uval("name") cost = uval("cost") hp = uval("hitpoints") mp = uval("movement") xp = uval("experience") level = uval("level") crown = "" if ms: if un.id in ms.units: crown = u" ♟" if un.id in ms.is_leader: crown = u" ♚" uaddon = "mainline" if "mainline" not in u.campaigns: uaddon = self.addon link = "../../%s/%s/%s.html" % (uaddon, self.isocode, uid) write("
    %s" % ( link, uid, u"i")) write("
    ") write("
    L%s%s
    " % (level, crown)) write("%s
    " % (link, name)) write('\n') write("
    ") write("%s%s
    " % (_("Cost: ", "wesnoth-help"), cost)) write("%s%s
    " % (_("HP: "), hp)) write("%s%s
    " % (_("MP: "), mp)) write("%s%s
    " % (_("XP: "), xp)) # Write info about abilities. anames = self.get_abilities(u) if anames: write("\n
    ") write(", ".join(anames)) write("
    ") # Write info about attacks. write("\n
    ") attacks = self.get_recursive_attacks(u) for attack in attacks: n = T(attack, "number") x = T(attack, "damage") x = "%s - %s" % (x, n) write("%s " % x) r = T(attack, "range") t = T(attack, "type") write("%s (%s)" % (_(r), _(t))) s = [] specials = attack.get_all(tag="specials") if specials: for special in specials[0].get_all(tag=""): sname = T(special, "name") if sname: s.append(sname) s = ", ".join(s) if s: write(" (%s)" % s) write("
    ") write("
    ") write("
    ") write("\n") else: write("
    ") write("\n") write("
    \n") def write_units_tree(self, grouper, title): self.output.write(html_header % {"path": "../../", "title": title}) n = self.analyze_units(grouper) self.write_navbar("units_tree") self.output.write("
    ") self.output.write("

    %s

    " % title) self.write_units() self.output.write('
    ') self.output.write("
    ") self.output.write(html_footer % { "generation_note": "generated on " + time.ctime()}) return n def write_unit_report(self, output, unit): def write(x): self.output.write(x) def _(x, c="wesnoth"): return self.translate(x, c) def find_attr(what, key): if unit.movetype: mtx = unit.movetype.get_all(tag=what) mty = None if mtx: mty = mtx[0].get_text_val(key) x = unit.get_all(tag=what) y = None if x: y = x[0].get_text_val(key, translation=self.translation.translate) if y: return True, y if unit.movetype and mty != None: return False, mty return False, "-" def uval(name): return self.wesnoth.get_unit_value(unit, name, translation=self.translation.translate) # Write unit name, picture and description. uid = unit.get_text_val("id") uname = uval("name") display_name = uname self.output = output write(html_header % {"path": "../../", "title": display_name}) self.write_navbar("unit_report") self.output.write("
    ") female = unit.get_all(tag="female") if female: fname = T(female[0], "name") if fname and fname != uname: display_name += "
    " + fname write('
    ') write('
    ') write("

    %s

    \n" % display_name) write('
    ') if female: mimage, portrait = self.pic(unit, unit) fimage, fportrait = self.pic(unit, female[0]) if not fimage: fimage = mimage if not fportrait: fportrait = portrait write('(image)\n' % mimage) write('(image)\n' % fimage) image = mimage else: image, portrait = self.pic(unit, unit) write('(image)\n' % image) write('
    \n') description = uval("description") # TODO: what is unit_description? if not description: description = uval("unit_description") if not description: description = "-" write("

    %s

    \n" % re.sub("\n", "\n
    ", description)) # Base info. hp = uval("hitpoints") mp = uval("movement") xp = uval("experience") level = uval("level") alignment = uval("alignment") write("

    Information

    \n") write("\n") write("\n") write("\n") write("\n") write("\n") write("\n") for val, text in [ ("cost", _("Cost: ", "wesnoth-help")), ("hitpoints", _("HP: ")), ("movement", _("Movement", "wesnoth-help") + ": "), ("experience", _("XP: ")), ("level", _("Level") + ": "), ("alignment", _("Alignment: ")), ("id", "ID")]: write("\n") write("" % text) x = uval(val) if val == "alignment": x = _(x) write("" % x) write("\n") # Write info about abilities. anames = self.get_abilities(unit) write("\n") write("" % _("Abilities: ", "wesnoth-help")) write("") write("\n") write("
    %s" % _("Advances from: ", "wesnoth-help")) write("\n") for pid in self.forest.get_parents(uid): punit = self.wesnoth.unit_lookup[pid] if "mainline" in unit.campaigns and "mainline" not in punit.campaigns: continue if "mainline" in unit.campaigns: addon = "mainline" else: addon = self.addon link = "../../%s/%s/%s.html" % (addon, self.isocode, pid) name = self.wesnoth.get_unit_value(punit, "name", translation=self.translation.translate) write("\n%s" % (link, name)) write("
    %s" % _("Advances to: ", "wesnoth-help")) write("\n") for cid in self.forest.get_children(uid): try: cunit = self.wesnoth.unit_lookup[cid] if "mainline" in cunit.campaigns: addon = "mainline" else: addon = self.addon link = "../../%s/%s/%s.html" % (addon, self.isocode, cid) if "mainline" in unit.campaigns and "mainline" not in cunit.campaigns: continue name = self.wesnoth.get_unit_value(cunit, "name", translation=self.translation.translate) except KeyError: error_message("Warning: Unit %s not found.\n" % cid) name = cid if "mainline" in unit.campaigns: continue link = self.target write("\n%s" % (link, name)) write("
    %s%s
    %s" + (", ".join(anames)) + "
    \n") # Write info about attacks. write("

    " + _("unit help^Attacks", "wesnoth-help") + " (damage - count)

    \n") write("\n") write('') attacks = self.get_recursive_attacks(unit) for attack in attacks: write("") aid = attack.get_text_val("name") aname = T(attack, "description") icon = attack.get_text_val("icon") if not icon: icon = "attacks/%s.png" % aid image_add = image_collector.add_image_check(self.addon, icon, no_tc = True) if not image_add.ipath: error_message("Error: No attack icon '%s' found for '%s'.\n" % ( icon, uid)) icon = os.path.join(pics_location, "unit$elves-wood$shaman.png") else: icon = os.path.join(pics_location, image_add.id_name) write("" % icon) write("" % _(r)) n = attack.get_text_val("number") x = attack.get_text_val("damage") x = "%s - %s" % (x, n) write("" % _(t)) s = [] specials = attack.get_all(tag="specials") if specials: for special in specials[0].get_all(tag=""): sname = T(special, "name") if sname: s.append(sname) else: error_message( "Warning: Weapon special %s has no name for %s.\n" % ( special.name, uid)) s = "
    ".join(s) write("" % s) write("") write("
    \"(image)\"/%s" % aname) r = T(attack, "range") write("
    %s
    %s" % x) t = T(attack, "type") write("
    %s
    %s
    \n") # Write info about resistances. resistances = [ ("blade", "attacks/sword-human.png"), ("pierce", "attacks/spear.png"), ("impact", "attacks/club.png"), ("fire", "attacks/fireball.png"), ("cold", "attacks/iceball.png"), ("arcane", "attacks/faerie-fire.png")] write("

    %s

    \n" % _("Resistances: ").strip(" :")) write("\n") write('') write("\n") write("\n") row = 0 for rid, ricon in resistances: special, r = find_attr("resistance", rid) if r == "-": r = 100 try: r = "%d%%" % (100 - int(r)) except ValueError: error_message("Warning: Invalid resistance %s for %s.\n" % ( r, uid)) rcell = "td" if special: rcell += ' class="special"' if row % 2 == 0: write("\n") else: write("") picname = image_collector.add_image(self.addon, ricon, no_tc = True) icon = os.path.join(pics_location, picname) write("\n" % (icon, )) write("\n" % (_(rid), r)) if row % 2 == 1: write("\n") row += 1 write("
    \"(icon)\"%s%s
    \n") # end left column write('
    ') write('
    ') for si in range(2): if si and not female: break if si: sportrait = fportrait simage = fimage else: simage = image sportrait = portrait style = "background-image: url(%s);" % simage write('
    ') write('
     
    ' % style) if portrait: write('(portrait)\n' % sportrait) write('
    ') # Write info about movement costs and terrain defense. write("

    " + _("Terrain", "wesnoth-help") + "

    \n") write("\n") write('') write("\n" % ( _("Movement Cost", "wesnoth-help"))) write("\n" % ( _("Terrain", "wesnoth-help"), _("Defense", "wesnoth-help"))) terrains = self.wesnoth.terrain_lookup terrainlist = [] already = {} for tstring, t in terrains.items(): tid = t.get_text_val("id") if tid in ["off_map", "off_map2", "fog", "shroud", "impassable", "void", "rails"]: continue if t.get_all(att="aliasof"): continue if tid in already: continue already[tid] = 1 name = T(t, "name") ticon = t.get_text_val("symbol_image") if tid == "flat": ticon = "grass/green-symbol" elif tid == "frozen": ticon = "frozen/ice" elif tid == "unwalkable": ticon = "unwalkable/lava" elif tid == "village": ticon = "village/human-tile" elif tid == "forest": ticon = "forest/pine-tile" terrainlist.append((name, tid, ticon)) terrainlist.sort() for tname, tid, ticon in terrainlist: not_from_race, c = find_attr("movement_costs", tid) ccell = "td" if c == "99": ccell += ' class="grayed"' dcell = "td" not_from_race, d = find_attr("defense", tid) if d == "-": d = 100 try: d = "%d%%" % (100 - int(d)) except ValueError: error_message("Warning: Invalid defense %s for %s.\n" % ( d, uid)) write("\n") picname = image_collector.add_image(self.addon, "terrain/" + ticon + ".png", no_tc=True) icon = os.path.join(pics_location, picname) write("\n" % (icon, )) write("<%s>%s<%s class=\"num\">%s\n" % ( tname, ccell, c, dcell, d)) write("\n") write("
    %s
    %s%s
    \"(icon)\"%s
    \n") write('
    ') # right column write('
    ') # columns parent self.output.write('
    ') write('
    ') # main self.output.write(html_footer % { "generation_note": "generated on " + time.ctime()}) def generate_campaign_report(addon, isocode, campaign, wesnoth): if campaign: cid = campaign.get_text_val("id") else: cid = "mainline" if not cid: cid = addon + "_" + campaign.get_text_val("define") print("campaign " + addon + " " + cid + " " + isocode) path = os.path.join(options.output, addon, isocode) if not os.path.isdir(path): os.mkdir(path) output = MyFile(os.path.join(path, "%s.html" % cid), "w") html = HTMLOutput(isocode, output, addon, cid, False, wesnoth) html.target = "%s.html" % cid grouper = GroupByRace(wesnoth, cid) if campaign: title = campaign.get_text_val("name", translation = html.translate) else: title = html.translate("Units", "wesnoth-help") if not title: title = cid n = html.write_units_tree(grouper, title) output.close() return n def generate_era_report(addon, isocode, era, wesnoth): eid = era.get_text_val("id") print("era " + addon + " " + eid + " " + isocode) path = os.path.join(options.output, addon, isocode) if not os.path.isdir(path): os.mkdir(path) output = MyFile(os.path.join(path, "%s.html" % eid), "w") html = HTMLOutput(isocode, output, addon, eid, True, wesnoth) html.target = "%s.html" % eid grouper = GroupByFaction(wesnoth, eid) ename = era.get_text_val("name", translation = html.translate) n = html.write_units_tree(grouper, ename) output.close() return n def generate_single_unit_reports(addon, isocode, wesnoth): path = os.path.join(options.output, addon, isocode) if not os.path.isdir(path): os.mkdir(path) html = HTMLOutput(isocode, None, addon, "units", False, wesnoth) grouper = GroupByNothing() html.analyze_units(grouper) for uid, unit in wesnoth.unit_lookup.items(): if unit.hidden: continue if "mainline" in unit.campaigns and addon != "mainline": continue filename = os.path.join(path, "%s.html" % uid) # We probably can come up with something better. if os.path.exists(filename): age = time.time() - os.path.getmtime(filename) # was modified in the last 12 hours - we should be ok if age < 3600 * 12: continue output = MyFile(filename, "w") html.target = "%s.html" % uid html.write_unit_report(output, unit) output.close() def html_postprocess_file(filename, isocode, batchlist): print("postprocessing " + filename) chtml = u"" ehtml = u"" cids = [[], []] for addon in batchlist: for campaign in addon.get("campaigns", []): if campaign["units"] == "?": continue if campaign["units"] <= 0: continue if addon["name"] == "mainline": lang = isocode else: lang = "en_US" c = addon["name"], campaign["id"], campaign["translations"].get( lang, campaign["name"]), lang if addon["name"] == "mainline": cids[0].append(c) else: cids[1].append(c) for i in range(2): campaigns = cids[i] campaigns.sort(key = lambda x: "A" if x[1] == "mainline" else "B" + x[2]) for campaign in campaigns: addon, cname, campname, lang = campaign chtml += u" %s
    \n" % ( campname, addon, lang, cname, campname) if i == 0 and cids[1]: chtml += u"-
    \n" eids = [[], []] for addon in batchlist: for era in addon.get("eras", []): if era["units"] == "?": continue if era["units"] <= 0: continue if addon["name"] == "mainline": lang = isocode else: lang = "en_US" e = addon["name"], era["id"], era["translations"].get( lang, era["name"]), lang if addon["name"] == "mainline": eids[0].append(e) else: eids[1].append(e) for i in range(2): eras = eids[i] eras.sort(key = lambda x: x[2]) for era in eras: addon, eid, eraname, lang = era ehtml += u" %s
    " % ( eraname, addon, lang, eid, eraname) if i == 0 and eids[1]: ehtml += u"-
    \n" f = open(filename, "r+b") html = f.read().decode("utf8") html = html.replace(u"PLACE CAMPAIGNS HERE\n", chtml) html = html.replace(u"PLACE ERAS HERE\n", ehtml) f.seek(0) f.write(html.encode("utf8")) f.close() def html_postprocess_all(batchlist): for isocode, filename in all_written_html_files: html_postprocess_file(filename, isocode, batchlist) def write_index(out_path): output = MyFile(os.path.join(out_path, "index.html"), "w") output.write(""" Redirecting to Wesnoth units database... """)