Merge branch 'staging/wesmere-wmlunits'
This commit is contained in:
commit
086de4a897
6 changed files with 1089 additions and 1145 deletions
|
@ -1,19 +1,21 @@
|
|||
"""
|
||||
Various helpers for use by the wmlunits tool.
|
||||
"""
|
||||
import sys, os, re, glob, shutil, copy, urllib.request, urllib.error, urllib.parse, subprocess
|
||||
import sys, os, re, glob, shutil, copy, subprocess
|
||||
|
||||
import wesnoth.wmlparser3 as wmlparser3
|
||||
|
||||
def get_datadir(wesnoth_exe):
|
||||
p = subprocess.Popen([wesnoth_exe, "--path"],
|
||||
stdout = subprocess.PIPE, stderr = subprocess.PIPE)
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE)
|
||||
out, err = p.communicate()
|
||||
return out.strip()
|
||||
|
||||
def get_userdir(wesnoth_exe):
|
||||
p = subprocess.Popen([wesnoth_exe, "--config-path"],
|
||||
stdout = subprocess.PIPE, stderr = subprocess.PIPE)
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE)
|
||||
out, err = p.communicate()
|
||||
return out.strip()
|
||||
|
||||
|
@ -35,50 +37,52 @@ class ImageCollector:
|
|||
self.images_by_ipath = {}
|
||||
self.binary_paths_per_addon = {}
|
||||
self.datadir = datadir
|
||||
if not self.datadir:
|
||||
self.datadir = get_datadir(wesnoth_exe)
|
||||
self.userdir = userdir
|
||||
|
||||
if not self.datadir: self.datadir = get_datadir(wesnoth_exe)
|
||||
if not self.userdir: self.userdir = get_userdir(wesnoth_exe)
|
||||
if not self.userdir:
|
||||
self.userdir = get_userdir(wesnoth_exe)
|
||||
|
||||
def add_binary_paths_from_WML(self, addon, WML):
|
||||
for binpath in WML.get_all(tag = "binary_path"):
|
||||
for binpath in WML.get_all(tag="binary_path"):
|
||||
path = binpath.get_text_val("path")
|
||||
if addon not in self.binary_paths_per_addon:
|
||||
self.binary_paths_per_addon[addon] = []
|
||||
self.binary_paths_per_addon[addon].append(path)
|
||||
|
||||
def _find_image(self, addon, name):
|
||||
|
||||
tilde = name.find("~")
|
||||
if tilde >= 0:
|
||||
name = name[:tilde]
|
||||
|
||||
bases = [os.path.join(self.datadir, "data/core/images")]
|
||||
binpaths = self.binary_paths_per_addon.get(addon, [])[:]
|
||||
binpaths.reverse()
|
||||
for x in binpaths:
|
||||
for path in binpaths:
|
||||
for idir in ["images", "images/units"]:
|
||||
bases.append(os.path.join(self.datadir, x, idir))
|
||||
bases.append(os.path.join(self.userdir, x, idir))
|
||||
bases.append(os.path.join(self.datadir, path, idir))
|
||||
bases.append(os.path.join(self.userdir, path, idir))
|
||||
|
||||
bases = [os.path.join("%s" % base, name) for base in bases]
|
||||
|
||||
for ipath in bases:
|
||||
if os.path.exists(ipath): return ipath, bases
|
||||
if os.path.exists(ipath):
|
||||
return ipath, bases
|
||||
return None, bases
|
||||
|
||||
def add_image_check(self, addon, name, no_tc = False):
|
||||
def add_image_check(self, addon, name, no_tc=False):
|
||||
if (addon, name) in self.images_by_addon_name:
|
||||
image = self.images_by_addon_name[(addon, name)]
|
||||
if addon not in image.addons: image.addons.add(addon)
|
||||
if addon not in image.addons:
|
||||
image.addons.add(addon)
|
||||
return image
|
||||
|
||||
ipath, bases = self._find_image(addon, name)
|
||||
if ipath in self.images_by_ipath:
|
||||
image = self.images_by_ipath[ipath]
|
||||
if addon not in image.addons: image.addons.add(addon)
|
||||
if addon not in image.addons:
|
||||
image.addons.add(addon)
|
||||
return image
|
||||
|
||||
|
||||
def make_name(x):
|
||||
x = x.strip("./ ")
|
||||
d = options.config_dir.strip("./ ")
|
||||
|
@ -90,8 +94,10 @@ class ImageCollector:
|
|||
x = x.strip("./ ")
|
||||
y = ""
|
||||
for c in x:
|
||||
if c == "/": c = "$"
|
||||
elif not c.isalnum() and c not in ".+-()[]{}": c = "_"
|
||||
if c == "/":
|
||||
c = "$"
|
||||
elif not c.isalnum() and c not in ".+-()[]{}":
|
||||
c = "_"
|
||||
y += c
|
||||
return y
|
||||
|
||||
|
@ -102,14 +108,14 @@ class ImageCollector:
|
|||
|
||||
image = Image(id_name, ipath, bases, no_tc)
|
||||
image.addons.add(addon)
|
||||
|
||||
|
||||
self.images_by_addon_name[(addon, name)] = image
|
||||
if ipath:
|
||||
self.images_by_ipath[ipath] = image
|
||||
|
||||
|
||||
return image
|
||||
|
||||
def add_image(self, addon, path, no_tc = False):
|
||||
def add_image(self, addon, path, no_tc=False):
|
||||
image = self.add_image_check(addon, path, no_tc)
|
||||
return image.id_name
|
||||
|
||||
|
@ -122,7 +128,7 @@ class ImageCollector:
|
|||
pass
|
||||
|
||||
no_tc = image.no_tc
|
||||
|
||||
|
||||
ipath = os.path.normpath(image.ipath)
|
||||
cdir = os.path.normpath(options.config_dir + "/data/add-ons")
|
||||
if ipath.startswith(cdir):
|
||||
|
@ -134,7 +140,7 @@ class ImageCollector:
|
|||
# We assume TeamColorizer is in the same directory as the
|
||||
# helpers.py currently executing.
|
||||
command = os.path.join(os.path.dirname(__file__),
|
||||
"TeamColorizer")
|
||||
"TeamColorizer")
|
||||
p = subprocess.Popen([command, ipath, opath])
|
||||
p.wait()
|
||||
else:
|
||||
|
@ -160,9 +166,7 @@ class WesnothList:
|
|||
self.movetype_lookup = {}
|
||||
self.era_lookup = {}
|
||||
self.campaign_lookup = {}
|
||||
self.parser = wmlparser3.Parser(wesnoth_exe, config_dir,
|
||||
data_dir)
|
||||
|
||||
self.parser = wmlparser3.Parser(wesnoth_exe, config_dir, data_dir)
|
||||
|
||||
def add_terrains(self):
|
||||
"""
|
||||
|
@ -171,20 +175,21 @@ class WesnothList:
|
|||
self.parser.parse_text("{core/terrain.cfg}\n")
|
||||
|
||||
n = 0
|
||||
for terrain in self.parser.get_all(tag = "terrain_type"):
|
||||
for terrain in self.parser.get_all(tag="terrain_type"):
|
||||
tstring = terrain.get_text_val("string")
|
||||
self.terrain_lookup[tstring] = terrain
|
||||
n += 1
|
||||
return n
|
||||
|
||||
|
||||
def add_languages(self, languages):
|
||||
"""
|
||||
Returns a dictionary mapping isocodes to languages.
|
||||
"""
|
||||
self.languages_found = {}
|
||||
|
||||
parser = wmlparser3.Parser(options.wesnoth, options.config_dir,
|
||||
options.data_dir)
|
||||
parser = wmlparser3.Parser(options.wesnoth,
|
||||
options.config_dir,
|
||||
options.data_dir)
|
||||
parser.parse_text("{languages}")
|
||||
|
||||
for locale in parser.get_all(tag="locale"):
|
||||
|
@ -199,12 +204,14 @@ class WesnothList:
|
|||
For an era, list all factions and units in it.
|
||||
"""
|
||||
eid = era.get_text_val("id")
|
||||
if not eid: return
|
||||
if not eid:
|
||||
return
|
||||
self.era_lookup[eid] = era
|
||||
era.faction_lookup = {}
|
||||
for multiplayer_side in era.get_all(tag = "multiplayer_side"):
|
||||
for multiplayer_side in era.get_all(tag="multiplayer_side"):
|
||||
fid = multiplayer_side.get_text_val("id")
|
||||
if fid == "Random": continue
|
||||
if fid == "Random":
|
||||
continue
|
||||
era.faction_lookup[fid] = multiplayer_side
|
||||
recruit = multiplayer_side.get_text_val("recruit", "").strip()
|
||||
leader = multiplayer_side.get_text_val("leader", "").strip()
|
||||
|
@ -242,7 +249,7 @@ class WesnothList:
|
|||
self.parser.parse_text("{multiplayer/eras.cfg}")
|
||||
|
||||
n = 0
|
||||
for era in self.parser.get_all(tag = "era"):
|
||||
for era in self.parser.get_all(tag="era"):
|
||||
self.add_era(era)
|
||||
n += 1
|
||||
return n
|
||||
|
@ -253,29 +260,29 @@ class WesnothList:
|
|||
we reference them everywhere by this id, and here can add them all to
|
||||
one big collection.
|
||||
"""
|
||||
addunits = self.parser.get_all(tag = "units")
|
||||
addunits += self.parser.get_all(tag = "+units")
|
||||
if not addunits: return 0
|
||||
addunits = self.parser.get_all(tag="units")
|
||||
addunits += self.parser.get_all(tag="+units")
|
||||
if not addunits:
|
||||
return 0
|
||||
|
||||
def getall(oftype):
|
||||
r = []
|
||||
r = []
|
||||
res = []
|
||||
for units in addunits:
|
||||
r += units.get_all(tag = oftype)
|
||||
return r
|
||||
res += units.get_all(tag=oftype)
|
||||
return res
|
||||
|
||||
# Find all unit types.
|
||||
newunits = getall("unit_type") + getall("unit")
|
||||
for unit in newunits:
|
||||
uid = unit.get_text_val("id")
|
||||
unit.id = uid
|
||||
|
||||
if unit.get_text_val("do_not_list", "no") != "no" or\
|
||||
|
||||
if unit.get_text_val("do_not_list", "no") not in ["no", "false"] or \
|
||||
unit.get_text_val("hide_help", "no") not in ["no", "false"]:
|
||||
unit.hidden = True
|
||||
unit.hidden = True
|
||||
else:
|
||||
unit.hidden = False
|
||||
|
||||
|
||||
if uid in self.unit_lookup:
|
||||
unit = self.unit_lookup[uid]
|
||||
# TODO: We might want to compare the two units
|
||||
|
@ -283,16 +290,16 @@ class WesnothList:
|
|||
# to do something clever like rename it...
|
||||
else:
|
||||
self.unit_lookup[uid] = unit
|
||||
if not hasattr(unit, "campaigns"): unit.campaigns = []
|
||||
if not hasattr(unit, "campaigns"):
|
||||
unit.campaigns = []
|
||||
unit.campaigns.append(campaign)
|
||||
|
||||
# Find all races.
|
||||
newraces = getall("race")
|
||||
for race in newraces:
|
||||
rid = race.get_text_val("id")
|
||||
if rid == None:
|
||||
if rid is None:
|
||||
rid = race.get_text_val("name")
|
||||
|
||||
self.race_lookup[rid] = race
|
||||
|
||||
# Find all movetypes.
|
||||
|
@ -314,8 +321,10 @@ class WesnothList:
|
|||
error_message("Warning: No race \"%s\" found (%s).\n" % (
|
||||
race, unit.get_text_val("id")))
|
||||
movetype = self.get_unit_value(unit, "movement_type")
|
||||
try: unit.movetype = self.movetype_lookup[movetype]
|
||||
except KeyError: unit.movetype = None
|
||||
try:
|
||||
unit.movetype = self.movetype_lookup[movetype]
|
||||
except KeyError:
|
||||
unit.movetype = None
|
||||
|
||||
unit.advance = []
|
||||
advanceto = unit.get_text_val("advances_to")
|
||||
|
@ -326,7 +335,6 @@ class WesnothList:
|
|||
for advance in advanceto.split(","):
|
||||
auid = advance.strip()
|
||||
if auid: unit.advance.append(auid)
|
||||
|
||||
# level
|
||||
try:
|
||||
level = int(self.get_unit_value(unit, "level"))
|
||||
|
@ -343,10 +351,9 @@ class WesnothList:
|
|||
"""
|
||||
Once all units have been added, do some checking.
|
||||
"""
|
||||
|
||||
# handle advancefrom tags
|
||||
for uid, unit in list(self.unit_lookup.items()):
|
||||
for advancefrom in unit.get_all(tag = "advancefrom"):
|
||||
for advancefrom in unit.get_all(tag="advancefrom"):
|
||||
fromid = advancefrom.get_text_val("unit")
|
||||
if fromid:
|
||||
try:
|
||||
|
@ -363,7 +370,6 @@ class WesnothList:
|
|||
for unit in list(self.unit_lookup.values()):
|
||||
unit.factions = []
|
||||
unit.eras = []
|
||||
|
||||
for eid, era in list(self.era_lookup.items()):
|
||||
for fid, multiplayer_side in list(era.faction_lookup.items()):
|
||||
for uid in multiplayer_side.units:
|
||||
|
@ -372,15 +378,14 @@ class WesnothList:
|
|||
except KeyError:
|
||||
error_message(
|
||||
("Error: Era '%s' faction '%s' references " +
|
||||
"non-existant unit id '%s'!\n") % (
|
||||
eid,
|
||||
fid,
|
||||
str(uid)))
|
||||
"non-existant unit id '%s'!\n") % (
|
||||
eid,
|
||||
fid,
|
||||
str(uid)))
|
||||
continue
|
||||
if not eid in unit.eras:
|
||||
unit.eras.append(eid)
|
||||
unit.factions.append((eid, fid))
|
||||
|
||||
# as a special case, add units from this addon but with no faction
|
||||
for unit in list(self.unit_lookup.values()):
|
||||
if unit.campaigns[0] == self.cid:
|
||||
|
@ -388,25 +393,25 @@ class WesnothList:
|
|||
if not eid in unit.eras:
|
||||
unit.eras.append(eid)
|
||||
unit.factions.append((eid, None))
|
||||
|
||||
|
||||
def get_base_unit(self, unit):
|
||||
b = unit.get_all(tag = "base_unit")
|
||||
b = unit.get_all(tag="base_unit")
|
||||
if b:
|
||||
b = b[0]
|
||||
buid = b.get_text_val("id")
|
||||
try: baseunit = self.unit_lookup[buid]
|
||||
try:
|
||||
baseunit = self.unit_lookup[buid]
|
||||
except KeyError:
|
||||
error_message(
|
||||
"Warning: No baseunit \"%s\" for \"%s\".\n" % (
|
||||
buid, unit.get_text_val("id")))
|
||||
buid, unit.get_text_val("id")))
|
||||
return None
|
||||
return baseunit
|
||||
return None
|
||||
|
||||
def get_unit_value(self, unit, attribute, default = None, translation = None):
|
||||
def get_unit_value(self, unit, attribute, default=None, translation=None):
|
||||
value = unit.get_text_val(attribute, None, translation)
|
||||
if value == None:
|
||||
if value is None:
|
||||
baseunit = self.get_base_unit(unit)
|
||||
if baseunit:
|
||||
return self.get_unit_value(baseunit, attribute, default, translation)
|
||||
|
@ -438,7 +443,8 @@ class UnitForest:
|
|||
for uid, u in list(self.lookup.items()):
|
||||
for cid in u.child_ids:
|
||||
c = self.lookup.get(cid, None)
|
||||
if not c: continue
|
||||
if not c:
|
||||
continue
|
||||
u.children.append(c)
|
||||
if not uid in c.parent_ids:
|
||||
c.parent_ids.append(uid)
|
||||
|
@ -458,7 +464,7 @@ class UnitForest:
|
|||
if c.id in already:
|
||||
error_message(
|
||||
("Warning: Unit %s advances to unit %s in a loop.\n" %
|
||||
(u.id, c.id)) +
|
||||
(u.id, c.id)) +
|
||||
(" Removing advancement %s.\n" % c.id))
|
||||
u.children.remove(c)
|
||||
for c in u.children:
|
||||
|
@ -469,7 +475,6 @@ class UnitForest:
|
|||
|
||||
def update(self):
|
||||
self.create_network()
|
||||
|
||||
self.breadth = sum([x.update_breadth() for x in list(self.trees.values())])
|
||||
return self.breadth
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,32 +1,80 @@
|
|||
var all = new Array();
|
||||
/*
|
||||
* Popup menu implementation for the Wesnoth units database
|
||||
*/
|
||||
(function() {
|
||||
var menus = [];
|
||||
var visibleMenu = false;
|
||||
|
||||
function toggle_menu(event, id, what) {
|
||||
var e = document.getElementById(id);
|
||||
var show = what;
|
||||
|
||||
/* Since we have Javascript, disable the CSS menu trigger. */
|
||||
if (event.className != "") {
|
||||
event.className = "";
|
||||
e.style.display = 'none';
|
||||
return;
|
||||
function toggleMenu(event, menu)
|
||||
{
|
||||
hideMenus(menu);
|
||||
|
||||
if (!menu.style.display || menu.style.display === "none") {
|
||||
menu.style.display = "block";
|
||||
visibleMenu = true;
|
||||
} else {
|
||||
menu.style.display = "none";
|
||||
visibleMenu = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (show == 0 || show == 1) return;
|
||||
|
||||
if (show == 2) {
|
||||
if (e.style.display == 'block') show = 0;
|
||||
}
|
||||
if (show == 0) {
|
||||
e.style.display = 'none';
|
||||
}
|
||||
else {
|
||||
e.style.display = 'block';
|
||||
all[id] = 1;
|
||||
for (mid in all) {
|
||||
if (mid != id) {
|
||||
e = document.getElementById(mid);
|
||||
e.style.display = 'none';
|
||||
|
||||
function hideMenus(skipMenu)
|
||||
{
|
||||
if (!visibleMenu) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = 0; i < menus.length; ++i) {
|
||||
if (menus[i] !== skipMenu) {
|
||||
menus[i].style.display = "none";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function isMenuBox(e)
|
||||
{
|
||||
return e.className.search(/\bpopupmenu\b/) != -1;
|
||||
}
|
||||
|
||||
function isNavBar(e)
|
||||
{
|
||||
return e.className.search(/\bnavbar\b/) != -1;
|
||||
}
|
||||
|
||||
window.addEventListener("load", function() {
|
||||
var navItems = document.getElementsByClassName("popupcontainer");
|
||||
|
||||
// Set event handlers for individual menu triggers.
|
||||
for (var i = 0; i < navItems.length; ++i) {
|
||||
var navItem = navItems[i],
|
||||
menu = navItem.getElementsByClassName("popupmenu")[0];
|
||||
|
||||
menus.push(menu);
|
||||
|
||||
var id = menu.id,
|
||||
a = navItem.getElementsByClassName("popuptrigger")[0];
|
||||
|
||||
a.addEventListener("click", function(event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
toggleMenu(event, event.target.nextElementSibling);
|
||||
}, false);
|
||||
}
|
||||
|
||||
// Dismiss all visible menus on click outside them.
|
||||
document.addEventListener("click", function(event) {
|
||||
if (!visibleMenu) {
|
||||
return;
|
||||
}
|
||||
|
||||
var parent = event.target;
|
||||
while(parent && !isMenuBox(parent) && !isNavBar(parent)) {
|
||||
parent = parent.parentElement;
|
||||
}
|
||||
|
||||
if (!parent || !isMenuBox(parent)) {
|
||||
hideMenus();
|
||||
}
|
||||
}, false);
|
||||
}, false);
|
||||
})();
|
||||
|
|
|
@ -1,103 +1,101 @@
|
|||
#!/usr/bin/env python2
|
||||
import glob, os, sys, time, re
|
||||
import glob
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import time
|
||||
sys.path.append(os.path.join(os.path.dirname(__file__), ".."))
|
||||
from . import html_output
|
||||
|
||||
def write_addon_overview(folder, addon):
|
||||
out = open(os.path.join(folder, "index.html"), "w")
|
||||
def w(x): out.write(x + "\n")
|
||||
|
||||
def w(x):
|
||||
out.write(x + "\n")
|
||||
|
||||
name = addon["name"]
|
||||
|
||||
path = "../"
|
||||
title = name + " Overview"
|
||||
generation_note = "generated on " + time.ctime()
|
||||
|
||||
w(html_output.html_header % locals())
|
||||
|
||||
w(html_output.top_bar % locals())
|
||||
|
||||
title = html_output.cleantext("Build Report for " + name)
|
||||
generation_note = "Last updated on " + time.ctime() + "."
|
||||
|
||||
w(html_output.website_header(path="../",
|
||||
title=title,
|
||||
classes=["wmlunits-report"]))
|
||||
|
||||
w('<div class="overview">')
|
||||
|
||||
|
||||
eras = addon.get("eras", [])
|
||||
|
||||
w("<h2>" + name + "</h2>")
|
||||
w('<h2>' + html_output.cleantext(name) + '</h2>')
|
||||
|
||||
if eras:
|
||||
w("<h3>Eras</h3><ul>")
|
||||
w('<h3>Eras</h3><ul>')
|
||||
for era in eras:
|
||||
epath = os.path.join("en_US", era["id"] + ".html")
|
||||
w('<li><a href="' + epath + '">' + era["name"] + '</a></li>')
|
||||
w("</ul>")
|
||||
|
||||
epath = html_output.cleanurl(os.path.join("en_US", era["id"] + ".html"))
|
||||
w('<li><a href="' + epath + '">' + html_output.cleantext(era["name"], quote=False) + '</a></li>')
|
||||
w('</ul>')
|
||||
|
||||
campaigns = addon.get("campaigns", [])
|
||||
if campaigns:
|
||||
w("<h3>Campaigns</h3><ul>")
|
||||
w('<h3>Campaigns</h3><ul>')
|
||||
for campaign in campaigns:
|
||||
cpath = os.path.join("en_US", campaign["id"] + ".html")
|
||||
w('<li><a href="' + cpath + '">' + campaign["name"] + '</a></li>')
|
||||
w("</ul>")
|
||||
|
||||
w("<div>")
|
||||
w('<li><a href="' + cpath + '">' + html_output.cleantext(campaign["name"], quote=False) + '</a></li>')
|
||||
w('</ul>')
|
||||
|
||||
w('<div>')
|
||||
if os.path.exists(os.path.join(folder, "error.log")):
|
||||
w('<p><b>Warnings or errors were found: <a href="error.html"/>log</a></b></p>')
|
||||
w('<p><a href="../overview.html">back to overview</a></p>')
|
||||
w("</div>")
|
||||
|
||||
w('<p><b>Warnings or errors were found: <a href="error.html">log</a></b></p>')
|
||||
w('<p><a href="../overview.html">Back to the full report</a></p>')
|
||||
w('</div>')
|
||||
|
||||
w('</div> <!-- overview -->')
|
||||
|
||||
w(html_output.html_footer % locals())
|
||||
|
||||
|
||||
w(html_output.website_footer())
|
||||
|
||||
|
||||
def main(folder):
|
||||
out = open(os.path.join(folder, "overview.html"), "w")
|
||||
def w(x): out.write(x + "\n")
|
||||
def w(x):
|
||||
out.write(x + "\n")
|
||||
|
||||
path = ""
|
||||
title = "Wesnoth Unit Database Overview"
|
||||
generation_note = "generated on " + time.ctime()
|
||||
w(html_output.website_header(path="",
|
||||
title="Database Build Report",
|
||||
classes=["wmlunits-report"]))
|
||||
|
||||
w('<h1>Database Build Report</h1>')
|
||||
|
||||
w(html_output.html_header % locals())
|
||||
|
||||
w(html_output.top_bar % locals())
|
||||
|
||||
w('<div class="overview">')
|
||||
|
||||
w('<table class="overview">')
|
||||
w("<tr><th>")
|
||||
w("Addon")
|
||||
w("</th><th>")
|
||||
w("Output Files")
|
||||
w("</th><th>")
|
||||
w("Error Log")
|
||||
w("</th></tr>")
|
||||
w('<thead><tr><th>Addon</th><th>Output Files</th><th>Error Log</th></tr></thead>')
|
||||
w('<tbody>')
|
||||
count = 0
|
||||
total_n = 0
|
||||
total_error_logs = 0
|
||||
total_lines = 0
|
||||
for f in sorted(glob.glob(os.path.join(folder, "*"))):
|
||||
if not os.path.isdir(f): continue
|
||||
if f.endswith("/pics"): continue
|
||||
|
||||
if not os.path.isdir(f):
|
||||
continue
|
||||
if f.endswith("/pics"):
|
||||
continue
|
||||
|
||||
error_log = os.path.abspath(os.path.join(f, "error.log"))
|
||||
error_html = os.path.abspath(os.path.join(f, "error.html"))
|
||||
|
||||
|
||||
try:
|
||||
n = len(os.listdir(os.path.join(f, "en_US")))
|
||||
except OSError:
|
||||
n = 0
|
||||
|
||||
|
||||
total_n += n
|
||||
|
||||
name = f[len(folder):].lstrip("/")
|
||||
error_name = os.path.join(name, "error.html")
|
||||
w('<tr><td>')
|
||||
w('<a href="' + os.path.join(name, "index.html") + '">' + name + '</a>')
|
||||
w('<a href="' + html_output.cleanurl(os.path.join(name, "index.html")) + '">' + html_output.cleantext(name, quote=False) + '</a>')
|
||||
w('</td><td>')
|
||||
w(str(n))
|
||||
w('</td><td>')
|
||||
if os.path.exists(error_log):
|
||||
|
||||
text = open(error_log).read()
|
||||
error_kind = "warnings"
|
||||
if "<INTERNAL ERROR>" in text:
|
||||
|
@ -108,19 +106,17 @@ def main(folder):
|
|||
error_kind = "parse error"
|
||||
elif "<TIMEOUT ERROR>" in text:
|
||||
error_kind = "timeout"
|
||||
|
||||
|
||||
source = []
|
||||
|
||||
|
||||
def postprocess(line):
|
||||
if line == "WMLError:": return ""
|
||||
if line == "?": return ""
|
||||
if line == "Preprocessor error:": return ""
|
||||
if line.startswith("Automatically found a possible data directory"): return ""
|
||||
if line.startswith("Overriding data directory with"): return ""
|
||||
if line == "'SKIP_CORE' defined.": return ""
|
||||
if re.match("added .* defines.", line): return ""
|
||||
if line.startswith("skipped 'data/core'"): return ""
|
||||
if line.startswith("preprocessing specified resource:"): return ""
|
||||
if line in ("WMLError:", "?", "Preprocessor error:", "'SKIP_CORE' defined.") or \
|
||||
line.startswith("Automatically found a possible data directory") or \
|
||||
line.startswith("Overriding data directory with") or \
|
||||
line.startswith("skipped 'data/core'") or \
|
||||
line.startswith("preprocessing specified resource:") or \
|
||||
re.match("added .* defines.", line):
|
||||
return ""
|
||||
|
||||
mo = re.match(r"\d+ /tmp(?:/wmlparser_.*?/|/)(.*\.cfg).*", line)
|
||||
if mo:
|
||||
|
@ -128,55 +124,55 @@ def main(folder):
|
|||
return ""
|
||||
|
||||
mo = re.match(".*--preprocess-defines(.*)", line)
|
||||
if mo: return "Defines: " + mo.group(1) + "<br />"
|
||||
|
||||
if mo:
|
||||
return "Defines: " + mo.group(1) + '<br />'
|
||||
|
||||
for s in source:
|
||||
line = line.replace(s, "WML")
|
||||
|
||||
|
||||
line = line.replace("included from WML:1", "")
|
||||
rows = line.replace("included from", "\n included from").splitlines()
|
||||
out = ""
|
||||
for row in rows:
|
||||
row = row.strip()
|
||||
out += row + "<br />"
|
||||
out += row + '<br />'
|
||||
return out
|
||||
|
||||
|
||||
htmlerr = open(error_html, "w")
|
||||
htmlerr.write("<html><body>")
|
||||
htmlerr.write('<html><body>')
|
||||
lines_count = 0
|
||||
for line in text.splitlines():
|
||||
line = line.strip()
|
||||
if line in ["<INTERNAL ERROR>", "<WML ERROR>", "<PARSE ERROR>", "<TIMEOUT ERROR>"]:
|
||||
htmlerr.write("<p>")
|
||||
htmlerr.write('<p>')
|
||||
elif line in ["</INTERNAL ERROR>", "</WML ERROR>", "</PARSE ERROR>", "</TIMEOUT ERROR>"]:
|
||||
htmlerr.write("</p>")
|
||||
htmlerr.write('</p>')
|
||||
else:
|
||||
err_html = postprocess(line)
|
||||
lines_count += err_html.count("<br")
|
||||
lines_count += err_html.count('<br')
|
||||
htmlerr.write(err_html)
|
||||
htmlerr.write("</body></html>")
|
||||
|
||||
total_lines += lines_count
|
||||
|
||||
total_error_logs += 1
|
||||
w('<a class="error" href="%s">%s (%d lines)</a>' % (error_name, error_kind, lines_count))
|
||||
w("</td></tr>")
|
||||
|
||||
count += 1
|
||||
|
||||
w("<tr><td>")
|
||||
w("Total (for %d addons):" % count)
|
||||
w("</td><td>")
|
||||
w(str(total_n))
|
||||
w("</td><td>")
|
||||
w(str(total_error_logs) + " (" + str(total_lines) + " lines)")
|
||||
w("</td></tr>")
|
||||
htmlerr.write('</body></html>')
|
||||
|
||||
total_lines += lines_count
|
||||
|
||||
total_error_logs += 1
|
||||
w('<a class="error" href="%s">%s (%d lines)</a>' % (html_output.cleanurl(error_name), error_kind, lines_count))
|
||||
w('</td></tr>')
|
||||
|
||||
count += 1
|
||||
w('</tbody>')
|
||||
|
||||
w('<tfoot><tr>')
|
||||
w('<th scope="row">Total (for %d addons):</th>' % count)
|
||||
w('<td>' + str(total_n) + '</td>')
|
||||
w('<td>' + str(total_error_logs) + ' (' + str(total_lines) + ' lines)</td>')
|
||||
w('</tr></tfoot>')
|
||||
|
||||
w('</table>')
|
||||
|
||||
w("</table>")
|
||||
|
||||
w('</div> <!-- overview -->')
|
||||
|
||||
w(html_output.html_footer % locals())
|
||||
|
||||
w(html_output.website_footer())
|
||||
|
||||
if __name__ == "__main__":
|
||||
main(sys.argv[1])
|
||||
|
|
|
@ -1,352 +0,0 @@
|
|||
/* Stylesheet for wmlunits HTML output. */
|
||||
|
||||
body {
|
||||
background-color: #efebe0;
|
||||
margin: 0px;
|
||||
}
|
||||
h1 {
|
||||
text-align: center;
|
||||
margin: 0 0 0.5em 0;
|
||||
}
|
||||
table.units {
|
||||
background-color: #fffbf0;
|
||||
margin: 0px;
|
||||
border: none;
|
||||
padding: 0px;
|
||||
border-spacing: 0px;
|
||||
width: auto;
|
||||
}
|
||||
div.header {
|
||||
background:#444444 url("headerbg.jpg") repeat-x scroll center top;
|
||||
border-bottom:1px solid #000000;
|
||||
margin:0pt;
|
||||
padding:0pt;
|
||||
width:100%;
|
||||
text-align: center;
|
||||
}
|
||||
div.topnav {
|
||||
background:#272727 url("navbg.png") repeat-x scroll center bottom;
|
||||
border-top:1px solid #595959;
|
||||
margin:0;
|
||||
padding:3px 4px 15px;
|
||||
text-align:center;
|
||||
}
|
||||
div.topnav a {
|
||||
color:#B48648;
|
||||
font-family:"Trebuchet MS",sans-serif;
|
||||
line-height:0.8em;
|
||||
font-size:0.8em;
|
||||
font-weight:bold;
|
||||
text-decoration:none;
|
||||
}
|
||||
div.topnav a:hover {
|
||||
color:#CCCCCC;
|
||||
}
|
||||
img {
|
||||
border: none;
|
||||
}
|
||||
div.header img {
|
||||
vertical-align:middle;
|
||||
}
|
||||
div.pic {
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
border: none;
|
||||
display: inline;
|
||||
float: left;
|
||||
}
|
||||
td.unitcell {
|
||||
font-size: small;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
border-bottom: 2px solid #cfcbc0;
|
||||
border-top: 2px solid #fffbf0;
|
||||
border-right: 2px solid #fffbf0;
|
||||
}
|
||||
td.unitcell a {
|
||||
color: black;
|
||||
font-size: medium;
|
||||
text-decoration: none;
|
||||
}
|
||||
div.main {
|
||||
margin-top: 0;
|
||||
margin-left: 9em;
|
||||
border-left: 1px solid black;
|
||||
}
|
||||
div.popupmenu
|
||||
{
|
||||
position: absolute;
|
||||
margin-left: 8.5em;
|
||||
margin-top: -1em;
|
||||
background: white;
|
||||
border: 1px solid black;
|
||||
padding: 8px;
|
||||
}
|
||||
div.popupmenu > div
|
||||
{
|
||||
color: gray;
|
||||
font-size: large;
|
||||
border-bottom: 1px solid #000000;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
div.popupmenu a {
|
||||
text-decoration: none;
|
||||
}
|
||||
a.unitmenu {
|
||||
display: block;
|
||||
margin-left: 1em;
|
||||
font-size: small;
|
||||
}
|
||||
.popuptrigger div.popupmenu
|
||||
{
|
||||
display: none;
|
||||
}
|
||||
.popuptrigger:hover div.popupmenu
|
||||
{
|
||||
display: block;
|
||||
}
|
||||
div.navbar {
|
||||
width: 9em;
|
||||
float: left;
|
||||
overflow: hidden;
|
||||
}
|
||||
ul.navbar {
|
||||
list-style: none;
|
||||
margin: 0 0 0 0.5em;
|
||||
border-spacing: 0px;
|
||||
padding: 0px;
|
||||
border-right: 1px solid black;
|
||||
width: 8.5em;
|
||||
}
|
||||
ul.navbar li {
|
||||
color: black;
|
||||
font-weight: bold;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
ul.navbar li a:hover {
|
||||
color: #804000;
|
||||
}
|
||||
ul.navbar a {
|
||||
color: #B48648;
|
||||
font-size: large;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
}
|
||||
ul.navbar a.unitmenu {
|
||||
font-size: medium;
|
||||
}
|
||||
ul.navbar div.popupmenu a {
|
||||
font-size: medium;
|
||||
}
|
||||
td.raceheader {
|
||||
background:#272727 url("navbg.png") repeat-x scroll center bottom;
|
||||
border-top:1px solid #595959;
|
||||
margin:0pt;
|
||||
padding:1px 1px 10px 1px;
|
||||
text-align:center;
|
||||
color: #B48648;
|
||||
font-size: x-large;
|
||||
font-weight: bold;
|
||||
}
|
||||
tr.levels th {
|
||||
border-bottom: 1px solid #cfcbc0;
|
||||
}
|
||||
table.unitinfo {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
}
|
||||
table.unitinfo th {
|
||||
text-align: left;
|
||||
font-weight: normal;
|
||||
white-space: nowrap;
|
||||
}
|
||||
table.attacks col.col1 {
|
||||
width: 7em;
|
||||
}
|
||||
table.resistances col.col1 {
|
||||
width: 5em;
|
||||
}
|
||||
table.resistances col.col5 {
|
||||
width: 5em;
|
||||
}
|
||||
table.resistances col.col3 {
|
||||
width: 4em;
|
||||
}
|
||||
table.resistances img {
|
||||
height: 36px;
|
||||
}
|
||||
table.terrain img {
|
||||
height: 36px;
|
||||
}
|
||||
table.terrain th.numheader {
|
||||
text-align: right;
|
||||
}
|
||||
td.grayed {
|
||||
color: gray;
|
||||
}
|
||||
td.empty {
|
||||
background-color: #fffbf0;
|
||||
}
|
||||
table.units col.col0 {
|
||||
background-color: #efebe0;
|
||||
width: 16%;
|
||||
}
|
||||
table.units col.col1 {
|
||||
background-color: #f7ebd8;
|
||||
width: 16%;
|
||||
}
|
||||
table.units col.col2 {
|
||||
background-color: #f4ebdc;
|
||||
width: 16%;
|
||||
}
|
||||
table.units col.col3 {
|
||||
background-color: #efebe0;
|
||||
width: 16%;
|
||||
}
|
||||
table.units col.col4 {
|
||||
background-color: #f4ebdc;
|
||||
width: 16%;
|
||||
}
|
||||
table.units col.col5 {
|
||||
background-color: #f7ebd8;
|
||||
width: 16%;
|
||||
}
|
||||
div.l {
|
||||
color: gray;
|
||||
font-weight: normal;
|
||||
font-size: small;
|
||||
border: 1px solid;
|
||||
float: right;
|
||||
margin: 0px;
|
||||
}
|
||||
div.i {
|
||||
padding: 4px;
|
||||
font-size: small;
|
||||
border: 1px solid white;
|
||||
float: left;
|
||||
margin: 0px;
|
||||
}
|
||||
div.i a {
|
||||
font-weight: 900;
|
||||
color: #8080ff;
|
||||
text-decoration: underline;
|
||||
}
|
||||
div.attributes {
|
||||
font-size: small;
|
||||
font-weight: normal;
|
||||
text-align: left;
|
||||
}
|
||||
div#footer {
|
||||
clear: both;
|
||||
color: #111111;
|
||||
font-size: small;
|
||||
border-top: 1px solid #999999;;
|
||||
padding: 1em;
|
||||
margin: 1em;
|
||||
}
|
||||
div#footer p {
|
||||
line-height: 1em;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
div#footer a {
|
||||
color: #111111;
|
||||
}
|
||||
|
||||
td.num {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
td.val {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
div.unit-columns {
|
||||
width: 51em;
|
||||
float: left;
|
||||
margin: 0 0 0 1em;
|
||||
}
|
||||
|
||||
div.unit-columns i {
|
||||
font-size: 140%;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
div.unit-columns h1 {
|
||||
text-shadow: 2px 2px 3px #998877;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
div.unit-columns h2 {
|
||||
border-bottom: 1px solid #000000;
|
||||
}
|
||||
|
||||
div.unit-columns h2 > small {
|
||||
font-weight: normal;
|
||||
font-size: medium;
|
||||
}
|
||||
|
||||
div.unit-column-left {
|
||||
width: 30em;
|
||||
float: left;
|
||||
}
|
||||
|
||||
div.unit-column-right {
|
||||
margin: 0 0 0 1em;
|
||||
width: 20em;
|
||||
float: right;
|
||||
}
|
||||
|
||||
table.overview {
|
||||
border-spacing: 0px;
|
||||
border: 1px solid #000000;
|
||||
}
|
||||
|
||||
table.overview th {
|
||||
text-align: center;
|
||||
padding: 1em;
|
||||
border-bottom: 2px solid #000000;
|
||||
}
|
||||
|
||||
table.overview td {
|
||||
border-bottom: 1px solid #000000;
|
||||
}
|
||||
|
||||
table.overview td + td {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
table.overview a.error {
|
||||
color: red;
|
||||
}
|
||||
|
||||
div.overview {
|
||||
margin: 0 auto;
|
||||
background-color: #E7D9C0;
|
||||
max-width: 60em;
|
||||
width: auto;
|
||||
border-radius: 1em 1em 1em 1em;
|
||||
border: solid 1px white;
|
||||
font-style: sans-serif;
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
div.portrait {
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
div.portrait div {
|
||||
position: absolute;
|
||||
height: 200px;
|
||||
width: 200px;
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
opacity: 0.25;
|
||||
}
|
||||
|
||||
div.portrait img {
|
||||
position: absolute;
|
||||
height: 200px;
|
||||
}
|
|
@ -7,12 +7,21 @@ Run without arguments to see usage.
|
|||
"""
|
||||
|
||||
# Makes things faster on 32-bit systems
|
||||
try: import psyco; psyco.full()
|
||||
except ImportError: pass
|
||||
|
||||
import sys, os, glob, shutil, urllib.request, urllib.error, urllib.parse, argparse, traceback
|
||||
import subprocess, yaml
|
||||
import multiprocessing, queue
|
||||
try:
|
||||
import psyco
|
||||
psyco.full()
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
import traceback
|
||||
import subprocess
|
||||
import multiprocessing
|
||||
import queue
|
||||
import yaml
|
||||
|
||||
import wesnoth.wmlparser3 as wmlparser3
|
||||
import unit_tree.helpers as helpers
|
||||
|
@ -27,23 +36,15 @@ def copy_images():
|
|||
print("Recolorizing pictures.")
|
||||
image_collector.copy_and_color_images(options.output)
|
||||
shutil.copy2(os.path.join(image_collector.datadir,
|
||||
"data/tools/unit_tree/style.css"), options.output)
|
||||
shutil.copy2(os.path.join(image_collector.datadir,
|
||||
"data/tools/unit_tree/menu.js"), 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 = urllib.request.urlopen(grab)
|
||||
open(local, "wb").write(url.read())
|
||||
"data/tools/unit_tree/menu.js"),
|
||||
options.output)
|
||||
|
||||
def shell(com):
|
||||
#print(com)
|
||||
p = subprocess.Popen(com, stdout = subprocess.PIPE,
|
||||
stderr = subprocess.PIPE, shell = True)
|
||||
p = subprocess.Popen(com,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
shell=True)
|
||||
out, err = p.communicate()
|
||||
#if out: sys.stdout.write(out)
|
||||
#if err: sys.stdout.write(err)
|
||||
|
@ -52,7 +53,8 @@ def shell(com):
|
|||
|
||||
def shell_out(com):
|
||||
p = subprocess.Popen(com,
|
||||
stdout = subprocess.PIPE, stderr = subprocess.PIPE)
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE)
|
||||
out, err = p.communicate()
|
||||
return out
|
||||
|
||||
|
@ -67,7 +69,7 @@ def move(f, t, name):
|
|||
|
||||
com = "mv " + f + "/" + bash(name) + " " + t + "/"
|
||||
return shell(com)
|
||||
|
||||
|
||||
_info = {}
|
||||
def get_info(addon):
|
||||
global _info
|
||||
|
@ -77,12 +79,13 @@ def get_info(addon):
|
|||
try:
|
||||
path = options.addons + "/" + addon + "/_info.cfg"
|
||||
if os.path.exists(path):
|
||||
parser = wmlparser3.Parser(options.wesnoth, options.config_dir,
|
||||
options.data_dir)
|
||||
parser = wmlparser3.Parser(options.wesnoth,
|
||||
options.config_dir,
|
||||
options.data_dir)
|
||||
parser.parse_file(path)
|
||||
_info[addon] = parser
|
||||
else:
|
||||
print(("Cannot find " + path))
|
||||
print("Cannot find " + path)
|
||||
except wmlparser3.WMLError as e:
|
||||
print(e)
|
||||
return _info[addon]
|
||||
|
@ -96,7 +99,7 @@ def get_dependencies(addon):
|
|||
return _deps[addon]
|
||||
_deps[addon] = []
|
||||
try:
|
||||
info = get_info(addon).get_all(tag = "info")[0]
|
||||
info = get_info(addon).get_all(tag="info")[0]
|
||||
row = info.get_text_val("dependencies")
|
||||
if row:
|
||||
deps1 = row.split(",")
|
||||
|
@ -106,7 +109,7 @@ def get_dependencies(addon):
|
|||
if d in global_addons:
|
||||
_deps[addon].append(d)
|
||||
else:
|
||||
print(("Missing dependency for " + addon + ": " + d))
|
||||
print("Missing dependency for " + addon + ": " + d)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
return _deps[addon]
|
||||
|
@ -119,8 +122,8 @@ def get_all_dependencies(addon):
|
|||
check = get_dependencies(addon)[:]
|
||||
while check:
|
||||
d = check.pop()
|
||||
if d == addon: continue
|
||||
if d in result: continue
|
||||
if d == addon or d in result:
|
||||
continue
|
||||
result.append(d)
|
||||
check += get_dependencies(d)
|
||||
return result
|
||||
|
@ -140,33 +143,32 @@ def sorted_by_dependencies(addons):
|
|||
n += 1
|
||||
continue
|
||||
if n == 0:
|
||||
print(("Cannot sort dependencies for these addons: " + str(unsorted)))
|
||||
sorted += unsorted
|
||||
break
|
||||
print("Cannot sort dependencies for these addons: " + str(unsorted))
|
||||
sorted += unsorted
|
||||
break
|
||||
return sorted
|
||||
|
||||
def search(batchlist, name):
|
||||
for info in batchlist:
|
||||
if info and info["name"] == name: return info
|
||||
if info and info["name"] == name:
|
||||
return info
|
||||
batchlist.append({})
|
||||
batchlist[-1]["name"] = name
|
||||
return batchlist[-1]
|
||||
|
||||
def list_contents():
|
||||
class Empty: pass
|
||||
local = Empty()
|
||||
class Empty:
|
||||
pass
|
||||
|
||||
local = Empty()
|
||||
mainline_eras = set()
|
||||
filename = options.list
|
||||
|
||||
def append(info, id, define, c = None, name = None, domain = None):
|
||||
|
||||
def append(info, id, define, c=None, name=None, domain=None):
|
||||
info.append({})
|
||||
info[-1]["id"]= id
|
||||
info[-1]["id"] = id
|
||||
info[-1]["define"] = define
|
||||
if c:
|
||||
info[-1]["name"] = c.get_text_val("name")
|
||||
else:
|
||||
info[-1]["name"] = name
|
||||
info[-1]["name"] = c.get_text_val("name") if c else name
|
||||
info[-1]["units"] = "?"
|
||||
info[-1]["translations"] = {}
|
||||
|
||||
|
@ -175,7 +177,7 @@ def list_contents():
|
|||
def translate(string, domain):
|
||||
return translation.translate(string, domain)
|
||||
if c:
|
||||
t = c.get_text_val("name", translation = translate)
|
||||
t = c.get_text_val("name", translation=translate)
|
||||
else:
|
||||
t = translate(name, domain)
|
||||
if t != info[-1]["name"]:
|
||||
|
@ -190,7 +192,7 @@ def list_contents():
|
|||
return dependency_eras
|
||||
|
||||
def list_eras(batchlist, addon):
|
||||
eras = local.wesnoth.parser.get_all(tag = "era")
|
||||
eras = local.wesnoth.parser.get_all(tag="era")
|
||||
if addon != "mainline":
|
||||
dependency_eras = get_dependency_eras(batchlist, addon)
|
||||
eras = [x for x in eras if not x.get_text_val("id") in dependency_eras]
|
||||
|
@ -199,30 +201,31 @@ def list_contents():
|
|||
eid = era.get_text_val("id")
|
||||
if addon == "mainline":
|
||||
mainline_eras.add(eid)
|
||||
append(info, eid, "MULTIPLAYER", c = era)
|
||||
append(info, eid, "MULTIPLAYER", c=era)
|
||||
|
||||
return info
|
||||
|
||||
|
||||
def list_campaigns(batchlist, addon):
|
||||
campaigns = local.wesnoth.parser.get_all(tag = "campaign")
|
||||
campaigns = local.wesnoth.parser.get_all(tag="campaign")
|
||||
info = []
|
||||
|
||||
for campaign in campaigns:
|
||||
cid = campaign.get_text_val("id")
|
||||
d = campaign.get_text_val("define")
|
||||
d2 = campaign.get_text_val("extra_defines")
|
||||
if d2: d += "," + d2
|
||||
if d2:
|
||||
d += "," + d2
|
||||
d3 = campaign.get_text_val("difficulties")
|
||||
if d3:
|
||||
d += "," + d3.split(",")[0]
|
||||
else:
|
||||
difficulty = campaign.get_all(tag = "difficulty")
|
||||
difficulty = campaign.get_all(tag="difficulty")
|
||||
if difficulty:
|
||||
d3 = difficulty[0].get_text_val("define")
|
||||
if d3:
|
||||
d += "," + d3
|
||||
|
||||
append(info, cid, d, c = campaign)
|
||||
append(info, cid, d, c=campaign)
|
||||
|
||||
return info
|
||||
|
||||
|
@ -241,10 +244,10 @@ def list_contents():
|
|||
q.put(("e", e))
|
||||
|
||||
q = multiprocessing.Queue()
|
||||
p = multiprocessing.Process(target = f, args = (options, wml, defines, q))
|
||||
p = multiprocessing.Process(target=f, args=(options, wml, defines, q))
|
||||
p.start()
|
||||
try:
|
||||
s, local.wesnoth = q.get(timeout = TIMEOUT)
|
||||
s, local.wesnoth = q.get(timeout=TIMEOUT)
|
||||
except queue.Empty:
|
||||
p.terminate()
|
||||
raise
|
||||
|
@ -253,15 +256,17 @@ def list_contents():
|
|||
if s == "e":
|
||||
remote_exception = local.wesnoth
|
||||
raise remote_exception
|
||||
|
||||
|
||||
def get_version(addon):
|
||||
parser = get_info(addon)
|
||||
if parser:
|
||||
for info in parser.get_all(tag = "info"):
|
||||
for info in parser.get_all(tag="info"):
|
||||
return info.get_text_val("version") + "*" + info.get_text_val("uploads")
|
||||
|
||||
try: os.makedirs(options.output + "/mainline")
|
||||
except OSError: pass
|
||||
try:
|
||||
os.makedirs(options.output + "/mainline")
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
try:
|
||||
batchlist = yaml.load(open(options.list))
|
||||
|
@ -279,8 +284,8 @@ def list_contents():
|
|||
|
||||
# Fake mainline campaign to have an overview of the mainline units
|
||||
info["campaigns"] = []
|
||||
append(info["campaigns"], "mainline", "", name = "Units", domain = "wesnoth-help")
|
||||
|
||||
append(info["campaigns"], "mainline", "", name="Units", domain="wesnoth-help")
|
||||
|
||||
if not options.addons_only:
|
||||
parse("{core}{campaigns}", "SKIP_CORE")
|
||||
info["campaigns"] += list_campaigns(batchlist, "mainline")
|
||||
|
@ -300,7 +305,8 @@ def list_contents():
|
|||
addons = sorted_by_dependencies(addons)
|
||||
|
||||
for i, addon in enumerate(addons):
|
||||
if not os.path.isdir(options.addons + "/" + addon): continue
|
||||
if not os.path.isdir(options.addons + "/" + addon):
|
||||
continue
|
||||
mem = "? KB"
|
||||
try:
|
||||
mem = dict([x.split("\t", 1) for x in open("/proc/self/status").read().split("\n") if x])["VmRSS:"]
|
||||
|
@ -310,16 +316,17 @@ def list_contents():
|
|||
sys.stdout.flush()
|
||||
d = options.output + "/" + addon
|
||||
logname = d + "/error.log"
|
||||
try: os.makedirs(d)
|
||||
except OSError: pass
|
||||
try:
|
||||
os.makedirs(d)
|
||||
except OSError:
|
||||
pass
|
||||
version = get_version(addon)
|
||||
move(options.addons, options.config_dir + "/data/add-ons", addon)
|
||||
for d in get_dependencies(addon):
|
||||
move(options.addons, options.config_dir + "/data/add-ons", d)
|
||||
try:
|
||||
info = search(batchlist, addon)
|
||||
|
||||
if info.get("version", "") == version and info.get("parsed", False) == True:
|
||||
if info.get("version", "") == version and info.get("parsed", False) is True:
|
||||
sys.stdout.write("up to date\n")
|
||||
continue
|
||||
info["parsed"] = False
|
||||
|
@ -350,18 +357,17 @@ def list_contents():
|
|||
ef.write("</INTERNAL ERROR>\n")
|
||||
ef.close()
|
||||
sys.stdout.write("failed\n")
|
||||
|
||||
finally:
|
||||
move(options.config_dir + "/data/add-ons", options.addons, addon)
|
||||
for d in get_dependencies(addon):
|
||||
move(options.config_dir + "/data/add-ons", options.addons, d)
|
||||
|
||||
|
||||
yaml.safe_dump(batchlist, open(filename, "w"),
|
||||
encoding = "utf-8", default_flow_style = False)
|
||||
encoding="utf-8", default_flow_style=False)
|
||||
|
||||
def process_campaign_or_era(addon, cid, define, batchlist):
|
||||
n = 0
|
||||
|
||||
|
||||
print(str(addon) + ": " + str(cid) + " " + str(define))
|
||||
|
||||
if not define:
|
||||
|
@ -374,10 +380,10 @@ def process_campaign_or_era(addon, cid, define, batchlist):
|
|||
options.transdir)
|
||||
wesnoth.batchlist = batchlist
|
||||
wesnoth.cid = cid
|
||||
|
||||
|
||||
wesnoth.parser.parse_text("{core/units.cfg}", "NORMAL")
|
||||
wesnoth.add_units("mainline")
|
||||
|
||||
|
||||
if define == "MULTIPLAYER":
|
||||
wesnoth.parser.parse_text("{core}{multiplayer}{multiplayer/eras.cfg}{~add-ons}", "MULTIPLAYER,SKIP_CORE")
|
||||
wesnoth.add_units(cid)
|
||||
|
@ -389,19 +395,19 @@ def process_campaign_or_era(addon, cid, define, batchlist):
|
|||
else:
|
||||
wesnoth.parser.parse_text("{core}{~add-ons}", "SKIP_CORE," + define)
|
||||
wesnoth.add_units(cid)
|
||||
|
||||
|
||||
if addon == "mainline" and cid == "mainline":
|
||||
write_animation_statistics(wesnoth)
|
||||
|
||||
wesnoth.add_binary_paths(addon, image_collector)
|
||||
|
||||
if define == "MULTIPLAYER":
|
||||
eras = wesnoth.parser.get_all(tag = "era")
|
||||
eras = wesnoth.parser.get_all(tag="era")
|
||||
for era in eras:
|
||||
wesnoth.add_era(era)
|
||||
wesnoth.find_unit_factions()
|
||||
else:
|
||||
campaigns = wesnoth.parser.get_all(tag = "campaign")
|
||||
campaigns = wesnoth.parser.get_all(tag="campaign")
|
||||
for campaign in campaigns:
|
||||
wesnoth.add_campaign(campaign)
|
||||
|
||||
|
@ -410,9 +416,8 @@ def process_campaign_or_era(addon, cid, define, batchlist):
|
|||
wesnoth.check_units()
|
||||
|
||||
for isocode in languages:
|
||||
|
||||
if addon != "mainline" and isocode != "en_US": continue
|
||||
|
||||
if addon != "mainline" and isocode != "en_US":
|
||||
continue
|
||||
if define == "MULTIPLAYER":
|
||||
for era in list(wesnoth.era_lookup.values()):
|
||||
if era.get_text_val("id") == cid:
|
||||
|
@ -426,7 +431,6 @@ def process_campaign_or_era(addon, cid, define, batchlist):
|
|||
if campaign.get_text_val("id") == cid:
|
||||
n = html_output.generate_campaign_report(addon, isocode, campaign, wesnoth)
|
||||
break
|
||||
|
||||
html_output.generate_single_unit_reports(addon, isocode, wesnoth)
|
||||
|
||||
return n
|
||||
|
@ -437,12 +441,13 @@ def batch_process():
|
|||
for addon in batchlist:
|
||||
name = addon["name"]
|
||||
set_dependencies(name, addon.get("dependencies", []))
|
||||
|
||||
|
||||
for addon in batchlist:
|
||||
name = addon["name"]
|
||||
|
||||
if not options.reparse and addon.get("parsed", False) == True: continue
|
||||
|
||||
|
||||
if not options.reparse and addon.get("parsed", False) == True:
|
||||
continue
|
||||
|
||||
if name == "mainline":
|
||||
worked = True
|
||||
else:
|
||||
|
@ -450,22 +455,24 @@ def batch_process():
|
|||
for d in addon.get("dependencies", []):
|
||||
move(options.addons, options.config_dir + "/data/add-ons", d)
|
||||
d = options.output + "/" + name
|
||||
try: os.makedirs(d)
|
||||
except OSError: pass
|
||||
try:
|
||||
os.makedirs(d)
|
||||
except OSError:
|
||||
pass
|
||||
logname = d + "/error.log"
|
||||
|
||||
|
||||
def err(mess):
|
||||
ef = open(logname, "a")
|
||||
ef.write(str(mess))
|
||||
ef.close()
|
||||
|
||||
html_output.write_error = err
|
||||
|
||||
|
||||
try:
|
||||
if not worked:
|
||||
print((name + " not found"))
|
||||
print(name + " not found")
|
||||
continue
|
||||
|
||||
|
||||
for era in addon.get("eras", []):
|
||||
eid = era["id"]
|
||||
n = process_campaign_or_era(name, eid, era["define"], batchlist)
|
||||
|
@ -473,21 +480,23 @@ def batch_process():
|
|||
|
||||
for campaign in addon.get("campaigns", []):
|
||||
cid = campaign["id"]
|
||||
if cid == None: cid = campaign["define"]
|
||||
if cid == None: cid = name
|
||||
if cid is None:
|
||||
cid = campaign["define"]
|
||||
if cid is None:
|
||||
cid = name
|
||||
n = process_campaign_or_era(name, cid, campaign["define"], batchlist)
|
||||
campaign["units"] = n
|
||||
|
||||
|
||||
except wmlparser3.WMLError as e:
|
||||
ef = open(logname, "a")
|
||||
ef.write("<WML ERROR>\n")
|
||||
ef.write(str(e))
|
||||
ef.write("</WML ERROR>\n")
|
||||
ef.close()
|
||||
print((" " + name + " failed"))
|
||||
print(" " + name + " failed")
|
||||
except Exception as e:
|
||||
traceback.print_exc()
|
||||
print((" " + name + " failed"))
|
||||
print(" " + name + " failed")
|
||||
ef = open(logname, "a")
|
||||
ef.write("<INTERNAL ERROR>\n")
|
||||
ef.write("please report as bug\n")
|
||||
|
@ -499,15 +508,15 @@ def batch_process():
|
|||
move(options.config_dir + "/data/add-ons", options.addons, name)
|
||||
for d in addon.get("dependencies", []):
|
||||
move(options.config_dir + "/data/add-ons", options.addons, d)
|
||||
|
||||
|
||||
addon["parsed"] = True
|
||||
|
||||
yaml.safe_dump(batchlist, open(options.batch, "w"),
|
||||
encoding = "utf-8", default_flow_style = False)
|
||||
|
||||
encoding="utf-8", default_flow_style=False)
|
||||
|
||||
try:
|
||||
unit_tree.overview.write_addon_overview(os.path.join(options.output,
|
||||
name), addon)
|
||||
unit_tree.overview.write_addon_overview(
|
||||
os.path.join(options.output, name), addon)
|
||||
except Exception as e:
|
||||
pass
|
||||
|
||||
|
@ -518,8 +527,9 @@ def write_unit_ids_UNUSED():
|
|||
uids = list(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)
|
||||
wesnoth.unit_lookup[u2].rid)
|
||||
if r == 0:
|
||||
r = cmp(u1, u2)
|
||||
return r
|
||||
uids.sort(by_race)
|
||||
race = None
|
||||
|
@ -528,7 +538,8 @@ def write_unit_ids_UNUSED():
|
|||
for uid in uids:
|
||||
u = wesnoth.unit_lookup[uid]
|
||||
if u.rid != race:
|
||||
if race != None: f.write("</ul>")
|
||||
if race is not None:
|
||||
f.write("</ul>")
|
||||
f.write("<p>%s</p>\n" % (u.rid,))
|
||||
f.write("<ul>")
|
||||
race = u.rid
|
||||
|
@ -544,7 +555,6 @@ def write_animation_statistics(wesnoth):
|
|||
f.close()
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
# We change the process name to "wmlunits"
|
||||
try:
|
||||
import ctypes
|
||||
|
@ -558,41 +568,41 @@ if __name__ == '__main__':
|
|||
|
||||
ap = argparse.ArgumentParser()
|
||||
ap.add_argument("-C", "--config-dir",
|
||||
help="Specify the user configuration dir (wesnoth --config-path).")
|
||||
help="Specify the user configuration dir (wesnoth --config-path).")
|
||||
ap.add_argument("-D", "--data-dir",
|
||||
help="Specify the wesnoth data dir (wesnoth --path).")
|
||||
help="Specify the wesnoth data dir (wesnoth --path).")
|
||||
ap.add_argument("-l", "--language", default="all",
|
||||
help="Specify a language to use. Else output is produced for all languages.")
|
||||
help="Specify a language to use. Else output is produced for all languages.")
|
||||
ap.add_argument("-o", "--output",
|
||||
help="Specify the output directory.")
|
||||
help="Specify the output directory.")
|
||||
ap.add_argument("-n", "--nocopy", action="store_true",
|
||||
help="No copying of files. By default all images are copied to the output dir.")
|
||||
help="No copying of files. By default all images are copied to the output dir.")
|
||||
ap.add_argument("-w", "--wesnoth",
|
||||
help="Specify the wesnoth executable to use. Whatever data " +
|
||||
"and config paths that executable is configured for will be " +
|
||||
"used to find game files and addons.")
|
||||
help="Specify the wesnoth executable to use. Whatever data " +
|
||||
"and config paths that executable is configured for will be " +
|
||||
"used to find game files and addons.")
|
||||
ap.add_argument("-t", "--transdir",
|
||||
help="Specify the directory with gettext message catalogues. " +
|
||||
"Defaults to ./translations.", default="translations")
|
||||
help="Specify the directory with gettext message catalogues. " +
|
||||
"Defaults to ./translations.", default="translations")
|
||||
ap.add_argument("-T", "--timeout",
|
||||
help="Use the timeout iven in seconds when parsing WML, default is 20 " +
|
||||
"seconds.")
|
||||
help="Use the timeout iven in seconds when parsing WML, default is 20 " +
|
||||
"seconds.")
|
||||
ap.add_argument("-r", "--reparse", action="store_true",
|
||||
help="Reparse everything.")
|
||||
help="Reparse everything.")
|
||||
ap.add_argument("-a", "--addons",
|
||||
help="Specify path to a folder with all addons. This should be " +
|
||||
"outside the user config folder.")
|
||||
help="Specify path to a folder with all addons. This should be " +
|
||||
"outside the user config folder.")
|
||||
ap.add_argument("-L", "--list",
|
||||
help = "List available eras and campaigns.")
|
||||
help="List available eras and campaigns.")
|
||||
ap.add_argument("-B", "--batch",
|
||||
help = "Batch process the given list.")
|
||||
ap.add_argument("-A", "--addons-only", action = "store_true",
|
||||
help = "Do only process addons (for debugging).")
|
||||
ap.add_argument("-v", "--verbose", action = "store_true")
|
||||
ap.add_argument("-W", "--wiki", action = "store_true",
|
||||
help = "write wikified units list to stdout")
|
||||
help="Batch process the given list.")
|
||||
ap.add_argument("-A", "--addons-only", action="store_true",
|
||||
help="Do only process addons (for debugging).")
|
||||
ap.add_argument("-v", "--verbose", action="store_true")
|
||||
ap.add_argument("-W", "--wiki", action="store_true",
|
||||
help="write wikified units list to stdout")
|
||||
options = ap.parse_args()
|
||||
|
||||
|
||||
html_output.options = options
|
||||
helpers.options = options
|
||||
unit_tree.overview.options = options
|
||||
|
@ -614,27 +624,29 @@ if __name__ == '__main__':
|
|||
|
||||
if not options.data_dir:
|
||||
options.data_dir = shell_out([options.wesnoth, "--path"]).strip().decode("utf8")
|
||||
print(("Using " + options.data_dir + " as data dir."))
|
||||
print("Using " + options.data_dir + " as data dir.")
|
||||
|
||||
if not options.config_dir:
|
||||
options.config_dir = shell_out([options.wesnoth, "--config-path"]).strip().decode("utf8")
|
||||
print(("Using " + options.config_dir + " as config dir."))
|
||||
print("Using " + options.config_dir + " as config dir.")
|
||||
|
||||
if not options.transdir:
|
||||
options.transdir = os.getcwd()
|
||||
|
||||
|
||||
if options.wiki:
|
||||
wiki_output.main()
|
||||
sys.exit(0)
|
||||
|
||||
image_collector = helpers.ImageCollector(options.wesnoth,
|
||||
options.config_dir, options.data_dir)
|
||||
options.config_dir,
|
||||
options.data_dir)
|
||||
html_output.image_collector = image_collector
|
||||
|
||||
if options.language == "all":
|
||||
languages = []
|
||||
parser = wmlparser3.Parser(options.wesnoth, options.config_dir,
|
||||
options.data_dir)
|
||||
parser = wmlparser3.Parser(options.wesnoth,
|
||||
options.config_dir,
|
||||
options.data_dir)
|
||||
parser.parse_text("{languages}")
|
||||
|
||||
for locale in parser.get_all(tag="locale"):
|
||||
|
@ -650,22 +662,21 @@ if __name__ == '__main__':
|
|||
if not options.list and not options.batch:
|
||||
sys.stderr.write("Need --list or --batch (or both).\n")
|
||||
sys.exit(-1)
|
||||
|
||||
|
||||
if options.output:
|
||||
# Generate output dir.
|
||||
if not os.path.isdir(options.output):
|
||||
os.mkdir(options.output)
|
||||
|
||||
|
||||
if options.list:
|
||||
list_contents()
|
||||
|
||||
|
||||
if options.batch:
|
||||
batch_process()
|
||||
|
||||
|
||||
unit_tree.overview.main(options.output)
|
||||
|
||||
if not options.nocopy:
|
||||
copy_images()
|
||||
|
||||
html_output.write_index(options.output)
|
||||
|
||||
html_output.write_index(options.output)
|
||||
|
|
Loading…
Add table
Reference in a new issue