0

At work we sometimes need to set up project folders with many subfolders, we try to keep them all consistent and so I'm trying to automate it. I want to be able to specify a folder structure and how many instances I want, and then see a preview of the finished file structure. Right now I can create a folder class and put other folder classes into it as subfolders:

class Folder:
     def __init__(self, name, level, subfolders):
          self.name = name
          self.level = level # not sure I actually need this, was trying to keep track of how deep the folder is
          self.subfolders = subfolders # this is just other class instances

Now for example, lets say I had a folder called "New Project", it's subfolders / classes were "CAD", "Admin", and "Client Data", and then "CAD" had a subfolder / class called "Old". I would want my text preview in the GUI to look like this:

My Project
    CAD
        Old
    Admin
    Client Data

Where I'm stuck is I am having a hard time wrapping my head around what the loop needs to look like to go through all the class instances and get the structure to preview and then build correctly. I've tried a couple while loops but they keep becoming super complex with counters and lists to keep track of where I am and it just gets unmanageable, has anybody got any ideas or pointers for a scenario like this?

3800Camaro
  • 11
  • 2

1 Answers1

0

Some recursion magic with pathlib.Path objects. This is assuming you don't care about files but it would be quite easy to add files too and print them with different colors or something.

Be careful when running on some big directories (example /home/) as it will take loooong time.

from pathlib import Path
from typing import List, Union

line_tab = "    "
BOLD = '\033[1m'
END = '\033[0m'

class Directory:
    def __init__(self, path: Union[str, Path], depth: int=0, is_root: bool=True):
        self.subfolders: List["Directory"] = []
        self.depth: int = depth
        self.is_root: bool = is_root
        self.path: Path = Path(path)
        self._get_subfolders()

    def __repr__(self):
        return f"<Directory object: {self.path.absolute()}>"

    def __str__(self):
        return f"{BOLD}{self.path.name}{END}" if self.is_root else f"{line_tab*self.depth}{self.path.name}"

    def _get_subfolders(self):
        for path in self.path.iterdir():
            if path.is_dir():
                self.subfolders.append(Directory(path, depth=self.depth+1, is_root=False))

    def print_dir_structure(self):
        print(str(self))
        for subfolder in self.subfolders:
           subfolder.print_dir_structure()

test = Directory("/home/user/somedir")
test.print_dir_structure()

# You can also access subfolders like that:
test.subfolders[0].subfolders[0].subfolders[1]

# And do whatever Path object allows:
# ex. Rename subfolder at index 0 to 'foobar'
test.subfolders[0].path.rename('foobar')

pathlib is my favorite standard lib, it's really powerful: https://docs.python.org/3/library/pathlib.html

enter image description here

Adam
  • 459
  • 2
  • 17