diff --git a/dcm2bids/cli/dcm2bids_scaffold.py b/dcm2bids/cli/dcm2bids_scaffold.py index 58824e4e..4c5609c3 100644 --- a/dcm2bids/cli/dcm2bids_scaffold.py +++ b/dcm2bids/cli/dcm2bids_scaffold.py @@ -13,12 +13,13 @@ import datetime import logging import os +import sys from os.path import join as opj - from dcm2bids.utils.io import write_txt from dcm2bids.utils.args import add_overwrite_arg, assert_dirs_empty -from dcm2bids.utils.utils import DEFAULT, run_shell_command +from dcm2bids.utils.utils import DEFAULT, run_shell_command, TreePrinter from dcm2bids.utils.scaffold import bids_starter_kit +from dcm2bids.utils.logger import setup_logging def _build_arg_parser(): @@ -38,18 +39,26 @@ def main(): parser = _build_arg_parser() args = parser.parse_args() + setup_logging("info") + logger = logging.getLogger(__name__) + assert_dirs_empty(parser, args, args.output_dir) for _ in ["code", "derivatives", "sourcedata"]: os.makedirs(opj(args.output_dir, _), exist_ok=True) - logging.info("The files used to create your BIDS directory comes from" - "https://github.com/bids-standard/bids-starter-kit") + logger.info("Currently running the following command: \n" + + " ".join(sys.argv) + "\n") + logger.info("The files used to create your BIDS directory were taken from " + "https://github.com/bids-standard/bids-starter-kit. \n") + # CHANGES write_txt(opj(args.output_dir, "CHANGES"), bids_starter_kit.CHANGES.replace('DATE', - datetime.date.today().strftime("%Y-%m-%d"))) - + datetime.date.today().strftime( + "%Y-%m-%d") + ) + ) # dataset_description write_txt(opj(args.output_dir, "dataset_description"), bids_starter_kit.dataset_description.replace("BIDS_VERSION", @@ -63,14 +72,23 @@ def main(): write_txt(opj(args.output_dir, "participants.tsv"), bids_starter_kit.participants_tsv) + # .bidsignore + write_txt(opj(args.output_dir, ".bidsignore"), + "tmp_dcm2bids") + # README try: run_shell_command(['wget', '-q', '-O', opj(args.output_dir, "README"), - 'https://github.com/bids-standard/bids-starter-kit/blob/main/templates/README.MD']) - except: + 'https://raw.githubusercontent.com/bids-standard/bids-starter-kit/main/templates/README.MD'], + log=False) + except Exception: write_txt(opj(args.output_dir, "README"), bids_starter_kit.README) + # output tree representation of where the scaffold was built. + + TreePrinter(args.output_dir).print_tree() + if __name__ == "__main__": main() diff --git a/dcm2bids/utils/io.py b/dcm2bids/utils/io.py index 8e694955..9e180761 100644 --- a/dcm2bids/utils/io.py +++ b/dcm2bids/utils/io.py @@ -1,14 +1,9 @@ # -*- coding: utf-8 -*- -import inspect import json -import os -import os.path as opj from pathlib import Path from collections import OrderedDict -import dcm2bids - def load_json(filename): """ Load a JSON file @@ -30,7 +25,7 @@ def save_json(filename, data): def write_txt(filename, lines): - with open(filename, "a+") as f: + with open(filename, "w") as f: f.write(f"{lines}\n") diff --git a/dcm2bids/utils/utils.py b/dcm2bids/utils/utils.py index b4aed687..815ef8b4 100644 --- a/dcm2bids/utils/utils.py +++ b/dcm2bids/utils/utils.py @@ -112,13 +112,14 @@ def splitext_(path, extensions=None): return os.path.splitext(path) -def run_shell_command(commandLine): +def run_shell_command(commandLine, log=True): """ Wrapper of subprocess.check_output Returns: Run command with arguments and return its output """ - logger = logging.getLogger(__name__) - logger.info("Running %s", commandLine) + if log: + logger = logging.getLogger(__name__) + logger.info("Running: %s", " ".join(commandLine)) return check_output(commandLine) @@ -131,3 +132,63 @@ def convert_dir(dir): str: direction - bids format """ return DEFAULT.entity_dir[dir] + + +class TreePrinter: + """ + Generates and prints a tree representation of a given a directory. + """ + + BRANCH = "│" + LAST = "└──" + JUNCTION = "├──" + BRANCH_PREFIX = "│ " + SPACE = " " + + def __init__(self, root_dir): + self.root_dir = Path(root_dir) + + def print_tree(self): + """ + Prints the tree representation of the root directory and + its subdirectories and files. + """ + tree = self._generate_tree(self.root_dir) + logger = logging.getLogger(__name__) + logger.info(f"Tree representation of {self.root_dir}{os.sep}") + logger.info(f"{self.root_dir}{os.sep}") + for item in tree: + logger.info(item) + + def _generate_tree(self, directory, prefix=""): + """ + Generates the tree representation of the recursively. + + Parameters: + - directory: Path + The directory for which a tree representation is needed. + - prefix: str + The prefix to be added to each entry in the tree. + + Returns a list of strings representing the tree. + """ + tree = [] + entries = sorted(directory.iterdir(), key=lambda path: str(path).lower()) + entries = sorted(entries, key=lambda entry: entry.is_file()) + entries_count = len(entries) + + for index, entry in enumerate(entries): + connector = self.LAST if index == entries_count - 1 else self.JUNCTION + if entry.is_dir(): + sub_tree = self._generate_tree( + entry, + prefix=prefix + + ( + self.BRANCH_PREFIX if index != entries_count - 1 else self.SPACE + ), + ) + tree.append(f"{prefix}{connector} {entry.name}{os.sep}") + tree.extend(sub_tree) + else: + tree.append(f"{prefix}{connector} {entry.name}") + return tree