Example #1
0
def make_dir(inpath, tmpldict, outpath=None, pathsubs=None):
    pathsubs = pathsubs or []
    inpath = op.abspath(inpath)
    bpath = op.basename(inpath)
    if not outpath:
        outpath = os.getcwd()
    dname = render_str(bpath, tmpldict)
    if not dname:
        return False
    mpath = op.abspath(op.join(outpath, dname))
    if not mpath:
        return False
    for sub in pathsubs:
        mpath = mpath.replace(*sub)
    if inpath == mpath:
        qprompt.fatal("Output cannot overwrite input template!")
    mpath = render_str(mpath, tmpldict)
    qprompt.status("Making dir `%s`..." % (mpath), fsys.makedirs, [mpath])

    # Iterate over files and directories IN PARENT ONLY.
    for r, ds, fs in os.walk(inpath):
        for f in fs:
            ipath = op.join(r, f)
            fname = render_str(f, tmpldict)
            opath = op.join(mpath, fname)
            if not make_file(ipath, tmpldict, opath):
                return False
        for d in ds:
            ipath = op.join(r, d)
            if not make_dir(ipath, tmpldict, mpath, pathsubs=pathsubs):
                return False
        break  # Prevents from walking beyond parent.
    return True
Example #2
0
def make_file(inpath, tmpldict, outpath=None):
    inpath = op.abspath(inpath)
    if outpath:
        outpath = render_str(outpath, tmpldict)
        if op.isdir(outpath):
            outpath = op.join(outpath, op.basename(inpath))
            outpath = render_str(outpath, tmpldict)
    if is_binary(inpath):
        qprompt.status("Copying `%s`..." % (outpath), fsys.copy,
                       [inpath, outpath])
        return
    text = render_file(inpath, tmpldict)
    if text == None:
        return False

    # Handle rendered output.
    if outpath:
        outpath = op.abspath(outpath)
        if inpath == outpath:
            qprompt.fatal("Output cannot overwrite input template!")
        fsys.makedirs(op.dirname(outpath))
        with io.open(outpath, "w", encoding="utf-8") as f:
            qprompt.status("Writing `%s`..." % (outpath), f.write, [text])
    else:
        qprompt.echo(text)
    return True
Example #3
0
def render_file(tmplpath, tmpldict, bail_miss=False):
    """Renders the template file and the given path using the given template
    variable dictionary. Returns the rendered text as a string."""
    tmplpath = op.abspath(tmplpath)
    env = Environment(undefined=SkipUndefined,
                      extensions=['jinja2_time.TimeExtension'])
    env.trim_blocks = True
    env.lstrip_blocks = True
    env.keep_trailing_newline = True
    for encoding in ["utf-8", "mbcs"]:
        try:
            env.loader = FileSystemLoader(op.dirname(tmplpath),
                                          encoding=encoding)
            tmpl = env.get_template(op.basename(tmplpath))
            break
        except UnicodeDecodeError:
            qprompt.warn("Issue while decoding template with `%s`!" % encoding)
    else:
        qprompt.fatal("Unknown issue while loading template!")
    with io.open(tmplpath) as fo:
        tmplstr = fo.read()
    miss = check_template(tmplstr, tmpldict)
    if miss:
        qprompt.warn("Template vars `%s` in `%s` were not supplied values!" %
                     ("/".join(miss), op.basename(tmplpath)))
    return tmpl.render(**tmpldict)
Example #4
0
def scan(scandir, picdirname, overwrite, shrink):
    """Scan scandir and all subdirectories for pics. Note text will be
    extracted and a notes file will be created under scandir."""
    dirpath = auxly.filesys.Path(scandir)
    if not dirpath.isdir():
        qprompt.fatal("Given path must be existing directory!")
    if picdirname != dirpath.name:
        if not qprompt.ask_yesno("Directory not named `pics`, continue?"):
            sys.exit()
    create_picnotes(dirpath, confirm=not overwrite, shrink=shrink)
Example #5
0
def get_tmpldict(args):
    # Setup custom YAML tags.
    yaml.add_constructor(u'!file', ctor_file)
    yaml.add_constructor(u'!cmd', ctor_cmd)
    yaml.add_constructor(u'!yaml', ctor_yaml)
    yaml.add_constructor(u'!opt', ctor_opt)
    yaml.add_constructor(u'!ask', ctor_ask)
    yaml.add_constructor(u'!py', ctor_py)

    # Prepare template dictionary.
    tmpldict = {}
    dfltfile = args['--defaults']
    if dfltfile:
        global _DFLTFILE
        _DFLTFILE = op.abspath(dfltfile)
        data = fsys.File(dfltfile).read()
        tmpldict = yaml.load(data)
    tmpldict = update(tmpldict,
                      {k: v
                       for k, v in zip(args['--string'], args['VAL'])})
    tmpldict = update(
        tmpldict, {
            k: fsys.File(v).read().strip()
            for k, v in zip(args['--file'], args['PATH'])
        })

    # Handle nested dictionaries.
    topop = []
    tmplnest = {}
    global KEYSEP
    KEYSEP = args['--keysep']
    if type(tmpldict) != dict:
        qprompt.fatal("Template dictionary is not correct type (%s)!" %
                      (type(tmpldict)))
    for k, v in tmpldict.items():
        if k.find(KEYSEP) > -1:
            level = tmplnest
            ks = k.split(KEYSEP)
            for ln, sk in enumerate(ks):
                level[sk] = level.get(sk, {})
                if len(ks) - 1 == ln:
                    level[sk] = v
                else:
                    level = level[sk]
            topop.append(k)
    for k in topop:
        tmpldict.pop(k)
    tmpldict = update(tmpldict, tmplnest)
    return tmpldict
Example #6
0
def parse(args):
    """Parses the given arguments into a template dictionary."""
    if args.get('INPATH'):
        args['--defaults'] = args['INPATH']
        if not op.isfile(args['--defaults']):
            qprompt.fatal("Given path could not be found: `%s`" % (args['--defaults']))
    tmpldict = get_tmpldict(args)
    utildict = get_defopts(tmpldict)
    utildict.update(get_cliopts(args))
    if args.get('--defaults') and not utildict.get('command'):
        utildict['command'] = "run"
    for key in ["inpath", "outpath"]:
        if key not in utildict.keys():
            utildict[key] = []
        elif type(utildict[key]) != list:
            utildict[key] = _tolist_no_none(utildict[key])
    while len(utildict['outpath']) < len(utildict['inpath']):
        utildict['outpath'].append(None)
    return utildict, tmpldict
Example #7
0
def get_tmpldict(args):
    # Setup custom YAML tags.
    yaml.add_constructor(u'!file', ctor_file)
    yaml.add_constructor(u'!cmd', ctor_cmd)
    yaml.add_constructor(u'!yaml', ctor_yaml)
    yaml.add_constructor(u'!opt', ctor_opt)
    yaml.add_constructor(u'!ask', ctor_ask)
    yaml.add_constructor(u'!py', ctor_py)

    # Prepare template dictionary.
    tmpldict = {}
    dfltfile = args['--defaults']
    if dfltfile:
        global _DFLTFILE
        _DFLTFILE = op.abspath(dfltfile)
        data = fsys.File(dfltfile).read()
        tmpldict = yaml.load(data)
    tmpldict = update(tmpldict, {k:v for k,v in zip(args['--string'], args['VAL'])})
    tmpldict = update(tmpldict, {k:fsys.File(v).read().strip() for k,v in zip(args['--file'], args['PATH'])})

    # Handle nested dictionaries.
    topop = []
    tmplnest = {}
    global KEYSEP
    KEYSEP = args['--keysep']
    if type(tmpldict) != dict:
        qprompt.fatal("Template dictionary is not correct type (%s)!" % (type(tmpldict)))
    for k,v in tmpldict.items():
        if k.find(KEYSEP) > -1:
            level = tmplnest
            ks = k.split(KEYSEP)
            for ln,sk in enumerate(ks):
                level[sk] = level.get(sk, {})
                if len(ks)-1 == ln:
                    level[sk] = v
                else:
                    level = level[sk]
            topop.append(k)
    for k in topop:
        tmpldict.pop(k)
    tmpldict = update(tmpldict, tmplnest)
    return tmpldict
Example #8
0
def parse(args):
    """Parses the given arguments into a template dictionary."""
    if args.get('INPATH'):
        args['--defaults'] = args['INPATH']
        if not op.isfile(args['--defaults']):
            qprompt.fatal("Given path could not be found: `%s`" %
                          (args['--defaults']))
    tmpldict = get_tmpldict(args)
    utildict = get_defopts(tmpldict)
    utildict.update(get_cliopts(args))
    if args.get('--defaults') and not utildict.get('command'):
        utildict['command'] = "run"
    for key in ["inpath", "outpath"]:
        if key not in utildict.keys():
            utildict[key] = []
        elif type(utildict[key]) != list:
            utildict[key] = _tolist_no_none(utildict[key])
    while len(utildict['outpath']) < len(utildict['inpath']):
        utildict['outpath'].append(None)
    return utildict, tmpldict
Example #9
0
def walk(startdir, picdirname):
    """Walk all directories under startdir and scan when directory name matches
    picdirname. Existing notes are overwritten."""
    if not op.isdir(startdir):
        qprompt.fatal("Given path must be existing directory!")

    total_count = {'reused': 0, 'scanned': 0}
    for d in auxly.filesys.walkdirs(startdir, "pics"):
        if op.basename(d) != picdirname:
            continue
        qprompt.hrule()
        qprompt.alert(f"Walking through `{d}`...")
        dirpath = auxly.filesys.Path(d)
        new_count = create_picnotes(dirpath, False)
        if new_count:
            total_count['reused'] += new_count['reused']
            total_count['scanned'] += new_count['scanned']
    qprompt.alert(
        f"Walk complete, scanned={total_count['scanned']} reused={total_count['reused']}"
    )
    sys.exit()
Example #10
0
def main():
    """This function implements the main logic."""
    if len(sys.argv) > 1 and op.isfile(sys.argv[1]):
        args = {}
        args['--defaults'] = sys.argv[1]
        args['--file'] = []
        args['--keysep'] = "::"
        args['--string'] = []
        args['PATH'] = []
        args['VAL'] = []
        args['runargs'] = sys.argv[2:] or ""
    else:
        args = docopt(__doc__, version="poppage-%s" % (__version__))
    utildict, tmpldict = utilconf.parse(args)

    # Check required conditions.
    if not utildict.get('inpath'):
        qprompt.fatal("Must supply INPATH!")

    # Handle command.
    if utildict['command'] == "check":
        check(utildict['inpath'][0], echo=True)
    elif utildict['command'] == "make":
        for inpath, outpath in zip(utildict['inpath'], utildict['outpath']):
            make(inpath, tmpldict, outpath=outpath)
    elif utildict['command'] == "run":
        run(utildict['inpath'][0],
            tmpldict,
            outpath=utildict['outpath'][0],
            execute=utildict.get('execute'),
            runargs=utildict.get('runargs'))
    elif utildict['command'] == "debug":
        qprompt.echo("Utility Dictionary:")
        pprint(utildict)
        qprompt.echo("Template Dictionary:")
        pprint(tmpldict)