Browse Source

New binary patatools

pull/189/head
Louis 8 years ago
parent
commit
4571bef5e5
  1. 8
      patacrep/build.py
  2. 2
      patacrep/errors.py
  3. 54
      patacrep/songbook/__init__.py
  4. 55
      patacrep/songbook/__main__.py
  5. 0
      patacrep/tools/__init__.py
  6. 116
      patacrep/tools/__main__.py
  7. 0
      patacrep/tools/cache/__init__.py
  8. 73
      patacrep/tools/cache/__main__.py
  9. 6
      patatools
  10. 1
      setup.py
  11. 6
      songbook

8
patacrep/build.py

@ -172,11 +172,11 @@ class SongbookBuilder:
# are function; values are return values of functions.
_called_functions = {}
def __init__(self, raw_songbook, basename):
# Representation of the .sb songbook configuration file.
self.songbook = Songbook(raw_songbook, basename)
def __init__(self, raw_songbook):
# Basename of the songbook to be built.
self.basename = basename
self.basename = raw_songbook['_basename']
# Representation of the .sb songbook configuration file.
self.songbook = Songbook(raw_songbook, self.basename)
def _run_once(self, function, *args, **kwargs):
"""Run function if it has not been run yet.

2
patacrep/errors.py

@ -7,7 +7,7 @@ class SongbookError(Exception):
"""
pass
class SBFileError(SongbookError):
class YAMLError(SongbookError):
"""Error during songbook file decoding"""
def __init__(self, message=None):

54
patacrep/songbook/__init__.py

@ -0,0 +1,54 @@
"""Raw songbook utilities"""
import logging
import os
import sys
import yaml
from patacrep import encoding
import patacrep
LOGGER = logging.getLogger()
def open_songbook(filename):
"""Open songbook, and return a raw songbook object.
:param str filename: Filename of the yaml songbook.
:rvalue: dict
:return: Songbook, as a dictionary.
"""
if os.path.exists(filename + ".sb") and not os.path.exists(filename):
filename += ".sb"
try:
with patacrep.encoding.open_read(filename) as songbook_file:
songbook = yaml.load(songbook_file)
if 'encoding' in songbook:
with encoding.open_read(
filename,
encoding=songbook['encoding']
) as songbook_file:
songbook = yaml.load(songbook_file)
except Exception as error: # pylint: disable=broad-except
raise patacrep.errors.YAMLError(str(error))
songbook['_basename'] = os.path.basename(filename)[:-3]
# Gathering datadirs
datadirs = []
if 'datadir' in songbook:
if isinstance(songbook['datadir'], str):
songbook['datadir'] = [songbook['datadir']]
datadirs += [
os.path.join(
os.path.dirname(os.path.abspath(filename)),
path
)
for path in songbook['datadir']
]
# Default value
datadirs.append(os.path.dirname(os.path.abspath(filename)))
songbook['datadir'] = datadirs
return songbook

55
patacrep/songbook/__main__.py

@ -3,20 +3,18 @@
import argparse
import locale
import logging
import os.path
import textwrap
import sys
import yaml
import textwrap
from patacrep.build import SongbookBuilder, DEFAULT_STEPS
from patacrep.utils import yesno
from patacrep import __version__
from patacrep import errors
from patacrep.build import SongbookBuilder, DEFAULT_STEPS
from patacrep.utils import yesno
import patacrep.encoding
# Logging configuration
logging.basicConfig(level=logging.INFO)
LOGGER = logging.getLogger()
LOGGER = logging.getLogger("patatools")
# pylint: disable=too-few-public-methods
class ParseStepsAction(argparse.Action):
@ -127,49 +125,16 @@ def main():
options = argument_parser(sys.argv[1:])
songbook_path = options.book[-1]
if os.path.exists(songbook_path + ".sb") and not os.path.exists(songbook_path):
songbook_path += ".sb"
basename = os.path.basename(songbook_path)[:-3]
try:
with patacrep.encoding.open_read(songbook_path) as songbook_file:
songbook = yaml.load(songbook_file)
if 'encoding' in songbook:
with patacrep.encoding.open_read(
songbook_path,
encoding=songbook['encoding']
) as songbook_file:
songbook = yaml.load(songbook_file)
except Exception as error: # pylint: disable=broad-except
LOGGER.error(error)
LOGGER.error("Error while loading file '{}'.".format(songbook_path))
sys.exit(1)
songbook = patacrep.songbook.open_songbook(options.book[-1])
# Gathering datadirs
datadirs = []
if options.datadir:
# Command line options
datadirs += [item[0] for item in options.datadir]
if 'datadir' in songbook:
if isinstance(songbook['datadir'], str):
songbook['datadir'] = [songbook['datadir']]
datadirs += [
os.path.join(
os.path.dirname(os.path.abspath(songbook_path)),
path
)
for path in songbook['datadir']
]
# Default value
datadirs.append(os.path.dirname(os.path.abspath(songbook_path)))
songbook['datadir'] = datadirs
songbook['_cache'] = options.cache[0]
if options.datadir:
for datadir in reversed(options.datadir):
songbook['datadir'].insert(0, datadir)
songbook['_cache'] = options.cache[0]
try:
sb_builder = SongbookBuilder(songbook, basename)
sb_builder = SongbookBuilder(songbook)
sb_builder.unsafe = True
sb_builder.build_steps(options.steps)

0
patacrep/tools/__init__.py

116
patacrep/tools/__main__.py

@ -0,0 +1,116 @@
#!/bin/env python3
"""Command line client to :mod:`tools`"""
import argparse
import logging
import operator
import os
import pkgutil
import re
import sys
import patacrep
# Logging configuration
logging.basicConfig(level=logging.INFO)
LOGGER = logging.getLogger()
def _execlp(program, args):
"""Call :func:`os.execlp`, adding `program` as the first argument to itself."""
return os.execlp(program, program, *args)
def _iter_subcommands():
"""Iterate over subcommands.
The objects returned are tuples of:
- the name of the command;
- its description;
- the function to call to execute the subcommand.
"""
subcommands = []
# Get python subcommands
path = [os.path.join(item, "patacrep", "tools") for item in sys.path]
prefix = "patacrep.tools."
module_re = re.compile(r'{}(?P<subcommand>[^\.]*)\.__main__'.format(prefix))
for module_loader, name, _ in pkgutil.walk_packages(path, prefix):
match = module_re.match(name)
if match:
module = module_loader.find_module(match.string).load_module()
if hasattr(module, "SUBCOMMAND_DESCRIPTION"):
subcommands.append(match.groupdict()['subcommand'])
yield (
match.groupdict()['subcommand'],
getattr(module, "SUBCOMMAND_DESCRIPTION"),
module.main,
)
class ArgumentParser(argparse.ArgumentParser):
"""Proxy class to circumvent an :mod:`argparse` bug.
Contrarily to what documented, the `argparse.REMAINDER
<https://docs.python.org/3/library/argparse.html#nargs>`_ `nargs` setting
does not include the remainder arguments if the first one begins with `-`.
This bug is reperted as `17050 <https://bugs.python.org/issue17050>`_. This
class can be deleted once this bug has been fixed.
"""
def parse_args(self, args=None, namespace=None):
if args is None:
args = sys.argv[1:]
subcommands = [command[0] for command in set(_iter_subcommands())]
if len(args) > 0:
if args[0] in subcommands:
args = [args[0], "--"] + args[1:]
value = super().parse_args(args, namespace)
if hasattr(value, 'remainder'):
value.remainder = value.remainder[1:]
return value
def commandline_parser():
"""Return a command line parser."""
parser = ArgumentParser(
prog="patatools",
description=(
"Miscellaneous tools for patacrep."
),
formatter_class=argparse.RawTextHelpFormatter,
)
parser.add_argument(
'--version',
help='Show version',
action='version',
version='%(prog)s ' + patacrep.__version__
)
subparsers = parser.add_subparsers(
title="Subcommands",
description="List of available subcommands.",
)
for command, message, function in sorted(_iter_subcommands(), key=operator.itemgetter(0)):
sub1 = subparsers.add_parser(command, help=message, add_help=False)
sub1.add_argument('remainder', nargs=argparse.REMAINDER)
sub1.set_defaults(function=function)
return parser
def main():
"""Main function"""
parser = commandline_parser()
args = parser.parse_args()
if hasattr(args, "function"):
args.function(args.remainder)
else:
parser.error("Missing command.")
if __name__ == "__main__":
main()

0
patacrep/tools/cache/__init__.py

73
patacrep/tools/cache/__main__.py

@ -0,0 +1,73 @@
"""`patatools cache` command: cache manipulation."""
import argparse
import logging
import os
import shutil
import sys
import textwrap
from patacrep import errors
from patacrep import songbook
LOGGER = logging.getLogger("patatools.cache")
SUBCOMMAND_DESCRIPTION = "Perform operations on cache."
def filename(name):
"""Check that argument is an existing, readable file name.
Return the argument for convenience.
"""
if os.path.isfile(name) and os.access(name, os.R_OK):
return name
raise argparse.ArgumentTypeError("Cannot read file '{}'.".format(name))
def commandline_parser():
"""Return a command line parser."""
parser = argparse.ArgumentParser(
prog="patatools cache",
description=SUBCOMMAND_DESCRIPTION,
formatter_class=argparse.RawTextHelpFormatter,
)
subparsers = parser.add_subparsers(
description="",
dest="command",
)
subparsers.required = True
clear = subparsers.add_parser(
"clear",
description="Delete cache.",
help="Delete cache.",
)
clear.add_argument(
'songbook',
metavar="SONGBOOK",
help=textwrap.dedent("""Songbook file to used to look for cache path."""),
type=filename,
)
clear.set_defaults(command=do_clear)
return parser
def do_clear(namespace):
"""Execute the `patatools cache clear` command."""
for datadir in songbook.open_songbook(namespace.songbook)['datadir']:
cachedir = os.path.join(datadir, ".cache")
LOGGER.info("Deleting cache directory '{}'...".format(cachedir))
if os.path.isdir(cachedir):
shutil.rmtree(cachedir)
def main(args=None):
"""Main function: run from command line."""
options = commandline_parser().parse_args(args)
try:
options.command(options)
except errors.SongbookError as error:
LOGGER.error(str(error))
sys.exit(1)
if __name__ == "__main__":
main()

6
patatools

@ -0,0 +1,6 @@
#! /bin/sh
# Do not edit this file. This file is just a helper file for development test.
# It is not part of the distributed software.
python -m patacrep.tools $@

1
setup.py

@ -39,6 +39,7 @@ setup(
entry_points={
'console_scripts': [
"songbook = patacrep.songbook.__main__:main",
"patatools = patacrep.tools.__main__:main",
],
},
classifiers=[

6
songbook

@ -3,8 +3,4 @@
# Do not edit this file. This file is just a helper file for development test.
# It is not part of the distributed software.
if [ $1 = "purgecache" ]; then
find . -name ".cache" -type d -print -exec rm -r {} +
else
python -m patacrep.songbook $*
fi
python -m patacrep.songbook $@

Loading…
Cancel
Save