# Copyright (c) 2025 Patrick Motsch # All rights reserved. import logging import json import base64 from typing import Dict, Any from modules.datamodels.datamodelChat import ActionResult, ActionDocument logger = logging.getLogger(__name__) async def uploadFile(self, parameters: Dict[str, Any]) -> ActionResult: try: connectionReference = parameters.get("connectionReference") if not connectionReference: return ActionResult.isFailure(error="connectionReference parameter is required") siteIdParam = parameters.get("siteId") if not siteIdParam: return ActionResult.isFailure(error="siteId parameter is required") folderPath = parameters.get("folderPath") if not folderPath: return ActionResult.isFailure(error="folderPath parameter is required") fileName = parameters.get("fileName") if not fileName: return ActionResult.isFailure(error="fileName parameter is required") contentParam = parameters.get("content") if not contentParam: return ActionResult.isFailure(error="content parameter is required") # Extract siteId from document if it's a reference siteId = None if isinstance(siteIdParam, str): from modules.datamodels.datamodelDocref import DocumentReferenceList try: docList = DocumentReferenceList.from_string_list([siteIdParam]) chatDocuments = self.services.chat.getChatDocumentsFromDocumentList(docList) if chatDocuments and len(chatDocuments) > 0: siteInfoJson = json.loads(chatDocuments[0].documentData) siteId = siteInfoJson.get("id") except: pass if not siteId: siteId = siteIdParam else: siteId = siteIdParam if not siteId: return ActionResult.isFailure(error="Could not extract siteId from parameter") # Get file content from document from modules.datamodels.datamodelDocref import DocumentReferenceList docList = DocumentReferenceList.from_string_list([contentParam] if isinstance(contentParam, str) else contentParam) chatDocuments = self.services.chat.getChatDocumentsFromDocumentList(docList) if not chatDocuments or len(chatDocuments) == 0: return ActionResult.isFailure(error="Could not get file content from document reference") fileContentBase64 = chatDocuments[0].documentData # Decode base64 try: fileContent = base64.b64decode(fileContentBase64) except Exception as e: return ActionResult.isFailure(error=f"Could not decode base64 file content: {str(e)}") # Get Microsoft connection connection = self.connection.getMicrosoftConnection(connectionReference) if not connection: return ActionResult.isFailure(error="No valid Microsoft connection found for the provided connection reference") # Upload file uploadResult = await self.services.sharepoint.uploadFile( siteId=siteId, folderPath=folderPath, fileName=fileName, content=fileContent ) if "error" in uploadResult: return ActionResult.isFailure(error=f"Upload failed: {uploadResult['error']}") logger.info(f"Uploaded file to SharePoint: {folderPath}/{fileName} ({len(fileContent)} bytes)") # Generate filename workflowContext = self.services.chat.getWorkflowContext() if hasattr(self.services, 'chat') else None filename = self._generateMeaningfulFileName( "file_upload_result", "json", workflowContext, "uploadFile" ) result = { "success": True, "siteId": siteId, "filePath": f"{folderPath}/{fileName}", "fileSize": len(fileContent), "uploadResult": uploadResult } validationMetadata = self._createValidationMetadata( "uploadFile", siteId=siteId, filePath=f"{folderPath}/{fileName}", fileSize=len(fileContent) ) document = ActionDocument( documentName=filename, documentData=json.dumps(result, indent=2), mimeType="application/json", validationMetadata=validationMetadata ) return ActionResult.isSuccess(documents=[document]) except Exception as e: errorMsg = f"Error uploading file to SharePoint: {str(e)}" logger.error(errorMsg) return ActionResult.isFailure(error=errorMsg)