Example #1
0
        def make_match_group (names, negatable=False, orlinked=False):

            names_negs = [(x, False) for x in names]
            if negatable:
                names_negs.extend([(x, True) for x in names])

            matchers = []
            for name, neg in names_negs:
                nname = name
                if neg:
                    nname = "n" + name
                values = getattr(params, nname)
                if values is None: # parameter not given
                    continue
                if not isinstance(values, list):
                    values = [values]
                for value in values:
                    try:
                        if name == "fexpr":
                            m = make_msg_matcher(value, params)
                        else:
                            m = make_matcher(name, value, [], params, neg)
                    except ExprError, e:
                        raise SieveError(str_to_unicode(str(e)))
                    matchers.append(m)
Example #2
0
def _main():

    locale.setlocale(locale.LC_ALL, "")

    usage = _("@info command usage",
              "%(cmd)s [OPTIONS] VCS [POPATHS...]",
              cmd="%prog")
    desc = _("@info command description",
             "Obtains a list of proper words from the message text ")
    ver = _("@info command version", u"%(cmd)s (Pology) %(version)s\n"
            u"Copyright ©  2011 "
            u"Javier Viñal <%(email)s>",
            cmd="%prog",
            version=version(),
            email="*****@*****.**")

    opars = ColorOptionParser(usage=usage, description=desc, version=ver)
    add_cmdopt_filesfrom(opars)

    (options, free_args) = opars.parse_args(str_to_unicode(sys.argv[1:]))

    # Collect PO files in given paths.
    popaths = collect_paths_cmdline(rawpaths=free_args,
                                    filesfrom=options.files_from,
                                    elsecwd=True,
                                    respathf=collect_catalogs,
                                    abort=True)

    dict_en = enchant.Dict("en")
    dict_local = enchant.Dict("es")

    for path in popaths:
        extract_proper_words(path, dict_en, dict_local)

    dict_en.close()
    for word in sorted(dict_local.session_dict()):
        print word
    dict_local.session_dict(clear=True)
    dict_local.close()
Example #3
0
def main ():

    locale.setlocale(locale.LC_ALL, "")

    # Get defaults for command line options from global config.
    cfgsec = pology_config.section("poediff")
    def_do_merge = cfgsec.boolean("merge", True)

    # Setup options and parse the command line.
    usage = _("@info command usage",
        "%(cmd)s [OPTIONS] FILE1 FILE2\n"
        "%(cmd)s [OPTIONS] DIR1 DIR2\n"
        "%(cmd)s -c VCS [OPTIONS] [PATHS...]",
        cmd="%prog")
    desc = _("@info command description",
        "Create embedded diffs of PO files.")
    ver = _("@info command version",
        u"%(cmd)s (Pology) %(version)s\n"
        u"Copyright © 2009, 2010 "
        u"Chusslove Illich (Часлав Илић) <%(email)s>",
        cmd="%prog", version=version(), email="*****@*****.**")

    showvcs = list(set(available_vcs()).difference(["none"]))
    showvcs.sort()

    opars = ColorOptionParser(usage=usage, description=desc, version=ver)
    opars.add_option(
        "-b", "--skip-obsolete",
        action="store_true", dest="skip_obsolete", default=False,
        help=_("@info command line option description",
               "Do not diff obsolete messages."))
    opars.add_option(
        "-c", "--vcs",
        metavar=_("@info command line value placeholder", "VCS"),
        dest="version_control",
        help=_("@info command line option description",
               "Paths are under version control by given VCS; "
               "can be one of: %(vcslist)s.",
               vcslist=format_item_list(showvcs)))
    opars.add_option(
        "--list-options",
        action="store_true", dest="list_options", default=False,
        help=_("@info command line option description",
               "List the names of available options."))
    opars.add_option(
        "--list-vcs",
        action="store_true", dest="list_vcs", default=False,
        help=_("@info command line option description",
               "List the keywords of known version control systems."))
    opars.add_option(
        "-n", "--no-merge",
        action="store_false", dest="do_merge", default=def_do_merge,
        help=_("@info command line option description",
               "Do not try to indirectly pair messages by merging catalogs."))
    opars.add_option(
        "-o", "--output",
        metavar=_("@info command line value placeholder", "POFILE"),
        dest="output",
        help=_("@info command line option description",
               "Output diff catalog to a file instead of stdout."))
    opars.add_option(
        "-p", "--paired-only",
        action="store_true", dest="paired_only", default=False,
        help=_("@info command line option description",
               "When two directories are diffed, ignore catalogs which "
               "are not present in both directories."))
    opars.add_option(
        "-q", "--quiet",
        action="store_true", dest="quiet", default=False,
        help=_("@info command line option description",
               "Do not display any progress info."))
    opars.add_option(
        "-Q", "--quick",
        action="store_true", dest="quick", default=False,
        help=_("@info command line option description",
               "Equivalent to %(opt)s.",
               opt="-bns"))
    opars.add_option(
        "-r", "--revision",
        metavar=_("@info command line value placeholder", "REV1[:REV2]"),
        dest="revision",
        help=_("@info command line option description",
               "Revision from which to diff to current working copy, "
               "or from first to second revision (if VCS is given)."))
    opars.add_option(
        "-s", "--strip-headers",
        action="store_true", dest="strip_headers", default=False,
        help=_("@info command line option description",
               "Do not diff headers and do not write out the top header "
               "(resulting output cannot be used as patch)."))
    opars.add_option(
        "-U", "--update-effort",
        action="store_true", dest="update_effort", default=False,
        help=_("@info command line option description",
               "Instead of outputting the diff, calculate and output "
               "an estimate of the effort that was needed to update "
               "the translation from old to new paths. "
               "Ignores %(opt1)s and %(opt1)s options.",
               opt1="-b", opt2="-n"))
    add_cmdopt_colors(opars)

    (op, free_args) = opars.parse_args(str_to_unicode(sys.argv[1:]))

    if op.list_options:
        report(list_options(opars))
        sys.exit(0)
    if op.list_vcs:
        report("\n".join(showvcs))
        sys.exit(0)

    # Could use some speedup.
    try:
        import psyco
        psyco.full()
    except ImportError:
        pass

    set_coloring_globals(ctype=op.coloring_type, outdep=(not op.raw_colors))

    if op.quick:
        op.do_merge = False
        op.skip_obsolete = True
        op.strip_headers = True

    # Create VCS.
    vcs = None
    if op.version_control:
        if op.version_control not in available_vcs(flat=True):
            error_wcl(_("@info",
                        "Unknown VCS '%(vcs)s' selected.",
                        vcs=op.version_control))
        vcs = make_vcs(op.version_control)

    # Sanity checks on paths.
    paths = free_args
    if not vcs:
        if len(paths) != 2:
            error_wcl(_("@info",
                        "Exactly two paths are needed for diffing."))
        for path in paths:
            if not os.path.exists(path):
                error_wcl("path does not exist: %s" % path)
        p1, p2 = paths
        if (not (   (os.path.isfile(p1) and (os.path.isfile(p2)))
                 or (os.path.isdir(p1) and (os.path.isdir(p2))))
        ):
            error_wcl(_("@info",
                        "Both paths must be either files or directories."))
    else:
        # Default to current working dir if no paths given.
        paths = paths or ["."]
        for path in paths:
            if not os.path.exists(path):
                error_wcl(_("@info",
                            "Path '%(path)s' does not exist.",
                            path=path))
            if not vcs.is_versioned(path):
                error_wcl(_("@info",
                            "Path '%(path)s' is not under version control.",
                            path=path))

    # Collect and pair PO files in given paths.
    # Each pair specification is in the form of
    # ((path1, path2), (vpath1, vpath2))
    # where path* are the real paths, and vpath* the visual paths to be
    # presented in diff output.
    if not vcs:
        fpairs = collect_file_pairs(paths[0], paths[1], op.paired_only)
        pspecs = [(x, x) for x in fpairs]
    else:
        lst = op.revision and op.revision.split(":", 1) or []
        if len(lst) > 2:
            error_wcl(_("@info",
                        "Too many revisions given: %(revlist)s.",
                        revspec=format_item_list(lst)))
        elif len(lst) == 2:
            revs = lst # diff between revisions
        elif len(lst) == 1:
            revs = [lst[0], None] # diff from revision to working copy
        else:
            revs = ["", None] # diff from head to working copy
            # Replace original paths with modified/added catalogs.
            paths_nc = []
            for path in paths:
                for path in vcs.to_commit(path):
                    if path.endswith(".po") or path.endswith(".pot"):
                        paths_nc.append(path)
            paths = paths_nc
            paths.sort()
        pspecs = collect_pspecs_from_vcs(vcs, paths, revs, op.paired_only)

    if not op.update_effort:
        ecat, ndiffed = diff_pairs(pspecs, op.do_merge,
                                   colorize=(not op.output),
                                   shdr=op.strip_headers,
                                   noobs=op.skip_obsolete,
                                   quiet=op.quiet)
        if ndiffed > 0:
            hmsgctxt = ecat.header.get_field_value(EDST.hmsgctxt_field)
            lines = []
            msgs = list(ecat)
            if not op.strip_headers:
                msgs.insert(0, ecat.header.to_msg())
            for msg in msgs:
                if op.strip_headers and msg.msgctxt == hmsgctxt:
                    sepl = []
                    sepl += [msg.manual_comment[0]]
                    sepl += msg.msgid.split("\n")[:2]
                    lines.extend(["# %s\n" % x for x in sepl])
                    lines.append("\n")
                else:
                    lines.extend(msg.to_lines(force=True, wrapf=ecat.wrapf()))
            diffstr = cjoin(lines)[:-1] # remove last newline
            if op.output:
                file = open(op.output, "w")
                file.write(diffstr.encode(ecat.encoding()))
                file.close()
            else:
                report(diffstr)
    else:
        updeff = pairs_update_effort(pspecs, quiet=op.quiet)
        ls = []
        for kw, desc, val, fmtval in updeff:
            ls.append(_("@info",
                        "%(quantity)s: %(value)s",
                        quantity=desc, value=fmtval))
        report("\n".join(ls))

    # Clean up.
    cleanup_tmppaths()
Example #4
0
def _main():

    locale.setlocale(locale.LC_ALL, "")

    usage = _("@info command usage",
              "%(cmd)s [OPTIONS] VCS [POPATHS...]",
              cmd="%prog")
    desc = _(
        "@info command description",
        "Compose hybridized Ijekavian-Ekavian translation out of "
        "translation modified from Ekavian to Ijekavian or vice-versa.")
    ver = _("@info command version", u"%(cmd)s (Pology) %(version)s\n"
            u"Copyright © 2009, 2010 "
            u"Chusslove Illich (Часлав Илић) <%(email)s>",
            cmd="%prog",
            version=version(),
            email="*****@*****.**")

    opars = ColorOptionParser(usage=usage, description=desc, version=ver)
    opars.add_option(
        "-a",
        "--accept-changes",
        action="store_true",
        dest="accept_changes",
        default=False,
        help=_(
            "@info command line option description",
            "Accept messages which have some changes between base "
            "and reconstructed base text."))
    opars.add_option("-r",
                     "--base-revision",
                     metavar=_("@info command line value placeholder",
                               "REVISION"),
                     action="store",
                     dest="base_revision",
                     default=None,
                     help=_(
                         "@info command line option description",
                         "Use the given revision as base for hybridization, "
                         "instead of local latest revision."))
    add_cmdopt_filesfrom(opars)

    (options, free_args) = opars.parse_args(str_to_unicode(sys.argv[1:]))

    try:
        import psyco
        psyco.full()
    except ImportError:
        pass

    # Create VCS.
    if len(free_args) < 1:
        showvcs = list(set(available_vcs()).difference(["none"]))
        showvcs.sort()
        error(
            _("@info", "Version control system not given "
              "(can be one of: %(vcslist)s).",
              vcslist=format_item_list(showvcs)))
    vcskey = free_args.pop(0)
    if vcskey not in available_vcs(flat=True):
        error(
            _("@info", "Unknown version control system '%(vcs)s'.",
              vcs=vcskey))
    vcs = make_vcs(vcskey)

    # Collect PO files in given paths.
    popaths = collect_paths_cmdline(rawpaths=free_args,
                                    filesfrom=options.files_from,
                                    elsecwd=True,
                                    respathf=collect_catalogs,
                                    abort=True)

    # Catalogs must be under version control.
    for path in popaths:
        if not vcs.is_versioned(path):
            error(
                _("@info",
                  "Catalog '%(file)s' is not under version control.",
                  file=path))

    # Go by modified PO file and hybridize it.
    for path in popaths:
        # Extract local head counterpart.
        tmpf = NamedTemporaryFile(prefix="pohybdl-export-", suffix=".po")
        if not vcs.export(path, options.base_revision, tmpf.name):
            error(
                _("@info",
                  "Version control system cannot export file '%(file)s'.",
                  file=path))
        # Hybridize by comparing local head and modified file.
        hybdl(path, tmpf.name, options.accept_changes)
Example #5
0
    @type abort: bool

    @return: matcher function
    @rtype: (msgf, msg, cat, hl=[])->bool
    """

    mopts = _prep_attrobj(mopts, dict(case=False, ))

    try:
        expr, p = _build_expr_r(exprstr, 0, len(exprstr), mopts)
        if p < len(exprstr):
            raise ExprError(exprstr,
                            _("@item:intext", "premature end of expression"))
    except ExprError, e:
        if abort:
            error(str_to_unicode(str(e)))
        else:
            raise
    return expr


def make_msg_fmatcher(exprstr,
                      mopts=None,
                      accels=None,
                      filters=[],
                      abort=False):
    """
    Build expression matcher for messages, with filtering.

    Like L{make_msg_matcher}, except that matchers built by this function
    do their own filtering, and so omit the first argument.
Example #6
0
def _main ():

    locale.setlocale(locale.LC_ALL, "")

    usage= _("@info command usage",
        "%(cmd)s [OPTIONS] [DKEY|SRCPATH|:SRCNAME]...",
        cmd="%prog")
    desc = _("@info command description",
        "Check validity and expand derivations from internal trapnakron.")
    ver = _("@info command version",
        u"%(cmd)s (Pology) %(version)s\n"
        u"Copyright © 2009, 2010 "
        u"Chusslove Illich (Часлав Илић) &lt;%(email)s&gt;",
        cmd="%prog", version=version(), email="*****@*****.**")

    opars = ColorOptionParser(usage=usage, description=desc, version=ver)
    opars.add_option(
        "-e", "--expansion-sample",
        action="store_true", dest="demoexp", default=False,
        help=_("@info command line option description",
               "Show a sample of expanded properties for "
               "each valid derivation."))
    opars.add_option(
        "-k", "--show-keys",
        action="store_true", dest="expwkeys", default=False,
        help=_("@info command line option description",
               "When expanding, also show all derivation keys by derivation."))
    opars.add_option(
        "-m", "--modified",
        action="store_true", dest="modified", default=False,
        help=_("@info command line option description",
               "Validate or expand only modified derivations."))
    opars.add_option(
        "-r", "--regex",
        action="store_true", dest="regex", default=False,
        help=_("@info command line option description",
               "Source names and derivation keys given in command line "
               "are regular expressions."))
    opars.add_option(
        "-s", "--statistics",
        action="store_true", dest="statistics", default=False,
        help=_("@info command line option description",
               "Show statistics."))

    (options, free_args) = opars.parse_args(str_to_unicode(sys.argv[1:]))

    try:
        import psyco
        psyco.full()
    except ImportError:
        pass

    onlysrcs = set()
    onlykeys = set()
    sksep = ":"
    for arg in free_args:
        if os.path.isfile(arg):
            test = os.path.splitext(arg.split(os.path.sep)[-1])[0]
            onlysrcs.add(test)
        elif arg.startswith(sksep):
            test = arg[len(sksep):]
            if options.regex:
                test = _Wre(test)
            onlysrcs.add(test)
        else:
            if options.regex:
                arg = _Wre(arg)
            else:
                arg = identify(arg)
            onlykeys.add(arg)

    onlysrcs = onlysrcs or None
    onlykeys = onlykeys or None

    # Create and validate the trapnakron.
    tp = trapnakron_ui()
    if options.modified:
        onlysrcs, onlykeys = _collect_mod_dkeys(tp, onlysrcs, onlykeys)
    validate(tp, onlysrcs, onlykeys, options.demoexp, options.expwkeys)

    if options.statistics:
        _statistics(tp, onlysrcs, onlykeys)
Example #7
0
def validate (tp, onlysrcs=None, onlykeys=None, demoexp=False, expwkeys=False):

    needed_pkeys = set()

    nom_pkeys = (
        [u"н"],
        [u"нм", u"нж", u"нс", u"ну"],
    )
    needed_pkeys.update(sum(nom_pkeys, []))

    gender_pkey = u"_род"
    needed_pkeys.add(gender_pkey)

    known_genders = set((u"м", u"ж", u"с", u"у"))
    known_genders.update(map(ctol, known_genders))

    known_alts = [
        ("_s", u"сист"),
        ("_a", u"алт"),
        ("_a2", u"алт2"),
        ("_a3", u"алт3"),
    ]
    base_envs = [u"", u"л", u"иј", u"ијл"]
    all_envs = set(base_envs)
    for aenv in [x[1] for x in known_alts]:
        all_envs.update(x + aenv for x in base_envs)

    if demoexp:
        demoexp_pkeys = [u"н", u"г", u"д", u"а", u"в", u"и",
                         u"нк", u"гк", u"дк", u"ак", u"вк",
                         u"нм", u"нмп"]
        needed_pkeys.update(demoexp_pkeys)

    dkeys_by_rtkey = {}

    # Sort keys such that derivations are checked by file and position.
    dkeys = tp.dkeys(single=onlykeys is None)
    def sortkey (x):
        path, lno, cno = tp.source_pos(x)
        return path.count(os.path.sep), path, lno, cno
    dkeys = sorted(dkeys, key=sortkey)

    nproblems = 0
    unmatched_srcs = set(onlysrcs) if onlysrcs is not None else None
    unmatched_keys = set(onlykeys) if onlykeys is not None else None
    reported_fmtexps = set()

    for dkey in dkeys:
        srcname = tp.source_name(dkey)
        path, lno, cno = tp.source_pos(dkey)
        cnproblems = 0

        if (   (    onlysrcs is not None
                and not _match_text(srcname, onlysrcs, unmatched_srcs))
            or (    onlykeys is not None
                and not _match_text(dkey, onlykeys, unmatched_keys))
        ):
            continue

        try:
            aprops = []
            seenesuffs = set()
            cenvs = tp.envs(dkey)
            for cenv in cenvs:
                if cenv != "":
                    envmatched = False
                    for ksuff, esuff in known_alts:
                        if cenv in all_envs and cenv.endswith(esuff):
                            envmatched = True
                            break
                else:
                    envmatched = True
                    ksuff, esuff = "", ""
                if envmatched and esuff not in seenesuffs:
                    dkeym = dkey + ksuff
                    props = dict([(x, tp.get2(dkeym, norm_pkey(x)))
                                   for x in needed_pkeys])
                    aprops.append((esuff, props))
                    seenesuffs.add(esuff)
                elif cenv not in all_envs:
                    warning(_("@info",
                              "Derivation at %(file)s:%(line)d:%(col)d "
                              "defines unknown environment '%(env)s'.",
                              file=path, line=lno, col=cno, env=cenv))
                    cnproblems += 1
        except Exception, e:
            warning(str_to_unicode(str(e)))
            cnproblems += 1
            continue

        for esuff, props in aprops:
            # Assure all nominative forms are unique.
            for pkeys in nom_pkeys: # select first nominative set by priority
                pvals = [props.get(x) for x in pkeys]
                noms = filter(lambda x: x is not None, pvals)
                if noms:
                    break
            if noms:
                rtkeys = map(norm_rtkey, noms)
                for rtkey in rtkeys:
                    odkey = dkeys_by_rtkey.get(rtkey)
                    if odkey is not None and tp.props(dkey) != tp.props(odkey):
                        opath, olno, ocno = tp.source_pos(odkey)
                        warning(_("@info",
                                  "Derivation at %(file1)s:%(line1)d:%(col1)d "
                                  "has normalized nominative equal to "
                                  "derivation at %(file2)s:%(line2)d:%(col2)d; "
                                  "consider adding a disambiguation marker "
                                  "(%(dchar)s).",
                                  file1=path, line1=lno, col1=cno,
                                  file2=opath, line2=olno, col2=ocno,
                                  dchar=_disamb_marker))
                        cnproblems += 1
                for rtkey in rtkeys: # must be in new loop
                    dkeys_by_rtkey[rtkey] = dkey

            # Assure presence of gender on noun derivations.
            if props.get(nom_pkeys[0][0]) is not None:
                gender = props.get(gender_pkey)
                if gender is None:
                    warning(_("@info",
                              "Derivation at %(file)s:%(line)d:%(col)d "
                              "does not define gender.",
                              file=path, line=lno, col=cno))
                    cnproblems += 1
                else:
                    for gender in hictoall(gender):
                        if gender not in known_genders:
                            warning(_("@info",
                                      "Derivation at %(file)s:%(line)d:%(col)d "
                                      "defines unknown gender '%(gen)s'.",
                                      file=path, line=lno, col=cno, gen=gender))
                            cnproblems += 1

            # Show selection of expanded properties if requested.
            if demoexp and not cnproblems:
                demoprops = [(x, props.get(x)) for x in demoexp_pkeys]
                demoprops = filter(lambda x: x[1] is not None, demoprops)
                fmtprops = ["%s=%s" % (x[0], _escape_pval(x[1]))
                            for x in demoprops]
                fmtsyns = ["%s" % _escape_syn(x) for x in tp.syns(dkey)]
                fmtexp = ", ".join(fmtsyns) + ": " + ", ".join(fmtprops)
                if expwkeys:
                    fmtdkeys = ", ".join(sorted(tp.altdkeys(dkey)))
                    fmtexp = "# " + fmtdkeys + "\n" + fmtexp
                if fmtexp not in reported_fmtexps:
                    if not esuff:
                        report(fmtexp)
                        reported_fmtexps.add(fmtexp)
                    else:
                        afmtexp = "    @" + esuff + ": " + ", ".join(fmtprops)
                        report(afmtexp)

        nproblems += cnproblems
        tp.empty_pcache()
Example #8
0
def main():

    locale.setlocale(locale.LC_ALL, "")

    # Get defaults for command line options from global config.
    cfgsec = pology_config.section("posieve")
    def_do_skip = cfgsec.boolean("skip-on-error", True)
    def_msgfmt_check = cfgsec.boolean("msgfmt-check", False)
    def_skip_obsolete = cfgsec.boolean("skip-obsolete", False)

    # Setup options and parse the command line.
    usage = _("@info command usage",
              "%(cmd)s [OPTIONS] SIEVE [POPATHS...]",
              cmd="%prog")
    desc = _(
        "@info command description",
        "Apply sieves to PO paths, which may be either single PO files or "
        "directories to search recursively for PO files. "
        "Some of the sieves only examine PO files, while others "
        "modify them as well. "
        "The first non-option argument is the sieve name; "
        "a list of several comma-separated sieves can be given too.")
    ver = _("@info command version", u"%(cmd)s (Pology) %(version)s\n"
            u"Copyright © 2007, 2008, 2009, 2010 "
            u"Chusslove Illich (Часлав Илић) &lt;%(email)s&gt;",
            cmd="%prog",
            version=version(),
            email="*****@*****.**")

    opars = ColorOptionParser(usage=usage, description=desc, version=ver)
    opars.add_option(
        "-a",
        "--announce-entry",
        action="store_true",
        dest="announce_entry",
        default=False,
        help=_("@info command line option description",
               "Announce that header or message is just about to be sieved."))
    opars.add_option("-b",
                     "--skip-obsolete",
                     action="store_true",
                     dest="skip_obsolete",
                     default=def_skip_obsolete,
                     help=_("@info command line option description",
                            "Do not sieve obsolete messages."))
    opars.add_option(
        "-c",
        "--msgfmt-check",
        action="store_true",
        dest="msgfmt_check",
        default=def_msgfmt_check,
        help=_("@info command line option description",
               "Check catalogs by %(cmd)s and skip those which do not pass.",
               cmd="msgfmt -c"))
    opars.add_option("-u",
                     "--single-entry",
                     metavar=_("@info command line value placeholder",
                               "ENTRY_NUMBER"),
                     action="store",
                     dest="single_entry",
                     default=0,
                     help=_("@info command line option description",
                            "Only perform the check on this ENTRY_NUMBER."))
    opars.add_option(
        "--force-sync",
        action="store_true",
        dest="force_sync",
        default=False,
        help=_("@info command line option description",
               "Force rewriting of all messages, whether modified or not."))
    opars.add_option("-H",
                     "--help-sieves",
                     action="store_true",
                     dest="help_sieves",
                     default=False,
                     help=_("@info command line option description",
                            "Show help for applied sieves."))
    opars.add_option("--issued-params",
                     action="store_true",
                     dest="issued_params",
                     default=False,
                     help=_(
                         "@info command line option description",
                         "Show all issued sieve parameters "
                         "(from command line and user configuration)."))
    opars.add_option("-l",
                     "--list-sieves",
                     action="store_true",
                     dest="list_sieves",
                     default=False,
                     help=_("@info command line option description",
                            "List available internal sieves."))
    opars.add_option("--list-options",
                     action="store_true",
                     dest="list_options",
                     default=False,
                     help=_("@info command line option description",
                            "List the names of available options."))
    opars.add_option("--list-sieve-names",
                     action="store_true",
                     dest="list_sieve_names",
                     default=False,
                     help=_("@info command line option description",
                            "List the names of available internal sieves."))
    opars.add_option("--list-sieve-params",
                     action="store_true",
                     dest="list_sieve_params",
                     default=False,
                     help=_("@info command line option description",
                            "List the parameters known to issued sieves."))
    opars.add_option("-m",
                     "--output-modified",
                     metavar=_("@info command line value placeholder", "FILE"),
                     action="store",
                     dest="output_modified",
                     default=None,
                     help=_("@info command line option description",
                            "Output names of modified files into FILE."))
    opars.add_option("--no-skip",
                     action="store_false",
                     dest="do_skip",
                     default=def_do_skip,
                     help=_(
                         "@info command line option description",
                         "Do not try to skip catalogs which signal errors."))
    opars.add_option("--no-sync",
                     action="store_false",
                     dest="do_sync",
                     default=True,
                     help=_("@info command line option description",
                            "Do not write any modifications to catalogs."))
    opars.add_option("-q",
                     "--quiet",
                     action="store_true",
                     dest="quiet",
                     default=False,
                     help=_(
                         "@info command line option description",
                         "Do not display any progress info "
                         "(does not influence sieves themselves)."))
    opars.add_option("-s",
                     metavar=_("@info command line value placeholder",
                               "NAME[:VALUE]"),
                     action="append",
                     dest="sieve_params",
                     default=[],
                     help=_("@info command line option description",
                            "Pass a parameter to sieves."))
    opars.add_option(
        "-S",
        metavar=_("@info command line value placeholder", "NAME[:VALUE]"),
        action="append",
        dest="sieve_no_params",
        default=[],
        help=_(
            "@info command line option description",
            "Remove a parameter to sieves "
            "(e.g. if it was issued through user configuration)."))
    opars.add_option("-v",
                     "--verbose",
                     action="store_true",
                     dest="verbose",
                     default=False,
                     help=_("@info command line option description",
                            "Output more detailed progress information."))
    add_cmdopt_filesfrom(opars)
    add_cmdopt_incexc(opars)
    add_cmdopt_colors(opars)

    (op, free_args) = opars.parse_args(str_to_unicode(sys.argv[1:]))

    if op.list_options:
        report(list_options(opars))
        sys.exit(0)

    if len(free_args) < 1 and not (op.list_sieves or op.list_sieve_names):
        error(_("@info", "No sieve to apply given."))

    op.raw_sieves = []
    op.raw_paths = []
    if len(free_args) > 2 and op.single_entry != 0:
        error(
            _("@info",
              "With single entry mode, you can only give one input file."))

    if len(free_args) >= 1:
        op.raw_sieves = free_args[0]
        op.raw_paths = free_args[1:]

    # Could use some speedup.
    try:
        import psyco
        psyco.full()
    except ImportError:
        pass

    set_coloring_globals(ctype=op.coloring_type, outdep=(not op.raw_colors))

    # Dummy-set all internal sieves as requested if sieve listing required.
    sieves_requested = []
    if op.list_sieves or op.list_sieve_names:
        # Global sieves.
        modpaths = glob.glob(os.path.join(datadir(), "sieve", "[a-z]*.py"))
        modpaths.sort()
        for modpath in modpaths:
            sname = os.path.basename(modpath)[:-3]  # minus .py
            sname = sname.replace("_", "-")
            sieves_requested.append(sname)
        # Language-specific sieves.
        modpaths = glob.glob(
            os.path.join(datadir(), "lang", "*", "sieve", "[a-z]*.py"))
        modpaths.sort()
        for modpath in modpaths:
            sname = os.path.basename(modpath)[:-3]  # minus .py
            sname = sname.replace("_", "-")
            lang = os.path.basename(os.path.dirname(os.path.dirname(modpath)))
            sieves_requested.append(lang + ":" + sname)

    # No need to load and setup sieves if only listing sieve names requested.
    if op.list_sieve_names:
        report("\n".join(sieves_requested))
        sys.exit(0)

    # Load sieve modules from supplied names in the command line.
    if not sieves_requested:
        sieves_requested = op.raw_sieves.split(",")
    sieve_modules = []
    for sieve_name in sieves_requested:
        # Resolve sieve file.
        if not sieve_name.endswith(".py"):
            # One of internal sieves.
            if ":" in sieve_name:
                # Language-specific internal sieve.
                lang, name = sieve_name.split(":")
                sieve_path_base = os.path.join("lang", lang, "sieve", name)
            else:
                sieve_path_base = os.path.join("sieve", sieve_name)
            sieve_path_base = sieve_path_base.replace("-", "_") + ".py"
            sieve_path = os.path.join(datadir(), sieve_path_base)
        else:
            # Sieve name is its path.
            sieve_path = sieve_name
        try:
            sieve_file = open(unicode_to_str(sieve_path))
            # ...unicode_to_str because of exec below.
        except IOError:
            error(_("@info", "Cannot load sieve '%(file)s'.", file=sieve_path))
        # Load file into new module.
        sieve_mod_name = "sieve_" + str(len(sieve_modules))
        sieve_mod = imp.new_module(sieve_mod_name)
        exec sieve_file in sieve_mod.__dict__
        sieve_file.close()
        sys.modules[sieve_mod_name] = sieve_mod  # to avoid garbage collection
        sieve_modules.append((sieve_name, sieve_mod))
        if not hasattr(sieve_mod, "Sieve"):
            error(
                _("@info",
                  "Module '%(file)s' does not define %(classname)s class.",
                  file=sieve_path,
                  classname="Sieve"))

    # Setup sieves (description, known parameters...)
    pp = ParamParser()
    snames = []
    for name, mod in sieve_modules:
        scview = pp.add_subcmd(name)
        if hasattr(mod, "setup_sieve"):
            mod.setup_sieve(scview)
        snames.append(name)

    # If info on sieves requested, report and exit.
    if op.list_sieves:
        report(_("@info", "Available internal sieves:"))
        report(pp.listcmd(snames))
        sys.exit(0)
    elif op.list_sieve_params:
        params = set()
        for scview in pp.cmdviews():
            params.update(scview.params(addcol=True))
        report("\n".join(sorted(params)))
        sys.exit(0)
    elif op.help_sieves:
        report(_("@info", "Help for sieves:"))
        report("")
        report(pp.help(snames))
        sys.exit(0)

    # Prepare sieve parameters for parsing.
    sieve_params = list(op.sieve_params)
    # - append paramaters according to configuration
    sieve_params.extend(read_config_params(pp.cmdviews(), sieve_params))
    # - remove paramaters according to command line
    if op.sieve_no_params:
        sieve_params_mod = []
        for parspec in sieve_params:
            if parspec.split(":", 1)[0] not in op.sieve_no_params:
                sieve_params_mod.append(parspec)
        sieve_params = sieve_params_mod

    # If assembly of issued parameters requested, report and exit.
    if op.issued_params:
        escparams = []
        for parspec in sieve_params:
            if ":" in parspec:
                param, value = parspec.split(":", 1)
                escparam = "%s:%s" % (param, escape_sh(value))
            else:
                escparam = parspec
            escparams.append(escparam)
        fmtparams = " ".join(["-s%s" % x for x in sorted(escparams)])
        if fmtparams:
            report(fmtparams)
        sys.exit(0)

    # Parse sieve parameters.
    sparams, nacc_params = pp.parse(sieve_params, snames)
    if nacc_params:
        error(
            _("@info", "Parameters not accepted by any of issued subcommands: "
              "%(paramlist)s.",
              paramlist=format_item_list(nacc_params)))

    # ========================================
    # FIXME: Think of something less ugly.
    # Add as special parameter to each sieve:
    # - root paths from which the catalogs are collected
    # - whether destination independent coloring is in effect
    # - test function for catalog selection
    root_paths = []
    if op.raw_paths:
        root_paths.extend(op.raw_paths)
    if op.files_from:
        for ffpath in op.files_from:
            root_paths.extend(collect_paths_from_file(ffpath))
    if not op.raw_paths and not op.files_from:
        root_paths = ["."]
    is_cat_included = build_path_selector(incnames=op.include_names,
                                          incpaths=op.include_paths,
                                          excnames=op.exclude_names,
                                          excpaths=op.exclude_paths)
    for p in sparams.values():
        p.root_paths = root_paths
        p.raw_colors = op.raw_colors
        p.is_cat_included = is_cat_included
    # ========================================

    # Create sieves.
    sieves = []
    for name, mod in sieve_modules:
        sieves.append(mod.Sieve(sparams[name]))

    # Get the message monitoring indicator from the sieves.
    # Monitor unless all sieves have requested otherwise.
    use_monitored = False
    for sieve in sieves:
        if getattr(sieve, "caller_monitored", True):
            use_monitored = True
            break
    if op.verbose and not use_monitored:
        report(_("@info:progress", "--> Not monitoring messages."))

    # Get the sync indicator from the sieves.
    # Sync unless all sieves have requested otherwise,
    # and unless syncing is disabled globally in command line.
    do_sync = False
    for sieve in sieves:
        if getattr(sieve, "caller_sync", True):
            do_sync = True
            break
    if not op.do_sync:
        do_sync = False
    if op.verbose and not do_sync:
        report(_("@info:progress", "--> Not syncing after sieving."))

    # Open in header-only mode if no sieve has message processor.
    # Categorize sieves by the presence of message/header processors.
    use_headonly = True
    header_sieves = []
    header_sieves_last = []
    message_sieves = []
    for sieve in sieves:
        if hasattr(sieve, "process"):
            use_headonly = False
            message_sieves.append(sieve)
        if hasattr(sieve, "process_header"):
            header_sieves.append(sieve)
        if hasattr(sieve, "process_header_last"):
            header_sieves_last.append(sieve)
    if op.verbose and use_headonly:
        report(_("@info:progress",
                 "--> Opening catalogs in header-only mode."))

    # Collect catalog paths.
    fnames = collect_paths_cmdline(rawpaths=op.raw_paths,
                                   incnames=op.include_names,
                                   incpaths=op.include_paths,
                                   excnames=op.exclude_names,
                                   excpaths=op.exclude_paths,
                                   filesfrom=op.files_from,
                                   elsecwd=True,
                                   respathf=collect_catalogs,
                                   abort=True)

    if op.do_skip:
        errwarn = warning
        errwarn_on_msg = warning_on_msg
    else:
        errwarn = error
        errwarn_on_msg = error_on_msg

    # Prepare inline progress indicator.
    if not op.quiet:
        update_progress = init_file_progress(fnames,
                                             addfmt=t_("@info:progress",
                                                       "Sieving: %(file)s"))

    # Sieve catalogs.
    modified_files = []
    for fname in fnames:
        if op.verbose:
            report(_("@info:progress", "Sieving %(file)s...", file=fname))
        elif not op.quiet:
            update_progress(fname)

        if op.msgfmt_check:
            d1, oerr, ret = collect_system(
                ["msgfmt", "-o", "/dev/null", "-c", fname])
            if ret != 0:
                oerr = oerr.strip()
                errwarn(
                    _("@info:progress", "%(file)s: %(cmd)s check failed:\n"
                      "%(msg)s",
                      file=fname,
                      cmd="msgfmt -c",
                      msg=oerr))
                warning(
                    _("@info:progress",
                      "Skipping catalog due to syntax check failure."))
                continue

        try:
            cat = Catalog(fname,
                          monitored=use_monitored,
                          headonly=use_headonly,
                          single_entry=int(op.single_entry))
        except CatalogSyntaxError, e:
            errwarn(
                _("@info:progress",
                  "%(file)s: Parsing failed: %(msg)s",
                  file=fname,
                  msg=e))
            warning(
                _("@info:progress",
                  "Skipping catalog due to parsing failure."))
            continue

        skip = False
        # First run all header sieves.
        if header_sieves and op.announce_entry:
            report(
                _("@info:progress",
                  "Sieving header of %(file)s...",
                  file=fname))
        for sieve in header_sieves:
            try:
                ret = sieve.process_header(cat.header, cat)
            except SieveCatalogError, e:
                errwarn(
                    _("@info:progress",
                      "%(file)s:header: Sieving failed: %(msg)s",
                      file=fname,
                      msg=e))
                skip = True
                break
            if ret not in (None, 0):
                break
Example #9
0
def main():

    locale.setlocale(locale.LC_ALL, "")

    # Get defaults for command line options from global config.
    cfgsec = pology_config.section("poepatch")
    def_do_merge = cfgsec.boolean("merge", True)

    # Setup options and parse the command line.
    usage = _("@info command usage", "%(cmd)s [OPTIONS] [OPTIONS] &lt; EDIFF\n"
              "%(cmd)s -u [OPTIONS] PATHS...",
              cmd="%prog")
    desc = _("@info command description",
             "Apply embedded diff of PO files as patch.")
    ver = _("@info command version", u"%(cmd)s (Pology) %(version)s\n"
            u"Copyright © 2009, 2010 "
            u"Chusslove Illich (Часлав Илић) &lt;%(email)s&gt;",
            cmd="%prog",
            version=version(),
            email="*****@*****.**")

    opars = ColorOptionParser(usage=usage, description=desc, version=ver)
    opars.add_option(
        "-a",
        "--aggressive",
        action="store_true",
        dest="aggressive",
        default=False,
        help=_(
            "@info command line option description",
            "Apply every message to its paired message in the target file, "
            "irrespective of whether its non-pairing parts match too."))
    opars.add_option(
        "-d",
        "--directory",
        metavar=_("@info command line value placeholder", "DIR"),
        dest="directory",
        help=_(
            "@info command line option description",
            "Prepend this directory path to any resolved target file path."))
    opars.add_option(
        "-e",
        "--embed",
        action="store_true",
        dest="embed",
        default=False,
        help=_(
            "@info command line option description",
            "Instead of applying resolved newer version of the message, "
            "add the full embedded diff into the target file."))
    opars.add_option(
        "-i",
        "--input",
        metavar=_("@info command line value placeholder", "FILE"),
        dest="input",
        help=_(
            "@info command line option description",
            "Read the patch from the given file instead of standard input."))
    opars.add_option(
        "-n",
        "--no-merge",
        action="store_false",
        dest="do_merge",
        default=def_do_merge,
        help=_("@info command line option description",
               "Do not try to indirectly pair messages by merging catalogs."))
    opars.add_option(
        "-p",
        "--strip",
        metavar=_("@info command line value placeholder", "NUM"),
        dest="strip",
        help=_(
            "@info command line option description",
            "Strip the smallest prefix containing NUM leading slashes from "
            "each file name found in the ediff file (like in patch(1)). "
            "If not given, only the base name of each file is taken."))
    opars.add_option(
        "-u",
        "--unembed",
        action="store_true",
        dest="unembed",
        default=False,
        help=_(
            "@info command line option description",
            "Instead of applying a patch, resolve all embedded differences "
            "in given paths to newer versions of messages."))

    (op, free_args) = opars.parse_args(str_to_unicode(sys.argv[1:]))

    # Could use some speedup.
    try:
        import psyco
        psyco.full()
    except ImportError:
        pass

    if not op.unembed:
        if free_args:
            error(
                _("@info",
                  "Too many arguments in command line: %(argspec)s",
                  argspec=" ".join(free_args)))
        if op.strip and not op.strip.isdigit():
            error(
                _("@info",
                  "Option %(opt)s expects a positive integer value.",
                  opt="--strip"))
        apply_ediff(op)
    else:
        paths = []
        for path in free_args:
            if not os.path.exists(path):
                warning(
                    _("@info", "Path '%(path)s' does not exist.", path=path))
            if os.path.isdir(path):
                paths.extend(collect_catalogs(path))
            else:
                paths.append(path)
        for path in paths:
            unembed_ediff(path)
Example #10
0
    def process (self, msg, cat):

        if not msg.translated or msg.obsolete:
            return
        if msg.msgid_plural is not None:
            return

        # Parse property map entries from the message.
        psep, kvsep = None, None
        ekeys = set()
        props = {}
        for i in range(len(msg.manual_comment)):
            ind = i + 1
            manc = (msg.manual_comment[i]).strip()
            if manc.startswith(self.p.pmhead):
                # Parse and check consistency of separators.
                espec = manc[len(self.p.pmhead):].lstrip()
                lkvsep, lpsep = espec[:2]
                if lkvsep.isalnum() or lpsep.isalnum():
                    warning_on_msg(_("@info",
                                     "An alphanumeric separator is used for "
                                     "property map entry in comment "
                                     "no. %(ord)d.", ord=ind),
                                     msg, cat)
                    return
                if not psep:
                    psep, kvsep = lpsep, lkvsep
                elif (psep, kvsep) != (lpsep, lkvsep):
                    warning_on_msg(_("@info",
                                     "Inconsistent separators for "
                                     "continued property map entry in comment "
                                     "no. %(ord)d.", ord=ind),
                                     msg, cat)
                    return
                # Remove leading and trailing separators.
                respec = espec[2:]
                if respec.endswith(psep + psep):
                    respec = respec[:-2]
                elif respec.endswith(psep):
                    respec = respec[:-1]
                else:
                    warning_on_msg(_("@info",
                                     "Missing terminating separator for "
                                     "property map entry in comment "
                                     "no. %(ord)d.", ord=ind),
                                     msg, cat)
                    return
                # Parse entry keys and key-value pairs.
                for elspec in respec.split(psep):
                    if kvsep in elspec:
                        pkey, pval = elspec.split(kvsep, 1)
                        props[pkey] = pval
                    else:
                        ekey = elspec
                        if not self.p.extrakeys:
                            warning_on_msg(_("@info",
                                             "Additional entry key '%(key)s' "
                                             "is defined but not allowed for "
                                             "property map entry in comment "
                                             "no. %(ord)d.", key=ekey, ord=ind),
                                             msg, cat)
                            return
                        ekeys.add(ekey)

            elif manc.startswith(self.p.sdhead):
                sddef = manc[len(self.p.sdhead):].lstrip()
                sdkey = str(self.sdord)
                sdexpr = sdkey + ":" + sddef
                if self.p.derivs:
                    sdexpr = ">" + self.p.derivs + "\n" + sdexpr
                try:
                    self.synder.import_string(sdexpr)
                    cprops = self.synder.props(sdkey)
                except Exception, e:
                    errmsg = str_to_unicode(str(e))
                    warning_on_msg(_("@info",
                                     "Invalid derivation '%(deriv)s':\n"
                                     "%(msg)s", deriv=sddef, msg=errmsg),
                                     msg, cat)
                    return

                jumble = "".join(["".join(x) for x in cprops.items()])
                if not psep:
                    psep = self._pick_sep(jumble, u"/|¦")
                    kvsep = self._pick_sep(jumble, u"=:→")
                    if not psep or not kvsep:
                        warning_on_msg(_("@info",
                                         "No known separator are applicable "
                                         "to keys and values derived from "
                                         "'%(deriv)s'.", deriv=sddef),
                                         msg, cat)
                        return
                else:
                    if psep in jumble or kvsep in jumble:
                        warning_on_msg(_("@info",
                                         "Previously selected separators "
                                         "are not applicable to "
                                         "keys and values derived from "
                                         "'%(deriv)s'.", deriv=sddef),
                                         msg, cat)
                        return

                props.update(cprops)
Example #11
0
def main():

    locale.setlocale(locale.LC_ALL, "")

    # Get defaults for command line options from global config.
    cfgsec = pology_config.section("pomtrans")

    showservs = list()
    showservs.sort()

    # Setup options and parse the command line.
    usage = _("@info command usage",
              "%(cmd)s [OPTIONS] TRANSERV PATHS...",
              cmd="%prog")
    desc = _("@info command description",
             "Perform machine translation of PO files.")
    ver = _("@info command version", u"%(cmd)s (Pology) %(version)s\n"
            u"Copyright © 2009, 2010 "
            u"Chusslove Illich (Часлав Илић) &lt;%(email)s&gt;",
            cmd="%prog",
            version=version(),
            email="*****@*****.**")

    opars = ColorOptionParser(usage=usage, description=desc, version=ver)
    opars.add_option("-a",
                     "--accelerator",
                     dest="accel",
                     metavar=_("@info command line value placeholder", "CHAR"),
                     help=_(
                         "@info command line option description",
                         "Accelerator marker character used in messages. "
                         "Detected from catalogs if not given."))
    opars.add_option("-c",
                     "--parallel-compendium",
                     dest="parcomp",
                     metavar=_("@info command line value placeholder", "FILE"),
                     help=_(
                         "@info command line option description",
                         "Translate from translation to another language, "
                         "found in compendium file at the given path."))
    opars.add_option("-l",
                     "--list-transervs",
                     action="store_true",
                     dest="list_transervs",
                     default=False,
                     help="List available translation services.")
    opars.add_option("-m",
                     "--flag-%s" % _flag_mtrans,
                     action="store_true",
                     dest="flag_mtrans",
                     default=False,
                     help=_("@info command line option description",
                            "Add '%(flag)s' flag to translated messages.",
                            flag=_flag_mtrans))
    opars.add_option(
        "-M",
        "--translation-mode",
        dest="tmode",
        metavar=_("@info command line value placeholder", "MODE"),
        help=_(
            "@info command line option description",
            "Translation mode for the chosen translation service. "
            "Overrides the default translation mode constructed "
            "based on source and target language. "
            "Mode string format is translation service dependent."))
    opars.add_option("-n",
                     "--no-fuzzy-flag",
                     action="store_false",
                     dest="flag_fuzzy",
                     default=True,
                     help=_(
                         "@info command line option description",
                         "Do not add '%(flag)s' flag to translated messages.",
                         flag="fuzzy"))
    opars.add_option(
        "-p",
        "--parallel-catalogs",
        dest="parcats",
        metavar=_("@info command line value placeholder", "SEARCH:REPLACE"),
        help=_(
            "@info command line option description",
            "Translate from translation to another language "
            "found in parallel catalogs. "
            "For given target catalog path, the path to parallel catalog "
            "is constructed by replacing once SEARCH with REPLACE."))
    opars.add_option("-s",
                     "--source-lang",
                     dest="slang",
                     metavar=_("@info command line value placeholder", "LANG"),
                     help=_(
                         "@info command line option description",
                         "Source language code. "
                         "Detected from catalogs if not given."))
    opars.add_option("-t",
                     "--target-lang",
                     dest="tlang",
                     metavar=_("@info command line value placeholder", "LANG"),
                     help=_(
                         "@info command line option description",
                         "Target language code. "
                         "Detected from catalogs if not given."))
    opars.add_option("-T",
                     "--transerv-bin",
                     dest="transerv_bin",
                     metavar=_("@info command line value placeholder", "PATH"),
                     help=_(
                         "@info command line option description",
                         "Custom path to translation service executable "
                         "(where applicable)."))
    opars.add_option(
        "-d",
        "--data-directory",
        dest="data_directory",
        metavar=_("@info command line value placeholder", "FOLDER"),
        help=_(
            "@info command line option description",
            "Custom path to a translation data directory (where applicable)."))

    (op, free_args) = opars.parse_args(str_to_unicode(sys.argv[1:]))

    # Could use some speedup.
    try:
        import psyco
        psyco.full()
    except ImportError:
        pass

    if op.list_transervs:
        report("\n".join(sorted(_known_transervs.keys())))
        sys.exit(0)

    if len(free_args) < 1:
        error(_("@info", "Translation service not specified."))
    transervkey = free_args.pop(0)
    if transervkey not in _known_transervs:
        error(
            _("@info",
              "Translation service '%(serv)s' not known.",
              serv=transervkey))

    tsbuilder_wopts = _known_transervs[transervkey]
    tsbuilder = lambda slang, tlang: tsbuilder_wopts(slang, tlang, op)

    paths = free_args
    if not op.parcomp and not op.parcats:
        translate_direct(paths, tsbuilder, op)
    else:
        translate_parallel(paths, tsbuilder, op)