예제 #1
0
def main():
    parser = argparse.ArgumentParser(add_help=False)

    parser.add_argument(
        "-v",
        "--verbosity",
        action="store",
        dest="verbosity",
        type=int,
        choices=(0, 1, 2, 3, 4, 5),
        required=False,
        default=3,
    )

    parser.add_argument(
        "--version",
        action="store_true",
    )
    parser.add_argument(
        "-h",
        "--help",
        dest="help",
        action="store_true",
    )
    parser.add_argument(
        "-u",
        "--ui",
        dest="ui_type",
        default="auto",
        choices=(
            "cmd",
            "gtk",
            "tk",
            # "qt",
            "auto",
            "none",
        ),
    )
    parser.add_argument(
        "--cmd",
        dest="ui_type",
        action="store_const",
        const="cmd",
        default=None,
        help="use command-line user interface",
    )
    parser.add_argument(
        "--gtk",
        dest="ui_type",
        action="store_const",
        const="gtk",
        default=None,
        help="use Gtk-based user interface",
    )
    parser.add_argument(
        "--tk",
        dest="ui_type",
        action="store_const",
        const="tk",
        default=None,
        help="use Tkinter-based user interface",
    )
    parser.add_argument(
        "--interactive",
        dest="interactive",
        action="store_true",
        default=None,
        help="switch to interactive command line interface",
    )
    parser.add_argument(
        "--no-interactive",
        dest="no_interactive",
        action="store_true",
        default=None,
        help=("do not automatically switch to interactive command line"
              " interface, for scripts"),
    )

    parser.add_argument(
        "-r",
        "--read-options",
        dest="readOptions",
        default="",
    )
    parser.add_argument(
        "-w",
        "--write-options",
        dest="writeOptions",
        default="",
    )

    parser.add_argument(
        "--json-read-options",
        dest="jsonReadOptions",
        default=None,
    )
    parser.add_argument(
        "--json-write-options",
        dest="jsonWriteOptions",
        default=None,
    )

    parser.add_argument(
        "--read-format",
        dest="inputFormat",
    )
    parser.add_argument(
        "--write-format",
        dest="outputFormat",
        action="store",
    )

    parser.add_argument(
        "--direct",
        dest="direct",
        action="store_true",
        default=None,
        help="if possible, convert directly without loading into memory",
    )
    parser.add_argument(
        "--indirect",
        dest="direct",
        action="store_false",
        default=None,
        help=(
            "disable `direct` mode, load full data into memory before writing"
            ", this is default"),
    )

    parser.add_argument(
        "--no-progress-bar",
        dest="progressbar",
        action="store_false",
        default=None,
    )
    parser.add_argument(
        "--no-color",
        dest="noColor",
        action="store_true",
        default=(os.sep != "/"),
    )

    parser.add_argument(
        "--sort",
        dest="sort",
        action="store_true",
        default=None,
    )
    parser.add_argument(
        "--no-sort",
        dest="sort",
        action="store_false",
        default=None,
    )
    parser.add_argument(
        "--sort-cache-size",
        dest="sortCacheSize",
        type=int,
        default=None,
    )

    # _______________________________

    parser.add_argument(
        "--reverse",
        dest="reverse",
        action="store_true",
    )

    parser.add_argument(
        "inputFilename",
        action="store",
        default="",
        nargs="?",
    )
    parser.add_argument(
        "outputFilename",
        action="store",
        default="",
        nargs="?",
    )

    def shouldUseCMD(args):
        if not canRunGUI():
            return True
        if args.interactive:
            return True
        if args.inputFilename and args.outputFilename:
            return True
        return False

    # _______________________________

    for key, option in UIBase.configDefDict.items():
        registerOption(parser, key, option)

    # _______________________________

    args = parser.parse_args()

    if args.version:
        print(f"PyGlossary {getVersion()}")
        sys.exit(0)

    log = logging.getLogger("pyglossary")

    log.setVerbosity(args.verbosity)
    log.addHandler(core.StdLogHandler(noColor=args.noColor), )
    # with the logger setted up, we can import other pyglossary modules, so they
    # can do some loggging in right way.

    core.checkCreateConfDir()

    if sys.getdefaultencoding() != "utf-8":
        log.warn(
            f"System encoding is not utf-8, it's {sys.getdefaultencoding()!r}")

    ##############################

    from pyglossary.glossary import Glossary, langDict
    from pyglossary.ui.ui_cmd import help, parseFormatOptionsStr

    Glossary.init()

    if log.isDebug():
        log.debug(f"en -> {langDict['en']!r}")

    ##############################

    ui_list = [
        "gtk",
        "tk",
    ]

    # log.info(f"PyGlossary {core.VERSION}")

    if args.help:
        help()
        sys.exit(0)

    # only used in ui_cmd for now
    readOptions = parseFormatOptionsStr(args.readOptions)
    if readOptions is None:
        return
    if args.jsonReadOptions:
        newReadOptions = json.loads(args.jsonReadOptions)
        if isinstance(newReadOptions, dict):
            readOptions.update(newReadOptions)
        else:
            log.error(f"invalid value for --json-read-options, "
                      f"must be an object/dict, not {type(newReadOptions)}")

    writeOptions = parseFormatOptionsStr(args.writeOptions)
    if writeOptions is None:
        return
    if args.jsonWriteOptions:
        newWriteOptions = json.loads(args.jsonWriteOptions)
        if isinstance(newWriteOptions, dict):
            writeOptions.update(newWriteOptions)
        else:
            log.error(f"invalid value for --json-write-options, "
                      f"must be an object/dict, not {type(newWriteOptions)}")
    """
		examples for read and write options:
		--read-options testOption=stringValue
		--read-options enableFoo=True
		--read-options fooList=[1,2,3]
		--read-options 'fooList=[1, 2, 3]'
		--read-options 'testOption=stringValue; enableFoo=True; fooList=[1, 2, 3]'
		--read-options 'testOption=stringValue;enableFoo=True;fooList=[1,2,3]'

		if a desired value contains ";", you can use --json-read-options
		or --json-write-options flags instead, with json object as value,
		quoted for command line. for example:
			'--json-write-options={"delimiter": ";"}'

	"""

    convertOptionsKeys = (
        "direct",
        "progressbar",
        "sort",
        "sortCacheSize",
        # "sortKey",  # TODO
    )

    config = {}
    for key, option in UIBase.configDefDict.items():
        if not option.cmd:
            continue
        value = getattr(args, key, None)
        if value is None:
            continue
        option = UIBase.configDefDict[key]
        if not option.validate(value):
            log.error("invalid config value: {key} = {value!r}")
            continue
        config[key] = value

    convertOptions = {}
    for key in convertOptionsKeys:
        value = getattr(args, key, None)
        if value is not None:
            convertOptions[key] = value

    if convertOptions.get("sort", False):
        convertOptions["defaultSortKey"] = Entry.defaultSortKey

    if args.inputFilename and readOptions:
        inputArgs = Glossary.detectInputFormat(
            args.inputFilename,
            format=args.inputFormat,
        )
        if not inputArgs:
            log.error(
                f"Could not detect format for input file {args.inputFilename}")
            sys.exit(1)
        inputFormat = inputArgs[1]
        readOptionsProp = Glossary.plugins[inputFormat].optionsProp
        for optName, optValue in readOptions.items():
            if optName not in Glossary.formatsReadOptions[inputFormat]:
                log.error(
                    f"Invalid option name {optName} for format {inputFormat}")
                sys.exit(1)
            prop = readOptionsProp[optName]
            optValueNew, ok = prop.evaluate(optValue)
            if not ok or not prop.validate(optValueNew):
                log.error(f"Invalid option value {optName}={optValue!r}"
                          f" for format {inputFormat}")
                sys.exit(1)
            readOptions[optName] = optValueNew

    if args.outputFilename and writeOptions:
        outputArgs = Glossary.detectOutputFormat(
            filename=args.outputFilename,
            format=args.outputFormat,
            inputFilename=args.inputFilename,
        )
        if outputArgs is None:
            sys.exit(1)
        _, outputFormat, _ = outputArgs
        writeOptionsProp = Glossary.plugins[outputFormat].optionsProp
        for optName, optValue in writeOptions.items():
            if optName not in Glossary.formatsWriteOptions[outputFormat]:
                log.error(
                    f"Invalid option name {optName} for format {outputFormat}")
                sys.exit(1)
            prop = writeOptionsProp[optName]
            optValueNew, ok = prop.evaluate(optValue)
            if not ok or not prop.validate(optValueNew):
                log.error(f"Invalid option value {optName}={optValue!r}"
                          f" for format {outputFormat}")
                sys.exit(1)
            writeOptions[optName] = optValueNew

    if config:
        log.debug(f"config = {config}")
    if convertOptions:
        log.debug(f"convertOptions = {convertOptions}")

    runKeywordArgs = dict(
        inputFilename=args.inputFilename,
        outputFilename=args.outputFilename,
        inputFormat=args.inputFormat,
        outputFormat=args.outputFormat,
        reverse=args.reverse,
        configOptions=config,
        readOptions=readOptions,
        writeOptions=writeOptions,
        convertOptions=convertOptions,
    )

    ui_type = args.ui_type

    if ui_type == "none":
        sys.exit(0 if base_ui_run(**runKeywordArgs) else 1)

    if ui_type == "auto" and shouldUseCMD(args):
        ui_type = "cmd"

    if ui_type == "cmd":
        if args.interactive:
            from pyglossary.ui.ui_cmd_interactive import UI
        elif args.inputFilename and args.outputFilename:
            from pyglossary.ui.ui_cmd import UI
        elif not args.no_interactive:
            from pyglossary.ui.ui_cmd_interactive import UI
        else:
            log.error("no input file given, try --help")
            sys.exit(1)
        sys.exit(0 if UI().run(**runKeywordArgs) else 1)

    if ui_type == "auto":
        ui_module = None
        for ui_type2 in ui_list:
            try:
                ui_module = __import__(
                    f"pyglossary.ui.ui_{ui_type2}",
                    fromlist=f"ui_{ui_type2}",
                )
            except ImportError:
                log.exception("error while importing UI module:")
            else:
                break
        if ui_module is None:
            log.error("no user interface module found! "
                      f"try \"{sys.argv[0]} -h\" to see command line usage")
            sys.exit(1)
    else:
        ui_module = __import__(
            f"pyglossary.ui.ui_{ui_type}",
            fromlist=f"ui_{ui_type}",
        )

    sys.exit(0 if ui_module.UI().run(**runKeywordArgs) else 1)
예제 #2
0
파일: main.py 프로젝트: lusu2004/pyglossary
def main():
    parser = argparse.ArgumentParser(add_help=False)

    parser.add_argument(
        "-v",
        "--verbosity",
        action="store",
        dest="verbosity",
        type=int,
        choices=(0, 1, 2, 3, 4, 5),
        required=False,
        default=3,
    )
    parser.add_argument(
        "--log-time",
        dest="log_time",
        action="store_true",
        default=None,
    )
    parser.add_argument(
        "--no-log-time",
        dest="log_time",
        action="store_false",
        default=None,
    )

    parser.add_argument(
        "--version",
        action="version",
        version=f"PyGlossary {VERSION}",
    )
    parser.add_argument(
        "-h",
        "--help",
        dest="help",
        action="store_true",
    )
    parser.add_argument(
        "-u",
        "--ui",
        dest="ui_type",
        default="auto",
        choices=(
            "cmd",
            "gtk",
            "tk",
            # "qt",
            "auto",
            "none",
        ),
    )

    parser.add_argument(
        "-r",
        "--read-options",
        dest="readOptions",
        default="",
    )
    parser.add_argument(
        "-w",
        "--write-options",
        dest="writeOptions",
        default="",
    )

    parser.add_argument(
        "--read-format",
        dest="inputFormat",
    )
    parser.add_argument(
        "--write-format",
        dest="outputFormat",
        action="store",
    )

    parser.add_argument(
        "--direct",
        dest="direct",
        action="store_true",
        default=None,
        help="if possible, convert directly without loading into memory",
    )
    parser.add_argument(
        "--indirect",
        dest="direct",
        action="store_false",
        default=None,
        help=(
            "disable `direct` mode, load full data into memory before writing"
            ", this is default"),
    )

    parser.add_argument(
        "--no-alts",
        dest="enable_alts",
        action="store_false",
        default=None,
        help="disable alternates",
    )

    parser.add_argument(
        "--no-progress-bar",
        dest="progressbar",
        action="store_false",
        default=None,
    )
    parser.add_argument(
        "--no-color",
        dest="noColor",
        action="store_true",
    )

    parser.add_argument(
        "--sort",
        dest="sort",
        action="store_true",
        default=None,
    )
    parser.add_argument(
        "--no-sort",
        dest="sort",
        action="store_false",
        default=None,
    )
    parser.add_argument(
        "--sort-cache-size",
        dest="sortCacheSize",
        type=int,
        default=None,
    )

    parser.add_argument(
        "--skip-resources",
        dest="skipResources",
        action="store_true",
        default=None,
        help="skip resources (images, audio, etc)",
    )
    parser.add_argument(
        "--utf8-check",
        dest="utf8Check",
        action="store_true",
        default=None,
    )
    parser.add_argument(
        "--no-utf8-check",
        dest="utf8Check",
        action="store_false",
        default=None,
    )
    parser.add_argument(
        "--lower",
        dest="lower",
        action="store_true",
        default=None,
        help="lowercase words before writing",
    )
    parser.add_argument(
        "--no-lower",
        dest="lower",
        action="store_false",
        default=None,
        help="do not lowercase words before writing",
    )
    parser.add_argument(
        "--remove-html",
        dest="remove_html",
        help="remove given html tags (comma-separated) from definitions",
    )
    parser.add_argument(
        "--remove-html-all",
        dest="remove_html_all",
        action="store_true",
        help="remove all html tags from definitions",
    )
    parser.add_argument(
        "--normalize-html",
        dest="normalize_html",
        action="store_true",
        help="lowercase and normalize html tags in definitions",
    )

    parser.add_argument(
        "--cleanup",
        dest="cleanup",
        action="store_true",
        default=None,
        help="cleanup cache or temporary files after convertion",
    )
    parser.add_argument(
        "--no-cleanup",
        dest="cleanup",
        action="store_false",
        default=None,
        help="do not cleanup cache or temporary files after convertion",
    )

    # _______________________________

    parser.add_argument(
        "--info",
        dest="save_info_json",
        action="store_true",
        help="save glossary info as json file with .info extension",
    )

    # _______________________________

    parser.add_argument(
        "--reverse",
        dest="reverse",
        action="store_true",
    )

    parser.add_argument(
        "inputFilename",
        action="store",
        default="",
        nargs="?",
    )
    parser.add_argument(
        "outputFilename",
        action="store",
        default="",
        nargs="?",
    )

    # _______________________________

    args = parser.parse_args()

    log = logging.getLogger("pyglossary")

    defaultVerbosity = log.getVerbosity()

    log.setVerbosity(args.verbosity)
    log.addHandler(core.StdLogHandler(noColor=args.noColor), )
    # with the logger setted up, we can import other pyglossary modules, so they
    # can do some loggging in right way.

    core.checkCreateConfDir()

    if sys.getdefaultencoding() != "utf-8":
        log.warn(
            f"System encoding is not utf-8, it's {sys.getdefaultencoding()!r}")

    ##############################

    from pyglossary.glossary import Glossary, langDict
    from pyglossary.ui.ui_cmd import help, parseFormatOptionsStr

    Glossary.init()

    if log.isDebug():
        log.debug(f"en -> {langDict['en']!r}")

    ##############################

    ui_list = (
        "gtk",
        "tk",
        "qt",
    )

    # log.info("PyGlossary %s"%VERSION)

    if args.help:
        help()
        sys.exit(0)

    if os.sep != "/":
        args.noColor = True

    # only used in ui_cmd for now
    readOptions = parseFormatOptionsStr(args.readOptions)
    if readOptions is None:
        return
    writeOptions = parseFormatOptionsStr(args.writeOptions)
    if writeOptions is None:
        return
    """
		examples for read and write options:
		--read-options testOption=stringValue
		--read-options enableFoo=True
		--read-options fooList=[1,2,3]
		--read-options 'fooList=[1, 2, 3]'
		--read-options 'testOption=stringValue; enableFoo=True; fooList=[1, 2, 3]'
		--read-options 'testOption=stringValue;enableFoo=True;fooList=[1,2,3]'
	"""

    prefOptionsKeys = (
        # "verbosity",
        "utf8Check",
        "lower",
        "skipResources",
        "enable_alts",
        "remove_html",
        "remove_html_all",
        "normalize_html",
        "save_info_json",
        "log_time",
        "cleanup",
    )

    convertOptionsKeys = (
        "direct",
        "progressbar",
        "sort",
        "sortCacheSize",
        # "sortKey",  # TODO
    )

    prefOptions = {}
    for param in prefOptionsKeys:
        value = getattr(args, param, None)
        if value is not None:
            prefOptions[param] = value

    convertOptions = {}
    for param in convertOptionsKeys:
        value = getattr(args, param, None)
        if value is not None:
            convertOptions[param] = value

    if convertOptions.get("sort", False):
        convertOptions["defaultSortKey"] = Entry.defaultSortKey

    if args.inputFilename and readOptions:
        inputFormat = Glossary.detectInputFormat(
            args.inputFilename,
            format=args.inputFormat,
        )
        if not inputFormat:
            log.error(
                f"Could not detect format for input file {args.inputFilename}")
            sys.exit(1)
        readOptionsProp = Glossary.plugins[inputFormat].optionsProp
        for optName, optValue in readOptions.items():
            if optName not in Glossary.formatsReadOptions[inputFormat]:
                log.error(
                    f"Invalid option name {optName} for format {inputFormat}")
                sys.exit(1)
            prop = readOptionsProp[optName]
            optValueNew, ok = prop.evaluate(optValue)
            if not ok or not prop.validate(optValueNew):
                log.error(f"Invalid option value {optName}={optValue!r}"
                          f" for format {inputFormat}")
                sys.exit(1)
            readOptions[optName] = optValueNew

    if args.outputFilename and writeOptions:
        _, outputFormat, _ = Glossary.detectOutputFormat(
            filename=args.outputFilename,
            format=args.outputFormat,
            inputFilename=args.inputFilename,
        )
        if not outputFormat:
            log.error(
                f"Could not detect format for output file {args.outputFilename}"
            )
            sys.exit(1)
        writeOptionsProp = Glossary.plugins[outputFormat].optionsProp
        for optName, optValue in writeOptions.items():
            if optName not in Glossary.formatsWriteOptions[outputFormat]:
                log.error(
                    f"Invalid option name {optName} for format {outputFormat}")
                sys.exit(1)
            prop = writeOptionsProp[optName]
            optValueNew, ok = prop.evaluate(optValue)
            if not ok or not prop.validate(optValueNew):
                log.error(f"Invalid option value {optName}={optValue!r}"
                          f" for format {outputFormat}")
                sys.exit(1)
            writeOptions[optName] = optValueNew

    if prefOptions:
        log.debug("prefOptions = %s", prefOptions)
    if convertOptions:
        log.debug("convertOptions = %s", convertOptions)
    """
	ui_type: User interface type
	Possible values:
		cmd - Command line interface, this ui will automatically selected
			if you give both input and output file
		gtk - GTK interface
		tk - Tkinter interface
		qt - Qt interface
		auto - Use the first available UI
	"""
    ui_type = args.ui_type

    if args.inputFilename:
        if args.outputFilename and ui_type != "none":
            ui_type = "cmd"
    else:
        if ui_type == "cmd":
            log.error("no input file given, try --help")
            exit(1)

    if ui_type == "none":
        if args.reverse:
            log.error("--reverse does not work with --ui=none")
            sys.exit(1)
        glos = Glossary()
        glos.convert(args.inputFilename,
                     inputFormat=args.inputFormat,
                     outputFilename=args.outputFilename,
                     outputFormat=args.outputFormat,
                     readOptions=readOptions,
                     writeOptions=writeOptions,
                     **convertOptions)
        sys.exit(0)
    elif ui_type == "cmd":
        from ui import ui_cmd
        sys.exit(0 if ui_cmd.UI().run(
            args.inputFilename,
            outputFilename=args.outputFilename,
            inputFormat=args.inputFormat,
            outputFormat=args.outputFormat,
            reverse=args.reverse,
            prefOptions=prefOptions,
            readOptions=readOptions,
            writeOptions=writeOptions,
            convertOptions=convertOptions,
        ) else 1)
    if ui_type == "auto":
        ui_module = None
        for ui_type2 in ui_list:
            try:
                ui_module = getattr(
                    __import__(f"ui.ui_{ui_type2}"),
                    f"ui_{ui_type2}",
                )
            except ImportError:
                log.exception("error while importing UI module:")
            else:
                break
        if ui_module is None:
            log.error("no user interface module found! "
                      f"try \"{sys.argv[0]} -h\" to see command line usage")
            sys.exit(1)
    else:
        ui_module = getattr(
            __import__(f"ui.ui_{ui_type}"),
            f"ui_{ui_type}",
        )

    sys.exit(0 if ui_module.UI(**prefOptions).run(
        editPath=args.inputFilename,
        readOptions=readOptions,
    ) else 1)
예제 #3
0
args = parser.parse_args()

log = logging.getLogger("root")

defaultVerbosity = log.getVerbosity()

log.setVerbosity(args.verbosity)
log.addHandler(
	core.StdLogHandler(noColor=args.noColor),
)
# with the logger setted up, we can import other pyglossary modules, so they
# can do some loggging in right way.


core.checkCreateConfDir()


##############################

from pyglossary.glossary import Glossary
from ui.ui_cmd import help, parseFormatOptionsStr

if args.verbosity != defaultVerbosity:
	Glossary.init()

##############################

ui_list = (
	"gtk",
	"tk",