Ctrl K
ComunidadGuías…

build/docbook-manual.py

Rama master · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
#!/usr/bin/python3 -u

import errno
import getopt
import glob
import os
from os import path
import shutil
import subprocess
import sys


# Constants
PUBLICAN = 'publican'

# Script options
options = "hda"
long_options = [
    "help",
    "delete",
    "epub",
    "html",
    "pdf",
    "txt",
    "release",
    "all"
    ]


def usage():
    print(f'''Usage: {path.basename(__file__)} \
/path/to/mantisbt/docbook /path/to/install [<lang> ...]
    Options:  -h | --help           Print this usage message
              -d | --delete         Delete install directory before building
                   --epub           Build EPUB manual
                   --html           Build HTML manual
                   --pdf            Build PDF manual
                   --txt            Build TXT manual
                   --release        Build single file types used for
                                    release tarballs
              -a | --all            Build all manual types
''')
# end usage()


def run_publican(args):
    """
    Run Publican with the given arguments.
    Prints an error message and exits with return code 1 if execution failed.

    :param args: Publican Command and arguments (as a list)
    :return:
    """
    publican = shutil.which(PUBLICAN)
    if publican is None:
        print(f"ERROR: {PUBLICAN} executable not found.")
        sys.exit(1)
    cmd = [publican]
    if type(args) is list:
        cmd.extend(args)
    else:
        cmd.append(args)

    try:
        print("Running", " ".join(cmd))
        ret = subprocess.run(cmd, text=True, capture_output=True, check=True)
        print(ret.stdout.strip())
        print()
    except subprocess.CalledProcessError as e:
        print(e.stderr.strip() if e.stderr else e.stdout.strip())
        print("ERROR:", e)
        sys.exit(1)


def main():
    try:
        opts, args = getopt.gnu_getopt(sys.argv[1:], options, long_options)
    except getopt.GetoptError as err:
        print(err)
        usage()
        sys.exit(2)

    # noinspection PyUnboundLocalVariable
    if len(args) < 2:
        usage()
        sys.exit(1)

    delete = False
    types = "html,pdf"

    # noinspection PyUnboundLocalVariable
    for opt, val in opts:
        if opt in ("-h", "--help"):
            usage()
            sys.exit(0)

        elif opt in ("-d", "--delete"):
            delete = True

        # Output formats
        elif opt in ("-a", "--all"):
            types = "html,html-desktop,txt,pdf,epub"
        elif opt == "--epub":
            types = "epub"
        elif opt == "--html":
            types = "html,html-desktop"
        elif opt == "--pdf":
            types = "pdf"
        elif opt == "--txt":
            types = "txt"
        elif opt == "--release":
            types = "html-desktop,pdf,txt"

    docroot = path.abspath(args[0])
    installroot = args[1]
    languages = []

    if len(args) > 2:
        languages.extend([lang for lang in args[2:] if lang])

    os.chdir(docroot)

    if delete and installroot != "/" and path.isdir(installroot):
        print("Deleting install directory " + installroot)
        for root, dirs, files in os.walk(installroot, topdown=False):
            for name in files:
                os.remove(path.join(root, name))
            for name in dirs:
                os.rmdir(path.join(root, name))

    buildcount = 0

    # Process all existing manuals
    for directory in next(os.walk(docroot))[1]:
        if directory == '.svn' or directory == 'template' or directory == 'erd':
            continue

        builddir = path.join(docroot, directory)
        os.chdir(builddir)

        # Languages to process
        if languages:
            langs = languages
        else:
            langs = next(os.walk(builddir))[1]
            if langs.count('.svn'):
                langs.remove('.svn')
            if langs.count('tmp'):
                langs.remove('tmp')

        # Build docbook with PUBLICAN
        if not path.exists('publican.cfg'):
            print("ERROR: publican.cfg not found")
            exit(1)

        print(f"Building manual in '{builddir}'\n")
        run_publican('clean')
        cmd = ['build', '--formats=' + types]
        if langs:
            cmd.append('--langs=' + ','.join(langs))
        run_publican(cmd)

        print(f"Copying generated manuals to '{installroot}'")
        for lang in langs:
            builddir = path.join('tmp', lang)
            installdir = path.join(installroot, lang, directory)

            # Create target directory tree
            try:
                os.makedirs(installdir)
            except OSError as e:
                # Ignore file exists error
                if e.errno != errno.EEXIST:
                    raise

            # Copy HTML manuals with rsync
            source = path.join(builddir, 'html*')
            glob_source = glob.glob(source)
            if glob_source:
                try:
                    rsync = ['rsync', '-a', '--delete'] + glob_source + [installdir]
                    print(" ".join(rsync))
                    subprocess.run(rsync, check=True)
                except subprocess.CalledProcessError as e:
                    print("ERROR:", e)
                    sys.exit(1)

            # Copy single file manuals (PDF, TXT and EPUB)
            for filetype in ['epub', 'pdf', 'txt']:
                if filetype == 'epub':
                    source = path.join(builddir, '*.epub')
                else:
                    source = path.join(builddir, filetype, '*' + filetype)
                dest = path.join(installdir, directory + '.' + filetype)
                for sourcefile in glob.glob(source):
                    print(f"Copying '{sourcefile}' to '{dest}'")
                    shutil.copy2(sourcefile, dest)
            print()

            run_publican('clean')
            print(f"{directory} Build complete\n")
            buildcount += len(langs)

    # end docbook build loop

    print(f"Done - {buildcount} docbooks built.\n")

# end main()


if __name__ == '__main__':
    main()