def fetch_command():
    """

    :return:
    """

    cmd = None
    if len(sys.argv) > 1:
        cmd = sys.argv[1].lower()

    if cmd in ['-h', '-help', '--help', '--h']:
        return 'help'

    if cmd is None or cmd.startswith('-'):
        system.log("""
        [ERROR]: tracksim requires a command argument that defines the
        operation to be carried out. The expected structure is:

            $ tracksim [COMMAND] [ARGUMENTS] [--OPTIONS]

        For a list of available commands run:

            $ tracksim help
        """)

        system.end(1)

    return cmd
Beispiel #2
0
def find_group_files(path: str) -> typing.List[str]:
    """
    Finds all group configuration JSON files stored in the specified path
    directory

    :param path:
        Path to the directory where the group files search should take place
    """

    paths = []

    # Prioritize group files named "group.json" over other files in the path
    items = ['group.json']
    for item in os.listdir(path):
        if item == 'group.json':
            continue
        items.append(item)

    for item in items:
        item_path = os.path.join(path, item)
        if not os.path.exists(item_path):
            continue

        if not os.path.isfile(item_path) or not item.endswith('.json'):
            continue

        try:
            with open(item_path, 'r+') as f:
                data = json.load(f)
        except json_decoder.JSONDecodeError as err:
            system.log([
                '[ERROR]: Failed to decode json file',
                [
                    'PATH: {}'.format(path),
                    'INFO: {}'.format(err.msg),
                    [
                        'LINE: {}'.format(err.lineno),
                        'CHAR: {}'.format(err.colno)
                    ]
                ]
            ])
            return system.end(1)

        if 'trials' in data:
            paths.append(item_path)

    if not paths:
        system.log('ERROR: No group trial found in path: "{}"'.format(path))
        system.end(2)

    return paths
Beispiel #3
0
def execute_command():
    """

    :return:
    """

    system.log("""
        ==============
        REMOVE RESULTS
        ==============

        This command will remove all analysis, group and trial reports stored
        located in the directory:

        {}
        """.format(paths.results()), whitespace_bottom=1)

    do_it = query.confirm(
        'Are you sure you want to continue',
        default=False
    )

    if not do_it:
        system.log('[ABORTED]: No files were deleted')
        return system.end(0)

    path = paths.results('reports')

    if os.path.exists(path):
        try:
            shutil.rmtree(path)
        except Exception:
            try:
                shutil.rmtree(path)
            except Exception:
                pass

    system.log("""
        [SUCCESS]: All results have been removed
        """, whitespace_top=1)
def load(
        configs_type: typing.Union[str, None],
        source: typing.Union[str, dict],
        inherits: dict = None,
        **kwargs
) -> dict:
    """
    Loads a JSON configuration file from the specified source path if the source
    argument is a string. Otherwise, assumes the source is already a dictionary
    object with the configuration information.

    Then any specified keyword arguments are added to the configurations,
    replacing any keys that were already defined.

    :param configs_type:
        The enumerated type of the configurations to be loaded
    :param source:
        Either a string representing an absolute path to the configs JSON file
        to be loaded, or a dictionary object of configuration values
    :param inherits:
        An optional dictionary of values that should be inherited where they
        do not exist already in the source settings
    :return: The loaded configuration dictionary object augmented by any
        keyword arguments
    """

    c = configs_type[0].lower() if configs_type else None
    if c == 't':
        configs_type = 'trial'
    elif c == 'g':
        configs_type = 'group'
    else:
        configs_type = None

    if isinstance(source, str):
        path = source

        try:
            with open(path, 'r+') as f:
                source = json.load(f)
        except FileNotFoundError:
            system.log([
                '[ERROR]: No such configuration file',
                ['PATH: {}'.format(path)]
            ])
            return system.end(1)
        except json_decoder.JSONDecodeError as err:
            system.log([
                '[ERROR]: Failed to decode configs json file',
                [
                    'PATH: {}'.format(path),
                    'INFO: {}'.format(err.msg),
                    [
                        'LINE: {}'.format(err.lineno),
                        'CHAR: {}'.format(err.colno)
                    ]
                ]
            ])
            return system.end(1)

        source['filename'] = os.path.abspath(path)
        source['path'] = os.path.dirname(source['filename'])
        source['directory'] = os.path.dirname(source['filename'])
    else:
        source = json.loads(json.dumps(source))
        source['path'] = source.get('path', os.path.abspath(os.path.curdir))
        source['directory'] = source.get(
            'directory',
            os.path.abspath(os.path.curdir)
        )

    if configs_type is None:
        configs_type = 'g' if 'trials' in source else 't'

    source['type'] = configs_type

    if inherits:
        for k, v in inherits.items():
            if configs_type == 'trial' and k in ['trials']:
                continue

            if k not in source:
                source[k] = v

    for k, v in kwargs.items():
        source[k] = v

    source['id'] = source['name'].replace(' ', '-')

    return source
def run(
        path: str,
        source_directory: str,
        directory_name: str,
        force: bool,
        **kwargs
):
    """

    :param path:
    :param source_directory:
    :param directory_name:
    :param force:
    :return:
    """

    target_path = os.path.join(os.path.abspath(path), directory_name)
    if os.path.exists(target_path):

        if not force:
            system.log("""
            [ABORTED EXPORT]
            A file or directory already exists at the specified path:

            {path}

            If you would like to replace the existing data at this path location
            either delete the existing data first, or run this command with the
            force flag.
            """.format(path=target_path))
            system.end(1)

        system.log('[REMOVING]: Existing directory {}'.format(target_path))
        try:
            shutil.rmtree(target_path)
        except OSError:
            try:
                # Give it a second
                shutil.rmtree(target_path)
            except OSError:
                system.log("""
                    [ABORTED EXPORT]
                    The existing directory could not be removed.
                    Unable to continue.
                    """)
                system.end(1)

    omit_html = kwargs.get('omit_html', False)
    omit_data = kwargs.get('omit_data', False)

    def list_ignores(src, names):
        """
        Creates a list of file names that should not be copied to the
        destination during the copytree operation.

        :param src:
            Source directory where the files originate
        :param names:
            A list of file names in the source directory to filter
        :return:
            A list of file names in the source directory that should NOT
            be copied to the destination path
        """

        ignored_names = []
        for name in names:
            if omit_html and not name.endswith('.json'):
                ignored_names.append(name)
            if omit_data and name.endswith('.json'):
                ignored_names.append(name)
        return ignored_names

    shutil.copytree(source_directory, target_path, ignore=list_ignores)

    result = create_index_file(source_directory, target_path)

    system.log("""
        [EXPORT COMPLETE]
        The export process was successful. All existing reports are now
        accessible through the index file:

         * {url}
        """.format(url=result['url']), whitespace=1)
def execute_command():
    """ Runs the configure command """

    parser = ArgumentParser()
    parser.description = cli.reformat(DESCRIPTION)

    parser.add_argument(
        'configure',
        type=str,
        help='The configure command to execute'
    )

    parser.add_argument(
        'key',
        type=str,
        nargs='?',
        default=None,
        help=cli.reformat("""
            The configuration key to be modify
            """)
    )

    parser.add_argument(
        'value',
        type=str,
        nargs='*',
        default=None,
        help=cli.reformat("""
            The value to assign to the configuration key. If omitted, the
            currently stored value for this key will be displayed.
            """)
    )

    parser.add_argument(
        '-r', '--remove',
        dest='remove',
        action='store_true',
        default=False,
        help=cli.reformat("""
            When included, this flag indicates that the specified key should
            be removed from the tracksim configs file.
            """)
    )

    parser.add_argument(
        '-l', '--list',
        dest='list',
        action='store_true',
        default=False,
        help=cli.reformat("""
            This flag is only useful when no key and no value have been
            specified. In such a case, this command will list all keys and
            values currently stored in the configuration file.
            """)
    )

    args = vars(parser.parse_args())

    configs = system.load_configs()
    if args['key'] is None:
        if args['list']:
            echo_all(configs)
        else:
            parser.print_help()
    elif len(args['value']) < 1:
        if args['remove']:
            remove_key(configs, args['key'])
        else:
            echo_key(configs, args['key'])
    else:
        set_key(configs, args['key'], args['value'])

    system.end(0)