Beispiel #1
0
 def test_guess_file_format(self):
     self.assertEqual('csv', file_utils.guess_file_format('/user/output.csv'))
     self.assertEqual('text', file_utils.guess_file_format('/user/output.text'))
     self.assertEqual('text', file_utils.guess_file_format('/user/output.txt'))
     self.assertEqual('html', file_utils.guess_file_format('/user/output.html'))
     self.assertEqual('html', file_utils.guess_file_format('/user/output.xhtml'))
     self.assertEqual(None, file_utils.guess_file_format('/user/output'))
Beispiel #2
0
def main(argv=None):
    parser = version.ArgumentParser(description=__doc__)

    parser.add_argument(
        '--help-reports',
        '--list-reports',
        nargs='?',
        default=None,
        action=ListReportsAction,
        help="Print the full list of supported reports and exit.")

    parser.add_argument(
        '--help-formats',
        '--list-formats',
        nargs='?',
        default=None,
        action=ListFormatsAction,
        help="Print the full list of supported formats and exit.")

    parser.add_argument(
        '-f',
        '--format',
        default=None,
        choices=['text', 'csv', 'html', 'htmldiv', 'xls', 'ofx', 'beancount'],
        help="Output format.")

    parser.add_argument(
        '-o',
        '--output',
        action='store',
        help=("Output filename. If not specified, the output goes "
              "to stdout. The filename is inspected to select a "
              "sensible default format, if one is not requested."))

    parser.add_argument('-t',
                        '--timings',
                        '--verbose',
                        action='store_true',
                        help='Print timings.')

    parser.add_argument('-q',
                        '--no-errors',
                        action='store_true',
                        help='Do not report errors.')

    parser.add_argument('filename',
                        metavar='FILENAME.beancount',
                        help='The Beancount input filename to load.')

    subparsers = parser.add_subparsers(
        title='report', help='Name/specification of the desired report.')

    for report_class in get_all_reports():
        name, aliases = report_class.names[0], report_class.names[1:]

        oss = io.StringIO()
        oss.write('  {} (aliases: {}; formats: {})'.format(
            report_class.__doc__, ','.join(report_class.names),
            ','.join(report_class.get_supported_formats())))

        report_parser = subparsers.add_parser(name,
                                              aliases=aliases,
                                              description=oss.getvalue())
        report_parser.set_defaults(report_class=report_class)
        report_class.add_args(report_parser)

        # Each subparser must gather the filter arguments. This is unfortunate,
        # but it works.
        report_parser.add_argument(
            'filters',
            nargs='*',
            help='Filter expression(s) to select the subset of transactions.')

    args = parser.parse_args(args=argv)

    # Warn on filters--not supported at this time.
    if hasattr(args, 'filters') and args.filters:
        parser.error(
            ("Filters are not supported yet. Extra args: {}. "
             "See bean-query if you need filtering now.").format(args.filters))

    # Handle special commands.
    if args.help_reports:
        print(get_list_report_string())
        return

    is_check = False
    if hasattr(args, 'report_class'):
        # Open output file and guess file format.
        outfile = open(args.output, 'w') if args.output else sys.stdout
        args.format = args.format or file_utils.guess_file_format(args.output)

        # Create the requested report and parse its arguments.
        chosen_report = args.report_class(args, parser)
        if chosen_report is None:
            parser.error("Unknown report")
        is_check = isinstance(chosen_report, misc_reports.ErrorReport)

        # Verify early that the format is supported, in order to avoid parsing the
        # input file if we need to bail out.
        supported_formats = chosen_report.get_supported_formats()
        if args.format and args.format not in supported_formats:
            parser.error(
                "Unsupported format '{}' for {} (available: {})".format(
                    args.format, chosen_report.names[0],
                    ','.join(supported_formats)))

    # Force hardcore validations, just for check.
    extra_validations = (validation.HARDCORE_VALIDATIONS if is_check else None)

    logging.basicConfig(
        level=logging.INFO if args.timings else logging.WARNING,
        format='%(levelname)-8s: %(message)s')

    # Parse the input file.
    errors_file = None if args.no_errors else sys.stderr
    with misc_utils.log_time('beancount.loader (total)', logging.info):
        entries, errors, options_map = loader.load_file(
            args.filename,
            log_timings=logging.info,
            log_errors=errors_file,
            extra_validations=extra_validations)

    if hasattr(args, 'report_class'):
        # Create holdings list.
        with misc_utils.log_time('report.render', logging.info):
            try:
                chosen_report.render(entries, errors, options_map, args.format,
                                     outfile)
            except base.ReportError as exc:
                sys.stderr.write("Error: {}\n".format(exc))
                return 1
    else:
        print(get_list_report_string())

    return (1 if errors else 0)