🔍 Code Extractor

function ensure_document_folders

Maturity: 58

Ensures all required folder hierarchies exist in FileCloud storage for a controlled document, creating them if they don't exist.

File:
/tf/active/vicechatdev/CDocs/controllers/filecloud_controller.py
Lines:
204 - 316
Complexity:
moderate

Purpose

This function manages the FileCloud folder structure for document storage. It handles two scenarios: (1) documents with custom paths where it creates the custom path and document folder, and (2) standard documents where it creates a hierarchical structure (root/department/doc_type/document). The function checks for folder existence before creation to avoid duplicates and ensures parent folders exist before creating child folders.

Source Code

def ensure_document_folders(document: Union[ControlledDocument, str]) -> Dict[str, str]:
    """
    Ensure all required folders exist in FileCloud for document storage.
    
    Args:
        document: ControlledDocument instance or document UID
        
    Returns:
        Dictionary of created folder paths
        
    Raises:
        ResourceNotFoundError: If document not found
        FileCloudError: If folder creation fails
    """
    # Get document instance if UID provided
    if isinstance(document, str):
        doc = ControlledDocument(uid=document)
        if not doc:
            raise ResourceNotFoundError(f"Document not found: {document}")
    else:
        doc = document

    # Check if document has a custom path
    if doc.custom_path:
        # For custom path, we need to ensure both the custom path and document folder exist
        custom_path = doc.custom_path
        document_folder = f"{custom_path}/{doc.doc_number}"
        
        client = get_filecloud_client()
        
        folders = {
            "custom": custom_path,
            "document": document_folder
        }
        
        # Create each folder if it doesn't exist
        for folder_name, folder_path in folders.items():
            try:
                # First check if folder exists
                folder_exists = False
                try:
                    check_result = client.check_folder_exists(folder_path)
                    logger.info(f"Checking folder existence: {folder_path} - Result: {check_result}")
                    folder_exists = isinstance(check_result, bool) and check_result
                except Exception:
                    folder_exists = False
                
                # Create folder if it doesn't exist
                if not folder_exists:
                    logger.info(f"Creating folder: {folder_path}")
                    # Split the path to get parent path and folder name
                    path_parts = folder_path.split('/')
                    parent_path = '/'.join(path_parts[:-1])
                    folder_name = path_parts[-1]
                    
                    # Ensure parent path exists first (recursive folder creation)
                    if parent_path and not client.check_folder_exists(parent_path):
                        ensure_path_exists(client, parent_path)
                    
                    result = client.create_folder(path=parent_path, folder_name=folder_name)
                    
                    if not result.get('success', False):
                        logger.error(f"Failed to create folder {folder_path}: {result.get('message', 'Unknown error')}")
                        raise FileCloudError(f"Failed to create folder {folder_path}")
            
            except Exception as e:
                logger.error(f"Error creating folder {folder_path}: {e}")
                raise FileCloudError(f"Error creating folder structure: {e}")
        
        return folders
    
    client = get_filecloud_client()
    
    # Define folder hierarchy
    root_folder = f"/{settings.FILECLOUD_ROOT_FOLDER}"
    department_folder = f"{root_folder}/{doc.department}"
    doc_type_folder = f"{department_folder}/{doc.doc_type}"
    document_folder = f"{doc_type_folder}/{doc.doc_number}"
    
    folders = {
        "root": root_folder,
        "department": department_folder,
        "doc_type": doc_type_folder,
        "document": document_folder
    }
    

    # Create each folder if it doesn't exist
    for folder_name, folder_path in folders.items():
        try:
            # First check if folder exists
            folder_exists = False
            try:
                check_result = client.check_folder_exists(folder_path)
                logger.info(f"Checking folder existence: {folder_path} - Result: {check_result}")
                folder_exists = isinstance(check_result, bool) and check_result
            except Exception:
                folder_exists = False
            
            # Create folder if it doesn't exist
            if not folder_exists:
                logger.info(f"Creating folder: {folder_path}")
                result = client.create_folder(path="/".join(folder_path.split('/')[:-1]), folder_name=folder_path.split('/')[-1])
                
                if not result.get('success', False):
                    logger.error(f"Failed to create folder {folder_path}: {result.get('message', 'Unknown error')}")
                    raise FileCloudError(f"Failed to create folder {folder_path}")
            
        except Exception as e:
            logger.error(f"Error creating folder {folder_path}: {e}")
            raise FileCloudError(f"Error creating folder structure: {e}")
    
    return folders

Parameters

Name Type Default Kind
document Union[ControlledDocument, str] - positional_or_keyword

Parameter Details

document: Either a ControlledDocument instance or a string containing the document UID. If a string UID is provided, the function will attempt to retrieve the corresponding ControlledDocument. The document object must have attributes like doc_number, department, doc_type, and optionally custom_path.

Return Value

Type: Dict[str, str]

Returns a dictionary mapping folder type names to their full paths in FileCloud. For custom paths, returns {'custom': custom_path, 'document': document_folder}. For standard paths, returns {'root': root_folder, 'department': department_folder, 'doc_type': doc_type_folder, 'document': document_folder}. All paths are strings representing absolute FileCloud paths.

Dependencies

  • logging
  • typing
  • CDocs.config.settings
  • CDocs.models.document.ControlledDocument
  • CDocs.controllers.ResourceNotFoundError
  • CDocs.controllers.FileCloudError
  • CDocs.utils.FC_api.FileCloudAPI

Required Imports

from typing import Dict, Union
from CDocs.models.document import ControlledDocument
from CDocs.controllers import ResourceNotFoundError
from CDocs.controllers import FileCloudError
from CDocs.config import settings
import logging

Conditional/Optional Imports

These imports are only needed under specific conditions:

from CDocs.utils.FC_api import get_filecloud_client

Condition: Required to obtain FileCloud API client for folder operations

Required (conditional)
from CDocs.utils.FC_api import ensure_path_exists

Condition: Only used when creating folders with custom paths to recursively ensure parent directories exist

Optional

Usage Example

from CDocs.models.document import ControlledDocument
from CDocs.controllers.document_controller import ensure_document_folders

# Using with a ControlledDocument instance
doc = ControlledDocument(uid='DOC-12345')
folders = ensure_document_folders(doc)
print(f"Created folders: {folders}")
# Output: {'root': '/ControlledDocs', 'department': '/ControlledDocs/Engineering', 'doc_type': '/ControlledDocs/Engineering/SOP', 'document': '/ControlledDocs/Engineering/SOP/DOC-12345'}

# Using with a document UID string
folders = ensure_document_folders('DOC-12345')

# For documents with custom paths
doc_custom = ControlledDocument(uid='DOC-67890')
doc_custom.custom_path = '/CustomProjects/ProjectX'
folders = ensure_document_folders(doc_custom)
print(f"Custom folders: {folders}")
# Output: {'custom': '/CustomProjects/ProjectX', 'document': '/CustomProjects/ProjectX/DOC-67890'}

Best Practices

  • Always handle the ResourceNotFoundError when passing document UIDs as strings, as the document may not exist in the database
  • Ensure the FileCloud client is properly authenticated before calling this function
  • The function is idempotent - it can be called multiple times safely as it checks for folder existence before creation
  • For custom paths, ensure the custom_path attribute is properly set on the document before calling
  • Monitor logs for folder creation failures as they indicate potential FileCloud connectivity or permission issues
  • The function uses the @log_controller_action decorator, so all calls are automatically logged for audit purposes
  • Parent folders are created recursively for custom paths, but standard paths assume the root folder structure is valid
  • Handle FileCloudError exceptions to gracefully manage folder creation failures in production environments

Similar Components

AI-powered semantic similarity - components with related functionality:

  • function get_filecloud_document_path 69.8% similar

    Constructs and returns the FileCloud storage path for a controlled document, supporting both custom and standard folder structures with version-specific file paths.

    From: /tf/active/vicechatdev/CDocs/controllers/filecloud_controller.py
  • function ensure_path_exists 63.8% similar

    Recursively creates a directory path in FileCloud storage by ensuring all parent directories exist before creating child directories.

    From: /tf/active/vicechatdev/CDocs/controllers/filecloud_controller.py
  • function upload_document_to_filecloud 63.1% similar

    Uploads a document version to FileCloud storage system with metadata, handling file creation, folder structure, and audit logging.

    From: /tf/active/vicechatdev/CDocs/controllers/filecloud_controller.py
  • function create_controlled_document 62.2% similar

    Creates a new controlled document node in a graph database with metadata, establishes relationships with the CDocs root node, and returns a ControlledDocument instance.

    From: /tf/active/vicechatdev/CDocs/FC_sync.py
  • function delete_document_from_filecloud 61.7% similar

    Deletes a document and its associated folder from FileCloud storage, with permission checks, audit logging, and error handling.

    From: /tf/active/vicechatdev/CDocs/controllers/filecloud_controller.py
← Back to Browse