Source code for ged2doc.cli

# -*- coding: utf-8 -*-

"""Console script for ged2doc."""

from argparse import ArgumentParser, FileType
import locale
import logging
import os
import platform
import sys

from .size import String2Size
from .i18n import I18N, DATE_FORMATS
from .input import make_file_locator
from .html_writer import HtmlWriter
from .name import NameFormat
from .odt_writer import OdtWriter
from .utils import languages, system_lang
import ged2doc
import ged4py
from ged4py.model import NameOrder

_log = logging.getLogger(__name__)


NAME_ORDER_LIST = [item.value for item in NameOrder]


[docs]def _make_writer(args=None): """Make Writer instance based on command line arguments. Parameters ---------- args : `list` [ `str` ] List of command line arguments passed to argparse, optional, by default uses `sys.argv`. Returns ------- args : `argparse.Namespace` Parsed command line arguments. writer : `ged2doc.writer.Writer` Instance of `~ged2doc.writer.Writer` to use for writing output file. """ version = "ged2doc {0} (ged4py {1}; python {2})".format(ged2doc.__version__, ged4py.__version__, platform.python_version()) parser = ArgumentParser(description='Convert GEDCOM file into document.') parser.add_argument('-v', "--verbose", action="count", default=0, help="Print some info to standard output, " "-vv prints debug info.") parser.add_argument("--log", default=None, metavar="PATH", type=FileType(mode="wt"), help="Produces log file with debugging information.") parser.add_argument("--version", action="version", version=version, help="Print version information and exit") # TODO: can enable FileType when Python2 support is dropped parser.add_argument("input", # type=FileType(mode="rb",), help="Location of input file, input file can be " "either GEDCOM file or ZIP archive which can also " "include images.") parser.add_argument("output", help="Location of output file.") group = parser.add_argument_group("Input Options") group.add_argument('-i', "--image-path", metavar="PATH", help="Directory containing files with images") group.add_argument('-p', "--file-name-pattern", metavar="PATTERN", default="*.ged*", help="Pattern to search for GEDCOM file inside ZIP " "archive, default: %(default)s") group.add_argument("--encoding", help="Input file encoding, default is to guess " "from file contents") group.add_argument("--encoding-errors", default="strict", metavar="MODE", help="Mode for handling decoding errors, one of strict," " ignore, or replace; default: %(default)s") group = parser.add_argument_group("Output Options") group.add_argument('-t', "--type", default=None, choices=['html', 'odt'], help=("Type of the output document, possible values:" " %(choices)s; by default type is determined by" " output file extension (*.odt, *.html, or *.htm" " are recognized)")) group.add_argument('-l', "--language", default=system_lang(), metavar="LANG_CODE", choices=languages(), help="Language for output document, supported " "languages are: %(choices)s. Default is to use " "system language (=%(default)s).") group.add_argument('-d', "--date-format", default=None, metavar="FMT", choices=DATE_FORMATS, help="Date format in output document, one of " "%(choices)s; if missing then language-specific " "format is used.") group.add_argument('-s', "--sort-order", default=NameOrder.SURNAME_GIVEN.value, metavar="ORDER", choices=NAME_ORDER_LIST, help="Ordering of the individuals, one of " "%(choices)s; default: %(default)s.") group.add_argument("--locale", default=None, metavar="LOCALE", help=("Locale name to use for name ordering, " "default is to use system locale.")) group.add_argument("--no-missing-date", default=False, action="store_true", help="Do not output events if they have no dates.") group.add_argument("--no-image", default=False, action="store_true", help="Disable images in output document.") group.add_argument("--no-toc", default=False, action="store_true", help="Disable Table of Contents in output document.") group.add_argument("--no-stat", default=False, action="store_true", help="Disable Name Statistics in output document.") group.add_argument('-w', "--tree-width", default=4, type=int, metavar="NUMBER", help="Number of generations in ancestors tree, " "default: %(default)s") group = parser.add_argument_group("Name Format Options") group.add_argument("--name-surname-first", dest='name_fmt', action='append_const', const=NameFormat.SURNAME_FIRST, help="Format names with surname in leading position.") group.add_argument("--name-comma", dest='name_fmt', action='append_const', const=NameFormat.COMMA, help="Format names with surname followed by comma " "(only if surname is in leading position).") group.add_argument("--name-maiden", dest='name_fmt', action='append_const', const=NameFormat.MAIDEN, help="Format names with surname followed by maiden " "name in parentheses.") group.add_argument("--name-maiden-only", dest='name_fmt', action='append_const', const=NameFormat.MAIDEN_ONLY, help="Format names with maiden name for surname.") group.add_argument("--name-capital", dest='name_fmt', action='append_const', const=NameFormat.CAPITAL, help="Format names with surname and maiden name in " "all capital.") group = parser.add_argument_group("HTML Output Options") group.add_argument("--html-page-width", default="800px", metavar="SIZE", type=String2Size("px"), help="HTML page width in pixels; default: %(default)s") group.add_argument("--html-image-width", default="300px", metavar="SIZE", type=String2Size("px"), help="Image width in pixels; default: %(default)s") group.add_argument("--html-image-height", default="300px", metavar="SIZE", type=String2Size("px"), help="Image height in pixels; default: %(default)s") group.add_argument('-u', "--html-image-upscale", default=False, action="store_true", help="Upscale small images") group = parser.add_argument_group("ODT Output Options") group.add_argument("--odt-page-width", default="6in", metavar="SIZE", type=String2Size("in"), help="ODT page width in inches; default: %(default)s") group.add_argument("--odt-page-height", default="9in", metavar="SIZE", type=String2Size("in"), help="ODT page height in inches; default: %(default)s") group.add_argument("--odt-margin-left", default="0.5in", metavar="SIZE", type=String2Size("in"), help="Page left margin in inches; default: %(default)s") group.add_argument("--odt-margin-right", default="0.5in", metavar="SIZE", type=String2Size("in"), help="Page right margin in inches; " "default: %(default)s") group.add_argument("--odt-margin-top", default="0.5in", metavar="SIZE", type=String2Size("in"), help="Page top margin in inches; default: %(default)s") group.add_argument("--odt-margin-bottom", default="0.25in", metavar="SIZE", type=String2Size("in"), help="Page bottom margin in inches; " "default: %(default)s") group.add_argument("--odt-image-width", default="2in", metavar="SIZE", type=String2Size("in"), help="Image width in inches; default: %(default)s") group.add_argument("--odt-image-height", default="2in", metavar="SIZE", type=String2Size("in"), help="Image height in inches; default: %(default)s") group.add_argument("--first-page", default=1, metavar="NUMBER", type=int, help="Number of the first page; default: %(default)s") group.add_argument("--odt-tree-type", choices=["emf", "svg"], default="emf", metavar="FORMAT", help="Type of image format for ancestor tree, one of " "%(choices)s; default: %(default)s") args = parser.parse_args(args) # configure logging if args.verbose == 0: log_level = logging.WARN elif args.verbose == 1: log_level = logging.INFO else: log_level = logging.DEBUG handler = logging.StreamHandler(stream=sys.stderr) handler.setLevel(log_level) handlers = [handler] if args.log: # this will log all levels (NOTSET is default) handler = logging.StreamHandler(stream=args.log) handlers += [handler] # rot logger will pass all messages, handlers will filter them logfmt = "%(levelname)s: %(name)s (%(filename)s:%(lineno)d)"\ " -- %(message)s" logging.basicConfig(level=logging.NOTSET, format=logfmt, handlers=handlers) # some debugging info _log.debug("version: %s", version) _log.debug("args: %s", args) # set locale if args.locale: locale.setlocale(locale.LC_ALL, args.locale) else: locale.setlocale(locale.LC_ALL, '') _log.debug("LC_ALL: %s", locale.setlocale(locale.LC_ALL)) _log.debug("LC_COLLATE: %s", locale.setlocale(locale.LC_COLLATE)) # instantiate file locator try: flocator = make_file_locator(args.input, args.file_name_pattern, args.image_path) except Exception as exc: _log.debug("caught exception: %s", exc, exc_info=True) parser.error("Error reading input file: {0}".format(exc)) tr = I18N(args.language, args.date_format) name_fmt = NameFormat(0) for option in args.name_fmt or []: name_fmt |= option # guess output type if not set if args.type is None: ext = os.path.splitext(args.output)[1] if ext.lower() == ".odt": args.type = "odt" elif ext.lower() in (".htm", ".html"): args.type = "html" else: parser.error("Cannot determine document type from file extension," " use --type option to specify document type") _log.debug("args: %s", args) if args.type == "html": writer = HtmlWriter(flocator, args.output, tr, encoding=args.encoding, encoding_errors=args.encoding_errors, sort_order=NameOrder(args.sort_order), name_fmt=name_fmt, events_without_dates=not args.no_missing_date, make_toc=not args.no_toc, make_stat=not args.no_stat, make_images=not args.no_image, tree_width=args.tree_width, page_width=args.html_page_width, image_width=args.html_image_width, image_height=args.html_image_height, image_upscale=args.html_image_upscale) elif args.type == "odt": writer = OdtWriter(flocator, args.output, tr, encoding=args.encoding, encoding_errors=args.encoding_errors, sort_order=NameOrder(args.sort_order), events_without_dates=not args.no_missing_date, make_toc=not args.no_toc, make_stat=not args.no_stat, make_images=not args.no_image, tree_width=args.tree_width, name_fmt=name_fmt, page_width=args.odt_page_width, page_height=args.odt_page_height, margin_left=args.odt_margin_left, margin_right=args.odt_margin_right, margin_top=args.odt_margin_top, margin_bottom=args.odt_margin_bottom, image_width=args.odt_image_width, image_height=args.odt_image_height, first_page=args.first_page, tree_format=args.odt_tree_type) return args, writer
[docs]def main(args=None): """Console script for ged2doc. Parameters ---------- args : `list` [ `str` ], optional Command line arguments, be default ``sys.argv`` is used. """ args, writer = _make_writer(args) try: writer.save() _log.debug("Success") return 0 except Exception as exc: _log.debug("caught exception: %s", exc, exc_info=True) print("Error while producing a document:\n {}".format(exc), file=sys.stderr) # clear output file in case some partial output was written try: _log.debug("trying to remove output file: %s", args.output) os.unlink(args.output) except OSError as exc: _log.debug("caught exception while removing file: %s", exc) return 1