wesnoth/data/tools/wmlunits

1035 lines
36 KiB
Plaintext
Raw Normal View History

#!/usr/bin/env python
#encoding: utf8
"""
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
2008-04-09 16:56:58 +00:00
import sys, os, re, glob, shutil, copy, urllib2
import wesnoth.wmldata as wmldata
import wesnoth.wmlparser as wmlparser
2008-03-31 09:58:49 +00:00
import wesnoth.wmltools as wmltools
sys.path.append(".")
import unit_tree.helpers as helpers
import unit_tree.animations as animations
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/Wesnoth:Copyrights">Copyright</a> &copy; 2003-2008 The Battle for Wesnoth</p>
<p>Supported by <a href="http://www.jexiste.fr/">Jexiste</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..
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:
sys.stderr.write(
"Warning: Unit %s not found as advancement of %s\n" %
(auid, uid))
continue
forest.add_node(helpers.UnitNode(au))
new_units_added[auid] = au
units_added = new_units_added
forest.update()
2008-04-09 16:56:58 +00:00
# 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
2008-04-09 16:56:58 +00:00
thelist = groups.keys()
thelist.sort()
2008-04-09 16:56:58 +00:00
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)
2008-04-09 16:56:58 +00:00
self.unitgrid = rows
def write_navbar(self):
def write(x): self.output.write(x)
2008-04-09 16:56:58 +00:00
def _(x): return self.get_translation("wesnoth", x)
languages = find_languages()
langlist = languages.keys()
langlist.sort()
2008-04-09 16:56:58 +00:00
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]
word_seperators = [" ", "_", "+", "(", ")"]
for i in range(1, len(name)):
if name[i] in ["+", "(", ")"] or name[i - 1] in word_seperators and name[i] not in word_seperators:
abbrev += name[i]
return abbrev
2008-04-09 16:56:58 +00:00
# Campaigns
2008-04-09 16:56:58 +00:00
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")
2008-04-09 16:56:58 +00:00
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 get_abilities(self, u):
anames = []
already = {}
for abilities in u.get_all("abilities"):
try: c = abilities.children()
except AttributeError: c = []
for ability in c:
id = ability.get_text_val("id")
if id in already: continue
already[id] = True
name = ability.get_text_val("name")
if not name: name = id
if not name: name = ability.name
anames.append(name)
return anames
2008-10-03 15:00:16 +00:00
def get_recursive_attacks(self, this_unit):
def copy_attributes(copy_from, copy_to):
for c in copy_from.children():
if isinstance(c, wmldata.DataText):
copy_to.set_text_val(c.name, c.data)
# 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 = self.get_recursive_attacks(base_unit)
base_attacks_count = len(attacks)
2008-10-03 15:00:16 +00:00
for i, attack in enumerate(this_unit.get_all("attack")):
2008-10-03 15:03:56 +00:00
# Attack merging is order based.
if i < base_attacks_count:
2008-10-03 15:00:16 +00:00
copy_attributes(attack, attacks[i])
2008-10-03 15:03:56 +00:00
else:
attacks.append(attack)
2008-10-03 15:00:16 +00:00
return attacks
def write_units(self):
def write(x): self.output.write(x)
def _(x): return self.get_translation("wesnoth", x)
rows = self.unitgrid
write("<table class=\"units\">\n")
write("<colgroup>")
for i in range(6):
write("<col class=\"col%d\" />" % i)
write("</colgroup>")
pic = image_collector.add_image("mainline",
"../../../images/misc/leader-crown.png")
crownimage = os.path.join("../pics", pic)
ms = None
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):
# Find the current multiplayer side so we can show the
# little crowns..
ms = None
try:
eid, fid = un.data
era = self.wesnoth.era_lookup[eid]
ms = era.faction_lookup[fid]
except TypeError:
pass
2008-04-09 16:56:58 +00:00
racename = un.name
attributes += " class=\"raceheader\""
write("<td%s>" % attributes)
2008-04-09 16:56:58 +00:00
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")
crown = ""
if ms:
if un.id in ms.units:
crown = u" ♟"
if un.id in ms.is_leader:
crown = u" ♚"
link = "../%s/%s.html" % (self.isocode, uid)
write("<div class=\"i\"><a href=\"%s\" title=\"id=%s\">%s</a>" % (
link, uid, u""))
write("</div>")
write("<div class=\"l\">L%s%s</div>" % (level, crown))
write("<a href=\"%s\">%s</a><br/>" % (link, name))
write('<div class="pic">')
image = self.pic(u, u)
write('<a href=\"%s\">' % link)
if crown == u" ♚":
write('<div style="background: url(%s)">' % image)
write('<img src="%s" alt="(image)" />' % crownimage)
write("</div>")
else:
write('<img src="%s" alt="(image)" />' % image)
write('</a>\n</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 info about abilities.
anames = self.get_abilities(u)
if anames:
write("\n<div style=\"clear:both\">")
write(", ".join(anames))
write("</div>")
# Write info about attacks.
write("\n<div style=\"clear:both\">")
2008-10-03 15:00:16 +00:00
attacks = self.get_recursive_attacks(u)
for attack in attacks:
n = attack.get_text_val("number")
x = attack.get_text_val("damage")
x = "%s - %s" % (x, n)
write("%s " % x)
r = attack.get_text_val("range")
t = attack.get_text_val("type")
write("%s (%s)" % (_(r), _(t)))
s = []
specials = attack.get_first("specials")
if specials:
for special in specials.children():
sname = special.get_text_val("name")
if sname:
s.append(sname)
s = ", ".join(s)
write(" (%s)" % s)
write("<br />")
write("</div>")
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" : "../"})
2008-04-09 16:56:58 +00:00
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)
2008-04-09 16:56:58 +00:00
def _(x): return self.get_translation("wesnoth", x)
2008-04-09 16:56:58 +00:00
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 = self.wesnoth.get_unit_value(unit, "description")
# TODO: what is unit_description?
if not description: description = unit.get_text_val("unit_description")
if not description: description = "-"
write("<p>%s</p>\n" % __import__('re').sub("\n","\n<br />", 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")
2008-04-09 16:56:58 +00:00
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")
2008-04-09 16:56:58 +00:00
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
2008-04-09 16:56:58 +00:00
write("\n<a href=\"%s\">%s</a>" % (link, name))
write("</td>\n")
write("</tr>\n")
2008-04-09 16:56:58 +00:00
for val, text in [
("cost", _("Cost: ")),
("hitpoints", _("HP: ")),
("movement", _("Movement") + ": "),
("experience", _("XP: ")),
("level", _("Level") + ": "),
("alignment", _("Alignment: ")),
("id", "ID")]:
write("<tr>\n")
2008-04-09 16:56:58 +00:00
write("<th>%s</th>" % text)
x = self.wesnoth.get_unit_value(unit, val)
if val == "alignment": x = self.get_translation("wesnoth", x)
2008-04-09 16:56:58 +00:00
write("<td>%s</td>" % x)
write("</tr>\n")
# Write info about abilities.
anames = self.get_abilities(unit)
write("<tr>\n")
write("<th>%s</th>" % _("Abilities: "))
write("<td>" + (", ".join(anames)) + "</td>")
write("</tr>\n")
write("</table>\n")
# Write info about attacks.
write("<table class=\"unitinfo\">\n")
2008-10-03 15:00:16 +00:00
attacks = self.get_recursive_attacks(unit)
for attack in attacks:
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, error = image_collector.add_image_check(unit.campaign, icon)
if error:
sys.stderr.write("Error: No attack icon '%s' found for '%s'.\n" % (
icon, uid))
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")
2008-04-09 16:56:58 +00:00
# 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: "))
2008-04-09 16:56:58 +00:00
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))
2008-04-09 16:56:58 +00:00
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
2008-04-09 16:56:58 +00:00
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()
2008-04-09 16:56:58 +00:00
for tname, tid in terrainlist:
not_from_race, c = find_attr("movement_costs", tid)
2008-04-09 16:56:58 +00:00
ccell = "td"
if c == "99": ccell += ' class="grayed"'
2008-04-09 16:56:58 +00:00
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))
2008-04-09 16:56:58 +00:00
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")
2008-04-09 16:56:58 +00:00
output.write("""
<html><head>
<meta http-equiv="refresh" content="0;url=C/mainline.html">
2008-04-09 16:56:58 +00:00
</head>
<body>
<a href="C/mainline.html">Redirecting to Wesnoth units database...</a>
2008-04-09 16:56:58 +00:00
</body>
</html>
""")
def copy_images():
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())
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 mainline 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."
sys.stderr.flush()
print "Parsing addons ...",
sys.stdout.flush()
n = stuff.add_addons(image_collector)
print "%d units found." % n
# Now we read each addon campaign in turn to get its units.
cnames = stuff.campaign_lookup.keys()
for cname in cnames:
if cname in stuff.is_mainline_campaign: continue
campaign = stuff.campaign_lookup[cname]
print "Parsing %s units ..." % cname,
sys.stdout.flush()
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."
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()
2008-03-31 09:58:49 +00:00
generate_campaign_report(options.output, isocode, "mainline", stuff)
2008-03-31 09:58:49 +00:00
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)
# Single unit reports.
generate_single_unit_reports(options.output, isocode, stuff)
return 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 the directory which has a po subfolder for translations. "+\
"(Defaults to the current directory.)")
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.getcwd()
if options.language == "all":
languages = find_languages().keys()
languages.sort()
else:
languages = [options.language]
image_collector = helpers.ImageCollector(datadir, userdir)
once_without_translation = False
for isocode in languages:
wesnoth = output(isocode)
if not once_without_translation:
copy_images()
once_without_translation = True
for u in wesnoth.unit_lookup.values():
r = u.race
if r: r = r.get_text_val("id", "none")
else: r = "none"
# Store rid and id for each units so we have it easier
u.rid = r
u.id = u.get_text_val("id")
# Write a list with all unit ids, just for fun.
uids = wesnoth.unit_lookup.keys()
def by_race(u1, u2):
r = cmp(wesnoth.unit_lookup[u1].rid,
wesnoth.unit_lookup[u2].rid)
if r == 0: r = cmp(u1, u2)
return r
uids.sort(by_race)
race = None
f = MyFile(os.path.join(options.output, "uids.html"), "w")
f.write("<html><body>")
for uid in uids:
u = wesnoth.unit_lookup[uid]
if u.race != race:
if race != None: f.write("</ul>")
f.write("<p>%s</p>\n" % u.rid)
f.write("<ul>")
race = u.race
f.write("<li>%s</li>\n" % uid)
f.write("</ul>")
f.write("</body></html>")
f.close()
# Write animation statistics
f = MyFile(os.path.join(options.output, "animations.html"), "w")
animations.write_table(f, wesnoth)
f.close()
2008-03-31 09:58:49 +00:00