123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- #!/usr/bin/env python3
- #
- # SuperTux
- # Copyright (C) 2014 Ingo Ruhnke <grumbel@gmail.com>
- #
- # This program is free software: you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation, either version 3 of the License, or
- # (at your option) any later version.
- #
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- #
- # You should have received a copy of the GNU General Public License
- # along with this program. If not, see <http://www.gnu.org/licenses/>.
- import argparse
- import glob
- import hashlib
- import os
- import subprocess
- import sys
- import sexpr
- def escape_str(string):
- return "\"%s\"" % string.replace("\"", "\\\"")
- class Addon:
- def __init__(self, filename):
- lst = sexpr.parse(filename)
- if lst[0][0] != "supertux-addoninfo":
- raise Exception("not a supertux-addoninfo: %s" % lst[0][0])
- else:
- for k, v in lst[0][1:]:
- if k == "id":
- self.id = v
- elif k == "version":
- self.version = int(v)
- elif k == "type":
- self.type = v
- elif k == "title":
- self.title = v
- elif k == "author":
- self.author = v
- elif k == "license":
- self.license = v
- else:
- raise Exception("unknown tag: %s" % k)
- self.md5 = ""
- self.url = ""
- def write(self, fout):
- fout.write(" (supertux-addoninfo\n")
- fout.write(" (id %s)\n" % escape_str(self.id))
- fout.write(" (version %d)\n" % self.version)
- fout.write(" (type %s)\n" % escape_str(self.type))
- fout.write(" (title %s)\n" % escape_str(self.title))
- fout.write(" (author %s)\n" % escape_str(self.author))
- fout.write(" (license %s)\n" % escape_str(self.license))
- fout.write(" (url %s)\n" % escape_str(self.url))
- fout.write(" (md5 %s)\n" % escape_str(self.md5))
- fout.write(" )\n")
- def process_addon(fout, addon_dir, nfo, base_url, zipdir):
- # print addon_dir, nfo
- with open(nfo) as fin:
- addon = Addon(fin.read())
- zipfile = addon.id + "_v" + str(addon.version) + ".zip"
- # see http://pivotallabs.com/barriers-deterministic-reproducible-zip-files/
- os.remove(os.path.join(zipdir, zipfile))
- zipout = os.path.relpath(os.path.join(zipdir, zipfile), addon_dir)
- subprocess.call(["zip", "-X", "-r", "--quiet", zipout, "."], cwd=addon_dir)
- with open(os.path.join(zipdir, zipfile), 'rb') as fin:
- addon.md5 = hashlib.md5(fin.read()).hexdigest()
- addon.url = base_url + zipfile
- addon.write(fout)
- def generate_index(fout, directory, base_url, zipdir):
- fout.write(";; automatically generated by build-addon-index.py\n")
- fout.write("(supertux-addons\n")
- for addon_dir in os.listdir(directory):
- addon_dir = os.path.join(directory, addon_dir)
- if os.path.isdir(addon_dir):
- # print(addon_dir)
- nfos = glob.glob(os.path.join(addon_dir, "*.nfo"))
- if len(nfos) == 0:
- raise Exception(".nfo file missing from %s" % addon_dir)
- elif len(nfos) > 1:
- raise Exception("to many .nfo files in %s" % addon_dir)
- else:
- try:
- process_addon(fout, addon_dir, nfos[0], base_url, zipdir)
- except Exception as e:
- sys.stderr.write("%s: ignoring addon because: %s\n" % (addon_dir, e))
- fout.write(")\n\n;; EOF ;;\n")
- EXAMPLE_TEXT="""Example:
- ./build-addon-index.py -z ../../addons/repository/ ../../addons/src/"""
- if __name__ == "__main__":
- parser = argparse.ArgumentParser(description="Addon Index/Zip Generator",
- epilog=EXAMPLE_TEXT,
- formatter_class=argparse.RawDescriptionHelpFormatter)
- parser.add_argument('DIRECTORY', type=str, nargs=1,
- help="directory containing the mods")
- parser.add_argument('-o', '--output', metavar='FILE', type=str, required=False,
- help="output file")
- parser.add_argument('-z', '--zipdir', metavar="DIR", type=str, required=True,
- help="generate zip files")
- parser.add_argument('-u', '--url', metavar='FILE', type=str,
- default="https://raw.githubusercontent.com/SuperTux/addons/master/repository/",
- help="base url")
- args = parser.parse_args()
- if args.output is None:
- fout = sys.stdout
- generate_index(fout, args.DIRECTORY[0], args.url, args.zipdir)
- else:
- with open(args.output, "w") as fout:
- generate_index(fout, args.DIRECTORY[0], args.url, args.zipdir)
- # EOF #
|