mirror of
https://github.com/wesnoth/wesnoth
synced 2024-09-21 00:13:57 +00:00
9630080049
...for multiple units advancing to the same unit, and added some sanity checks for units who can advance to themselves.
851 lines
29 KiB
Python
Executable File
851 lines
29 KiB
Python
Executable File
#!/usr/bin/env python
|
|
"""
|
|
wmlunits -- tool to output information on all units in HTML
|
|
|
|
Run without arguments to see usage.
|
|
"""
|
|
|
|
# Makes things faster on 32-bit systems
|
|
try: import psyco; psyco.full()
|
|
except ImportError: pass
|
|
|
|
import sys, os, re, glob, shutil, copy, urllib2
|
|
|
|
import wesnoth.wmldata as wmldata
|
|
import wesnoth.wmlparser as wmlparser
|
|
import wesnoth.wmltools as wmltools
|
|
|
|
sys.path.append(".")
|
|
import unit_tree.helpers as helpers
|
|
|
|
html_header = '''
|
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
|
<html>
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
|
<link rel=stylesheet href=\"%(path)sstyle.css\" type=\"text/css\">
|
|
</head>
|
|
<body>'''.strip()
|
|
|
|
html_footer = '''
|
|
<div id="footer">
|
|
<p><a href="http://www.wesnoth.org/wiki/Site_Map">Site map</a></p>
|
|
<p><a href="http://www.wesnoth.org/wiki/Wesnoth:Copyrights">Copyright</a> © 2003-2008 The Battle for Wesnoth</p>
|
|
<p>Supported by <a href="http://www.jexiste.fr/">Jexiste</a></p>
|
|
<p><a href="http://www.ibiblio.org/"><img src="http://www.ibiblio.org/hosted/images/ibiblio_hosted-110x32.png" width="110" height="32" border="0" alt="hosted by ibiblio" /></a></p>
|
|
</div>
|
|
</body></html>
|
|
'''.strip()
|
|
|
|
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.campaign == self.campaign
|
|
|
|
def groups(self, unit):
|
|
return [unit.race]
|
|
|
|
def group_name(self, group):
|
|
if not group: return "None"
|
|
return group.get_text_val("plural_name")
|
|
|
|
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]]
|
|
faction = era.faction_lookup[group[1]]
|
|
name = faction.get_text_val("name")
|
|
name = name[name.rfind("=") + 1:]
|
|
name = era.get_text_val("name") + " / " + name
|
|
return name
|
|
|
|
class HTMLOutput:
|
|
def __init__(self, isocode, output, campaign, wesnoth, verbose = False):
|
|
self.isocode = isocode
|
|
self.output = output
|
|
self.campaign = campaign
|
|
self.verbose = verbose
|
|
self.target = "index.html"
|
|
self.wesnoth = wesnoth
|
|
self.forest = None
|
|
|
|
def get_translation(self, textdomain, key):
|
|
return self.wesnoth.parser.translations.get(textdomain, self.isocode,
|
|
key, key)
|
|
|
|
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 grouper.unitfilter(u):
|
|
forest.add_node(helpers.UnitNode(u))
|
|
units_added[uid] = u
|
|
|
|
# Always add any child units, even if they have been filtered out..
|
|
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:
|
|
# FIXME: write error message
|
|
continue
|
|
forest.add_node(helpers.UnitNode(au))
|
|
units_added[auid] = au
|
|
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()
|
|
|
|
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 = u1.get_text_val("name")
|
|
u2name = u2.get_text_val("name")
|
|
return cmp(u1name, u2name)
|
|
|
|
def grid_place(nodes, x):
|
|
nodes.sort(by_name)
|
|
for node in nodes:
|
|
level = node.unit.level
|
|
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
|
|
|
|
def write_navbar(self):
|
|
def write(x): self.output.write(x)
|
|
def _(x): return self.get_translation("wesnoth", x)
|
|
languages = find_languages()
|
|
langlist = languages.keys()
|
|
langlist.sort()
|
|
|
|
write("""
|
|
<div class="header">
|
|
<a href="http://www.wesnoth.org">
|
|
<img src="../wesnoth-logo.jpg" alt="Wesnoth logo"/>
|
|
</a>
|
|
</div>
|
|
<div class="topnav">
|
|
<a href="../index.html">Wesnoth Units database</a>
|
|
</div>
|
|
""")
|
|
|
|
write("<table class=\"navbar\">")
|
|
|
|
write("<tr>\n")
|
|
|
|
def abbrev(name):
|
|
abbrev = name[0]
|
|
for i in range(1, len(name)):
|
|
if name[i - 1] in [" ", "_"]:
|
|
abbrev += name[i]
|
|
return abbrev
|
|
|
|
# Campaigns
|
|
x = _("TitleScreen button^Campaign")
|
|
write("<th>%s</th></tr><tr><td>" % x)
|
|
cids = [[], []]
|
|
for cid in self.wesnoth.campaign_lookup.keys():
|
|
if cid in self.wesnoth.is_mainline_campaign:
|
|
cids[0].append(cid)
|
|
else:
|
|
cids[1].append(cid)
|
|
|
|
for i in range(2):
|
|
cnames = cids[i]
|
|
cnames.sort()
|
|
for cname in cnames:
|
|
lang = self.isocode
|
|
if cname == "mainline":
|
|
campname = self.get_translation("wesnoth", "Multiplayer")
|
|
campabbrev = campname
|
|
else:
|
|
campname = self.wesnoth.campaign_lookup[cname].get_text_val("name")
|
|
if not campname:
|
|
campname = cname
|
|
campabbrev = self.wesnoth.campaign_lookup[cname].get_text_val("abbrev")
|
|
if not campabbrev:
|
|
campabbrev = abbrev(campname)
|
|
|
|
write(" <a title=\"%s\" href=\"../%s/%s.html\">%s</a><br/>\n" % (
|
|
campname, lang, cname, campabbrev))
|
|
if i == 0 and cids[1]:
|
|
write("-<br/>\n")
|
|
write("</td>\n")
|
|
write("</tr>\n")
|
|
|
|
# Eras
|
|
write("<tr>\n")
|
|
x = _("Era")
|
|
write("<th>%s</th></tr><tr><td>" % x)
|
|
eids = [[], []]
|
|
for eid in self.wesnoth.era_lookup.keys():
|
|
if eid in self.wesnoth.is_mainline_era:
|
|
eids[0].append(eid)
|
|
else:
|
|
eids[1].append(eid)
|
|
for i in range(2):
|
|
eranames = [(self.wesnoth.era_lookup[eid].get_text_val("name"),
|
|
eid) for eid in eids[i]]
|
|
eranames.sort()
|
|
for eraname, eid in eranames:
|
|
write(" <a title=\"%s\" href=\"../%s/%s.html\">%s</a><br/>" % (
|
|
eraname, lang, eid, abbrev(eraname)))
|
|
if i == 0 and eids[1]:
|
|
write("-<br/>\n")
|
|
write("</td>\n")
|
|
write("</tr>\n")
|
|
|
|
# Races
|
|
if self.campaign == "mainline":
|
|
write("<tr>\n")
|
|
x = _("Race")
|
|
write("<th>%s</th></tr><tr><td>" % x)
|
|
write("<a href=\"mainline.html\">%s</a><br/>\n" % (
|
|
self.get_translation("wesnoth-editor", "all")))
|
|
racenames = {}
|
|
for u in self.wesnoth.unit_lookup.values():
|
|
if u.campaign != self.campaign: continue
|
|
race = u.race
|
|
racename = race.get_text_val("plural_name")
|
|
racenames[racename] = race.get_text_val("id")
|
|
racenames = racenames.items()
|
|
racenames.sort()
|
|
|
|
for racename, rid in racenames:
|
|
write(" <a href=\"mainline.html#%s\">%s</a><br/>" % (
|
|
racename, racename))
|
|
write("</td>\n")
|
|
write("</tr>\n")
|
|
|
|
# Languages
|
|
write("<tr>\n")
|
|
x = _("Language")
|
|
write("<th>%s</th></tr><tr><td>" % x)
|
|
for lang in langlist:
|
|
labb = lang
|
|
underscore = labb.find("_")
|
|
if underscore > 0: labb = labb[:underscore]
|
|
write(" <a title=\"%s\" href=\"../%s/%s\">%s</a><br/>\n" % (
|
|
languages[lang], lang, self.target,
|
|
labb))
|
|
write("</td>\n")
|
|
write("</tr>\n")
|
|
|
|
write("</table>\n")
|
|
|
|
def pic(self, u, x):
|
|
image = self.wesnoth.get_unit_value(x, "image")
|
|
if not image:
|
|
if x.name == "female":
|
|
baseunit = self.wesnoth.get_base_unit(u)
|
|
if baseunit:
|
|
female = baseunit.get_first("female")
|
|
return self.pic(u, female)
|
|
sys.stderr.write(
|
|
"Warning: Missing image for unit %s(%s).\n" % (
|
|
u.get_text_val("id"), x.name))
|
|
return None
|
|
picname = image_collector.add_image(u.campaign, image)
|
|
image = os.path.join("../pics", picname)
|
|
return image
|
|
|
|
def write_units(self):
|
|
def write(x): self.output.write(x)
|
|
rows = self.unitgrid
|
|
write("<table class=\"units\">\n")
|
|
write("<colgroup>")
|
|
for i in range(6):
|
|
write("<col class=\"col%d\" />" % i)
|
|
write("</colgroup>")
|
|
for row in range(len(rows)):
|
|
write("<tr>\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):
|
|
racename = un.name
|
|
attributes += " class=\"raceheader\""
|
|
write("<td%s>" % attributes)
|
|
write("<a name=\"%s\">%s</a>" % (racename, racename))
|
|
write("</td>\n")
|
|
elif un:
|
|
u = un.unit
|
|
attributes += " class=\"unitcell\""
|
|
write("<td%s>" % attributes)
|
|
|
|
uid = u.get_text_val("id")
|
|
name = self.wesnoth.get_unit_value(u, "name")
|
|
cost = self.wesnoth.get_unit_value(u, "cost")
|
|
hp = self.wesnoth.get_unit_value(u, "hitpoints")
|
|
mp = self.wesnoth.get_unit_value(u, "movement")
|
|
xp = self.wesnoth.get_unit_value(u, "experience")
|
|
level = self.wesnoth.get_unit_value(u, "level")
|
|
|
|
|
|
write("<div class=\"l\">L%s</div>" % level)
|
|
link = "../%s/%s.html" % (self.isocode, uid)
|
|
write("<a href=\"%s\">%s</a><br/>" % (link, name))
|
|
|
|
write('<div class="pic">')
|
|
image = self.pic(u, u)
|
|
write('<a href=\"%s\"><img src="%s" alt="(image)" /></a>\n' % (
|
|
link, image))
|
|
write('</div>\n')
|
|
write("<div class=\"attributes\">")
|
|
write("%s%s<br />" % (
|
|
self.get_translation("wesnoth", "Cost: "), cost))
|
|
write("%s%s<br />" % (
|
|
self.get_translation("wesnoth", "HP: "), hp))
|
|
write("%s%s<br />" % (
|
|
self.get_translation("wesnoth", "MP: "), mp))
|
|
write("%s%s<br />" % (
|
|
self.get_translation("wesnoth", "XP: "), xp))
|
|
write("</div>")
|
|
write("</td>\n")
|
|
else:
|
|
write("<td class=\"empty\"></td>")
|
|
write("</tr>\n")
|
|
write("</table>\n")
|
|
|
|
def write_units_tree(self, grouper, title):
|
|
self.output.write(html_header % {"path" : "../"})
|
|
|
|
self.analyze_units(grouper)
|
|
self.write_navbar()
|
|
|
|
self.output.write("<h1>%s</h1>" % title)
|
|
|
|
self.write_units()
|
|
|
|
self.output.write(html_footer)
|
|
|
|
def write_unit_report(self, output, unit):
|
|
def write(x): self.output.write(x)
|
|
def _(x): return self.get_translation("wesnoth", x)
|
|
|
|
def find_attr(what, key):
|
|
if unit.movetype:
|
|
mtx = unit.movetype.get_first(what)
|
|
mty = None
|
|
if mtx: mty = mtx.get_text_val(key)
|
|
x = unit.get_first(what)
|
|
y = None
|
|
if x: y = x.get_text_val(key)
|
|
if y:
|
|
return True, y
|
|
if unit.movetype and mty != None:
|
|
return False, mty
|
|
return False, "-"
|
|
|
|
self.output = output
|
|
write(html_header % {"path" : "../"})
|
|
self.write_navbar()
|
|
|
|
# Write unit name, picture and description.
|
|
uid = unit.get_text_val("id")
|
|
uname = self.wesnoth.get_unit_value(unit, "name")
|
|
display_name = uname
|
|
|
|
female = unit.get_first("female")
|
|
if female:
|
|
fname = female.get_text_val("name")
|
|
if fname and fname != uname:
|
|
display_name += "<br/>" + fname
|
|
|
|
write("<h1>%s</h1>\n" % display_name)
|
|
|
|
write('<div class="pic">')
|
|
if female:
|
|
mimage = self.pic(unit, unit)
|
|
fimage = self.pic(unit, female)
|
|
if not fimage: fimage = mimage
|
|
write('<img src="%s" alt="(image)" />\n' % mimage)
|
|
write('<img src="%s" alt="(image)" />\n' % fimage)
|
|
else:
|
|
image = self.pic(unit, unit)
|
|
write('<img src="%s" alt="(image)" />\n' % image)
|
|
write('</div>\n')
|
|
|
|
description = unit.get_text_val("description")
|
|
if not description: description = unit.get_text_val("unit_description")
|
|
if not description: description = "-"
|
|
write("<p>%s</p>\n" % description)
|
|
|
|
# Base info.
|
|
hp = self.wesnoth.get_unit_value(unit, "hitpoints")
|
|
mp = self.wesnoth.get_unit_value(unit, "movement")
|
|
xp = self.wesnoth.get_unit_value(unit, "experience")
|
|
level = self.wesnoth.get_unit_value(unit, "level")
|
|
alignment = self.wesnoth.get_unit_value(unit, "alignment")
|
|
|
|
write("<table class=\"unitinfo\">\n")
|
|
write("<tr>\n")
|
|
write("<th>%s" % _("Advances from: "))
|
|
write("</th><td>\n")
|
|
for pid in self.forest.get_parents(uid):
|
|
punit = self.wesnoth.unit_lookup[pid]
|
|
if unit.campaign == "mainline" and punit.campaign != "mainline":
|
|
continue
|
|
link = "../%s/%s.html" % (self.isocode, pid)
|
|
name = self.wesnoth.get_unit_value(punit, "name")
|
|
write("\n<a href=\"%s\">%s</a>" % (link, name))
|
|
write("</td>\n")
|
|
write("</tr><tr>\n")
|
|
write("<th>%s" % self.get_translation("wesnoth", "Advances to: "))
|
|
write("</th><td>\n")
|
|
for cid in self.forest.get_children(uid):
|
|
link = "../%s/%s.html" % (self.isocode, cid)
|
|
try:
|
|
cunit = self.wesnoth.unit_lookup[cid]
|
|
if unit.campaign == "mainline" and cunit.campaign != "mainline":
|
|
continue
|
|
name = self.wesnoth.get_unit_value(cunit, "name")
|
|
except KeyError:
|
|
sys.stderr.write("Warning: Unit %s not found.\n" % cid)
|
|
name = cid
|
|
if unit.campaign == "mainline": continue
|
|
write("\n<a href=\"%s\">%s</a>" % (link, name))
|
|
write("</td>\n")
|
|
write("</tr>\n")
|
|
|
|
for val, text in [
|
|
("cost", _("Cost: ")),
|
|
("hitpoints", _("HP: ")),
|
|
("movement", _("Movement") + ": "),
|
|
("experience", _("XP: ")),
|
|
("level", _("Level") + ": "),
|
|
("alignment", _("Alignment: "))]:
|
|
write("<tr>\n")
|
|
write("<th>%s</th>" % text)
|
|
x = self.wesnoth.get_unit_value(unit, val)
|
|
if val == "alignment": x = self.get_translation("wesnoth", x)
|
|
write("<td>%s</td>" % x)
|
|
write("</tr>\n")
|
|
write("</table>\n")
|
|
|
|
# Write info about attacks.
|
|
write("<table class=\"unitinfo\">\n")
|
|
for attack in unit.get_all("attack"):
|
|
write("<tr>")
|
|
|
|
aid = attack.get_text_val("name")
|
|
aname = attack.get_text_val("description")
|
|
|
|
icon = attack.get_text_val("icon")
|
|
if not icon:
|
|
icon = "attacks/%s.png" % aid
|
|
picname = image_collector.add_image(unit.campaign, icon)
|
|
icon = os.path.join("../pics", picname)
|
|
write("<td><img src=\"%s\" alt=\"(image)\"/></td>" % icon)
|
|
|
|
write("<td>%s" % aname)
|
|
|
|
t = attack.get_text_val("type")
|
|
write("<br/>%s</td>" % self.get_translation("wesnoth", t))
|
|
|
|
n = attack.get_text_val("number")
|
|
x = attack.get_text_val("damage")
|
|
x = "%s - %s" % (x, n)
|
|
write("<td>%s" % x)
|
|
|
|
r = attack.get_text_val("range")
|
|
write("<br/>%s</td>" % self.get_translation("wesnoth", r))
|
|
|
|
s = []
|
|
specials = attack.get_first("specials")
|
|
if specials:
|
|
for special in specials.children():
|
|
sname = special.get_text_val("name")
|
|
if sname:
|
|
s.append(sname)
|
|
else:
|
|
sys.stderr.write(
|
|
"Warning: Weapon special %s has no name for %s.\n" % (
|
|
special.name, uid))
|
|
s = "<br/>".join(s)
|
|
write("<td>%s</td>" % s)
|
|
|
|
|
|
write("</tr>")
|
|
write("</table>\n")
|
|
|
|
# Write info about resistances.
|
|
resistances = [
|
|
"blade",
|
|
"pierce",
|
|
"impact",
|
|
"fire",
|
|
"cold",
|
|
"arcane"]
|
|
|
|
write("<table class=\"unitinfo\">\n")
|
|
write("<tr>\n")
|
|
write("<th colspan=\"2\">%s</th>\n" %
|
|
self.get_translation("wesnoth", "Resistances: "))
|
|
|
|
write("</tr>\n")
|
|
for rid in resistances:
|
|
special, r = find_attr("resistance", rid)
|
|
if r == "-": r = 0
|
|
try: r = "%d%%" % (100 - int(r))
|
|
except ValueError:
|
|
sys.stderr.write("Warning: Invalid resistance %s for %s.\n" % (
|
|
r, uid))
|
|
rcell = "td"
|
|
if special: rcell += ' class="special"'
|
|
write("<tr>\n")
|
|
write("<th>%s</th><td>%s</td>\n" % (
|
|
self.get_translation("wesnoth", rid), r))
|
|
write("</tr>\n")
|
|
write("</table>\n")
|
|
|
|
# Write info about movement costs and terrain defense.
|
|
write("<table class=\"unitinfo\">\n")
|
|
write("<tr>\n")
|
|
write("<th>%s</th><th>%s</th><th>%s</th>\n" % (
|
|
_("Terrain"), _("Movement Cost"), _("Defense") ))
|
|
write("</tr>\n")
|
|
|
|
terrains = self.wesnoth.terrain_lookup
|
|
terrainlist = []
|
|
for tid, t in terrains.items():
|
|
if tid in ["off_map", "fog", "shroud"]: continue
|
|
if t.get_first("aliasof"): continue
|
|
name = t.get_text_val("name")
|
|
terrainlist.append((name, tid))
|
|
terrainlist.sort()
|
|
|
|
for tname, tid 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 = 0
|
|
try: d = "%d%%" % (100 - int(d))
|
|
except ValueError:
|
|
sys.stderr.write("Warning: Invalid defense %s for %s.\n" % (
|
|
d, uid))
|
|
|
|
write("<tr>\n")
|
|
write("<td>%s</td><%s>%s</td><%s>%s</td>\n" % (
|
|
tname, ccell, c, dcell, d))
|
|
write("</tr>\n")
|
|
write("</table>\n")
|
|
|
|
write(html_footer)
|
|
|
|
languages_found = {}
|
|
def find_languages():
|
|
"""
|
|
Returns a dictionary mapping isocodes to languages.
|
|
"""
|
|
global languages
|
|
if languages_found: return languages_found
|
|
parser = wmlparser.Parser(datadir)
|
|
WML = wmldata.DataSub("WML")
|
|
parser.parse_text("{languages}\n")
|
|
parser.parse_top(WML)
|
|
|
|
for locale in WML.get_all("locale"):
|
|
isocode = locale.get_text_val("locale")
|
|
name = locale.get_text_val("name")
|
|
languages_found[isocode] = name
|
|
return languages_found
|
|
|
|
class MyFile:
|
|
"""
|
|
I don't understand why this is needed..
|
|
"""
|
|
def __init__(self, filename, mode):
|
|
self.f = open(filename, mode)
|
|
def write(self, x):
|
|
x = x.encode("utf8")
|
|
self.f.write(x)
|
|
def close(self):
|
|
self.f.close()
|
|
|
|
def generate_campaign_report(out_path, isocode, campaign, wesnoth):
|
|
print "Generating report for %s_%s." % (isocode, campaign)
|
|
path = os.path.join(out_path, isocode )
|
|
if not os.path.isdir(path): os.mkdir(path)
|
|
output = MyFile(os.path.join(path, "%s.html" % campaign), "w")
|
|
html = HTMLOutput(isocode, output, campaign, wesnoth)
|
|
html.target = "%s.html" % campaign
|
|
grouper = GroupByRace(wesnoth, campaign)
|
|
|
|
if campaign == "mainline":
|
|
title = html.get_translation("wesnoth", "Multiplayer")
|
|
else:
|
|
title = wesnoth.campaign_lookup[campaign].get_text_val("name")
|
|
if not title:
|
|
title = campaign
|
|
|
|
html.write_units_tree(grouper, title)
|
|
|
|
def generate_era_report(out_path, isocode, eid, wesnoth):
|
|
print "Generating report for %s_%s." % (isocode, eid)
|
|
path = os.path.join(out_path, isocode)
|
|
if not os.path.isdir(path): os.mkdir(path)
|
|
|
|
era = wesnoth.era_lookup[eid]
|
|
ename = era.get_text_val("name")
|
|
output = MyFile(os.path.join(path, "%s.html" % eid), "w")
|
|
|
|
html = HTMLOutput(isocode, output, eid, wesnoth)
|
|
html.target = "%s.html" % eid
|
|
grouper = GroupByFaction(wesnoth, eid)
|
|
title = ename
|
|
html.write_units_tree(grouper, title)
|
|
|
|
def generate_single_unit_reports(out_path, isocode, wesnoth):
|
|
|
|
odir = os.path.join(out_path, isocode)
|
|
if not os.path.isdir(odir):
|
|
os.mkdir(odir)
|
|
|
|
html = HTMLOutput(isocode, None, "units", wesnoth)
|
|
grouper = GroupByRace(wesnoth, None)
|
|
html.analyze_units(grouper)
|
|
|
|
for uid, unit in wesnoth.unit_lookup.items():
|
|
output = MyFile(os.path.join(odir, "%s.html" % uid), "w")
|
|
html.target = "%s.html" % uid
|
|
html.write_unit_report(output, unit)
|
|
|
|
def write_index(out_path):
|
|
output = MyFile(os.path.join(out_path, "index.html"), "w")
|
|
output.write("""
|
|
<html><head>
|
|
<meta http-equiv="refresh" content="0;url=C/mainline.html">
|
|
</head>
|
|
<body>
|
|
<a href="C/mainline.html">Redirecting to Wesnoth units database...</a>
|
|
</body>
|
|
</html>
|
|
""")
|
|
|
|
def output(isocode):
|
|
"""
|
|
We output:
|
|
* All mainline units sorted by race
|
|
* Each mainline era's units sorted by faction
|
|
* Each mainline campaign's units sorted by race
|
|
* Each addon era's units sorted by faction
|
|
* Each addon campaign's units sorted by race
|
|
"""
|
|
print "WML parser language reset to %s." % isocode
|
|
|
|
stuff = helpers.WesnothList(isocode, datadir, userdir, transdir)
|
|
|
|
# Parse some stuff we may need.
|
|
print "Parsing terrains ...",
|
|
n = stuff.add_terrains()
|
|
print "%d terrains found." % n
|
|
|
|
print "Parsing mainline eras ...",
|
|
n = stuff.add_mainline_eras()
|
|
print "%d mainline eras found." % n
|
|
stuff.is_mainline_era = {}
|
|
for c in stuff.era_lookup.keys():
|
|
stuff.is_mainline_era[c] = True
|
|
|
|
print "Parsing mainline campaigns ...",
|
|
n = stuff.add_mainline_campaigns()
|
|
print "%d mainline campaigns found." % n
|
|
stuff.is_mainline_campaign = {}
|
|
for c in stuff.campaign_lookup.keys():
|
|
stuff.is_mainline_campaign[c] = True
|
|
|
|
# Parse all unit data
|
|
# This reads in units.cfg, giving us all the mainline units.
|
|
print "Parsing mainline units ...",
|
|
sys.stdout.flush()
|
|
WML = stuff.parser.parse("{core/units.cfg}")
|
|
n = stuff.add_units(WML, "mainline")
|
|
print n, "mainline units found."
|
|
|
|
# Now we read each campaign in turn to get its units.
|
|
cnames = stuff.campaign_lookup.keys()
|
|
for cname in cnames:
|
|
print "Parsing %s units ..." % cname,
|
|
sys.stdout.flush()
|
|
campaign = stuff.campaign_lookup[cname]
|
|
define = campaign.get_text_val("define")
|
|
WML = stuff.parser.parse("""
|
|
#define %s\n#enddef
|
|
{campaigns}""" % define,
|
|
ignore_macros = lambda x: x.find("/scenarios") == -1)
|
|
n = stuff.add_units(WML, cname)
|
|
image_collector.add_binary_pathes_from_WML(cname, WML)
|
|
print n, "units found."
|
|
|
|
print "Parsing addons ...",
|
|
n = stuff.add_addons(image_collector)
|
|
print "%d units found." % n
|
|
|
|
stuff.find_unit_factions()
|
|
|
|
# Report generation
|
|
if not os.path.isdir(options.output):
|
|
os.mkdir(options.output)
|
|
write_index(options.output)
|
|
|
|
|
|
campaigns = stuff.campaign_lookup.keys()
|
|
|
|
generate_campaign_report(options.output, isocode, "mainline", stuff)
|
|
|
|
for campaign in campaigns:
|
|
generate_campaign_report(options.output, isocode, campaign, stuff)
|
|
|
|
for eid in stuff.era_lookup.keys():
|
|
generate_era_report(options.output, isocode, eid, stuff)
|
|
|
|
# Write a list with all unit ids, just for fun.
|
|
uids = stuff.unit_lookup.keys()
|
|
uids.sort()
|
|
f = MyFile(os.path.join(options.output, "uids.html"), "w")
|
|
f.write("<html><body>")
|
|
f.write("<ul>" + "\n".join(["<li>%s</li>" % x for x in uids]))
|
|
f.write("</body></html>")
|
|
f.close()
|
|
|
|
# Single unit reports.
|
|
generate_single_unit_reports(options.output, isocode, stuff)
|
|
|
|
if __name__ == '__main__':
|
|
global options
|
|
global image_collector
|
|
import optparse
|
|
|
|
op = optparse.OptionParser()
|
|
op.add_option("-l", "--language", default = "all",
|
|
help = "Specify a language.")
|
|
op.add_option("-o", "--output",
|
|
help = "Specify output directory.")
|
|
op.add_option("-n", "--nocopy", action = "store_true",
|
|
help = "No copying of files.")
|
|
op.add_option("-d", "--datadir",
|
|
help = "Specify Wesnoth's data to use. Default is to search current "+\
|
|
"directory upwards.")
|
|
op.add_option("-u", "--userdir",
|
|
help = "Specify user data dir to use, which is automatically scanned "+\
|
|
"for addons. For example -u ~/.wesnoth/data")
|
|
op.add_option("-t", "--transdir",
|
|
help = "Specify directory which has a po subfolder for translations.")
|
|
options, args = op.parse_args()
|
|
|
|
if not options.output:
|
|
op.print_help()
|
|
sys.exit(-1)
|
|
|
|
options.output = os.path.expanduser(options.output)
|
|
|
|
if not options.datadir:
|
|
wmltools.pop_to_top("wmlunits")
|
|
datadir = os.getcwd() + "/data"
|
|
else:
|
|
datadir = options.datadir
|
|
|
|
userdir = options.userdir
|
|
if options.transdir:
|
|
transdir = options.transdir
|
|
else:
|
|
transdir = os.path.dirname(datadir)
|
|
|
|
if options.language == "all":
|
|
languages = find_languages().keys()
|
|
languages.sort()
|
|
else:
|
|
languages = [options.language]
|
|
|
|
image_collector = helpers.ImageCollector(datadir, userdir)
|
|
|
|
for isocode in languages:
|
|
output(isocode)
|
|
|
|
if not options.nocopy:
|
|
print "Copying files."
|
|
image_collector.copy_and_color_images(options.output)
|
|
shutil.copy2(os.path.join("data", "tools/unit_tree/style.css"), options.output)
|
|
for grab in [
|
|
"http://www.wesnoth.org/mw/skins/glamdrol/headerbg.jpg",
|
|
"http://www.wesnoth.org/mw/skins/glamdrol/wesnoth-logo.jpg",
|
|
"http://www.wesnoth.org/mw/skins/glamdrol/navbg.png"]:
|
|
local = os.path.join(options.output, grab[grab.rfind("/") + 1:])
|
|
if not os.path.exists(local):
|
|
print "Fetching", grab
|
|
url = urllib2.urlopen(grab)
|
|
file(local, "w").write(url.read())
|
|
|