Search code examples
pythondictionarydirectorysubdirectoryftplib

How to create a Python nested dictionary based on a FTP tree of folders


I'm trying to create a dictionary based on a tree of folders located on a FTP server (see image below):

enter image description here

The result I'm looking for is : A primary dictionnary that have secondary dictionnaries (as keys) with some lists (as values).

rootpath = r'C:\Users\_M92\Desktop\myFolder'

dict = {'subfolder1': ['sub-subfolder1', 'sub-subfolder2', 'sub-subfolder3']}, \
       {'subfolder2': ['sub-subfolder1']}, \
       {'subfolder3': ['sub-subfolder1', 'sub-subfolder2']}

I have to precise that the sub-subfolders can eventually have some folders within.
Do you have any suggestions how to reach this kind of operations, please ?

EDIT :

With @Elmatador DeAngel's suggestion/answer here, we get close enough :

dict = {'subfolder1': {'sub-subfolder1': 'Empty', 'sub-subfolder2': 'Empty', 'sub-subfolder3': 'Empty'},\
        'subfolder2': {'sub-subfolder1': 'Empty'},  \
        'subfolder3': {'sub-subfolder1': 'Empty', 'sub-subfolder2': 'Empty'}}

Solution

  • I am aware that you're looking for a code using FTPlib. I don't have an FTP server to show tje example, but I can be of some help.

    You could use the concept of a recursive function; a function that calls itself.

    It's simple, scan a folder using os.listdir() Then check if it's a folder, and if it is, then recall the same function to do the same operation and add it to a dictionary.

    Here's a simple example(without an FTP):

    
    import os
    
    
    
    dictionary = {}
    
    path = "C:/Users/User/Desktop/SomeFile"
    
    def is_dictionary(path): 
    
           try:
                os.chdir(path)
                return True
                
           except:
                return False
           
    def RecursiveFunc(data, path): 
          
          f = os.listdir(path)
          if f != {}:
           for i in f: 
             if is_dictionary(f"{path}/{i}"):
                    if os.listdir(f"{path}/{i}") != []:
                       data[i] = {}
                       RecursiveFunc(data[i], f"{path}/{i}")
                      
                    else:
                       data[i] = 'Empty'
         
                 
                        
    RecursiveFunc(dictionary, path)
    
    print(str(dictionary))
    

    You just gotta do the same with the FTPlib library. You can use FTP.cwd() to move from a dictionary to another, and FTP.nlst() to list all the files in said dictionary, and then call a recursive function to do the same job to the file inside the file.

    Output:

    {'subfolder1': {'sub-subfolder1': 'Empty', 'sub-subfolder2': 'Empty', 'sub-subfolder3': 'Empty'},
    {'subfolder2': {'sub-subfolder1': 'Empty'}, 
    {'subfolder3': {'sub-subfolder1': 'Empty', 'sub-subfolder2': 'Empty'}}
    

    EDIT

    I wrote a code that almost perfectly resembles the output you desire.

    Here it is:

    
    import os
    
    dictionary = []
    
    path = "C:/Users/User/Desktop/MyFolder"
    
    def is_dic(path): 
    
           try:
                os.chdir(path)
                return True
                
           except:
                return False
           
    def RecursiveFunc(data, path): 
          
          f = os.listdir(path)
          index = 0
          for i in f:
              
               if is_dic(f"{path}/{i}"):
                   if os.listdir(f"{path}/{i}") == []: 
                              data.append(str(i))
                              
                              
                   else:
                   
                           data.append({i: []})
                           RecursiveFunc(data[index][i], f"{path}/{i}" )
                   
                   index += 1               
         
                 
                              
                              
    
                          
    RecursiveFunc(dictionary, path)
    
    
    print(str(dictionary))
    
    

    Output:

    [{'subfolder1': ['sub-subfolder1', 'sub-subfolder2', 'sub-subfolder3']}, 
    {'subfolder2': ['sub-subfolder1']}, 
    {'subfolder3': ['sub-subfolder1', 'sub-subfolder2']}]