From 9644514e604637ec7f9215008e38628cc5f6f923 Mon Sep 17 00:00:00 2001 From: ValueOn AG Date: Thu, 4 Sep 2025 01:48:00 +0200 Subject: [PATCH] shareopint fixed --- modules/methods/methodSharepoint.py | 186 +++++++++++++++++++++++++--- 1 file changed, 172 insertions(+), 14 deletions(-) diff --git a/modules/methods/methodSharepoint.py b/modules/methods/methodSharepoint.py index 12af28d6..a8257bc3 100644 --- a/modules/methods/methodSharepoint.py +++ b/modules/methods/methodSharepoint.py @@ -357,6 +357,7 @@ class MethodSharepoint(MethodBase): - "and:DELTA AND 2025 Mars AND Group" - all terms must be present - "folders:and:DELTA AND 2025 Mars AND Group" - combined options Note: For storage locations, use "folders:" prefix. All search terms must be present by default. + resultDocument (str, optional): JSON result document from previous findDocumentPath action to refine search searchScope (str, optional): Search scope - options: "all" (default), "documents" (files only), "pages" (SharePoint pages only) maxResults (int, optional): Maximum number of results to return (default: 100) expectedDocumentFormats (list, optional): Expected document formats with extension, mimeType, description @@ -364,6 +365,7 @@ class MethodSharepoint(MethodBase): try: connectionReference = parameters.get("connectionReference") searchQuery = parameters.get("searchQuery", "*") + resultDocument = parameters.get("resultDocument") searchScope = parameters.get("searchScope", "all") maxResults = parameters.get("maxResults", 100) expectedDocumentFormats = parameters.get("expectedDocumentFormats", []) @@ -371,6 +373,36 @@ class MethodSharepoint(MethodBase): if not connectionReference: return ActionResult.isFailure(error="Connection reference is required") + # If resultDocument is provided, extract site information to refine search + if resultDocument: + try: + import json + # Resolve the reference label to get the actual document list + document_list = self.service.getChatDocumentsFromDocumentList([resultDocument]) + if not document_list or len(document_list) == 0: + return ActionResult.isFailure(error=f"No document list found for reference: {resultDocument}") + + # Get the first document's content (which should be the JSON) + first_document = document_list[0] + file_data = self.service.getFileData(first_document.fileId) + if not file_data: + return ActionResult.isFailure(error=f"No file data found for document: {resultDocument}") + + # Parse the JSON content + result_data = json.loads(file_data) + found_documents = result_data.get("foundDocuments", []) + + # Extract site information from the result for context + if found_documents: + # Use the site information from the previous search to refine current search + # This could be used to limit search to specific sites or add context + logger.info(f"Refining search using {len(found_documents)} documents from previous result") + + except json.JSONDecodeError as e: + return ActionResult.isFailure(error=f"Invalid JSON in resultDocument: {str(e)}") + except Exception as e: + return ActionResult.isFailure(error=f"Error resolving resultDocument reference: {str(e)}") + # Parse searchQuery to extract path, search terms, search type, and options pathQuery, fileQuery, searchType, searchOptions = self._parseSearchQuery(searchQuery) @@ -540,6 +572,7 @@ class MethodSharepoint(MethodBase): documentList (str): Reference to the document list to read connectionReference (str): Reference to the Microsoft connection pathQuery (str): Path query to locate documents (e.g., "/Documents/Project1", "*" for all sites) + resultDocument (str, optional): JSON result document from findDocumentPath action (alternative to pathQuery) includeMetadata (bool, optional): Whether to include metadata (default: True) expectedDocumentFormats (list, optional): Expected document formats with extension, mimeType, description """ @@ -547,12 +580,50 @@ class MethodSharepoint(MethodBase): documentList = parameters.get("documentList") connectionReference = parameters.get("connectionReference") pathQuery = parameters.get("pathQuery", "*") + resultDocument = parameters.get("resultDocument") includeMetadata = parameters.get("includeMetadata", True) expectedDocumentFormats = parameters.get("expectedDocumentFormats", []) if not documentList or not connectionReference: return ActionResult.isFailure(error="Document list reference and connection reference are required") + # If resultDocument is provided, extract folder IDs from it + if resultDocument: + try: + import json + # Resolve the reference label to get the actual document list + document_list = self.service.getChatDocumentsFromDocumentList([resultDocument]) + if not document_list or len(document_list) == 0: + return ActionResult.isFailure(error=f"No document list found for reference: {resultDocument}") + + # Get the first document's content (which should be the JSON) + first_document = document_list[0] + file_data = self.service.getFileData(first_document.fileId) + if not file_data: + return ActionResult.isFailure(error=f"No file data found for document: {resultDocument}") + + # Parse the JSON content + result_data = json.loads(file_data) + found_documents = result_data.get("foundDocuments", []) + + # Extract folder IDs from the result + folder_ids = [] + for doc in found_documents: + if doc.get("type") == "folder": + folder_ids.append(doc.get("id")) + + if folder_ids: + # Use the first folder ID found as pathQuery + pathQuery = folder_ids[0] + logger.info(f"Using folder ID from resultDocument: {pathQuery}") + else: + return ActionResult.isFailure(error="No folders found in resultDocument") + + except json.JSONDecodeError as e: + return ActionResult.isFailure(error=f"Invalid JSON in resultDocument: {str(e)}") + except Exception as e: + return ActionResult.isFailure(error=f"Error resolving resultDocument reference: {str(e)}") + # Get documents from reference - ensure documentList is a list, not a string if isinstance(documentList, str): documentList = [documentList] # Convert string to list @@ -736,6 +807,7 @@ class MethodSharepoint(MethodBase): pathQuery (str): Path query where to upload documents (e.g., "/Documents/Project1", "*" for default location) documentList (str): Reference to the document list to upload fileNames (List[str]): List of names for the uploaded files + resultDocument (str, optional): JSON result document from findDocumentPath action (alternative to pathQuery) expectedDocumentFormats (list, optional): Expected document formats with extension, mimeType, description """ try: @@ -743,11 +815,49 @@ class MethodSharepoint(MethodBase): pathQuery = parameters.get("pathQuery", "/Documents") documentList = parameters.get("documentList") fileNames = parameters.get("fileNames") + resultDocument = parameters.get("resultDocument") expectedDocumentFormats = parameters.get("expectedDocumentFormats", []) if not connectionReference or not documentList or not fileNames: return ActionResult.isFailure(error="Connection reference, document list, and file names are required") + # If resultDocument is provided, extract folder IDs from it + if resultDocument: + try: + import json + # Resolve the reference label to get the actual document list + document_list = self.service.getChatDocumentsFromDocumentList([resultDocument]) + if not document_list or len(document_list) == 0: + return ActionResult.isFailure(error=f"No document list found for reference: {resultDocument}") + + # Get the first document's content (which should be the JSON) + first_document = document_list[0] + file_data = self.service.getFileData(first_document.fileId) + if not file_data: + return ActionResult.isFailure(error=f"No file data found for document: {resultDocument}") + + # Parse the JSON content + result_data = json.loads(file_data) + found_documents = result_data.get("foundDocuments", []) + + # Extract folder IDs from the result + folder_ids = [] + for doc in found_documents: + if doc.get("type") == "folder": + folder_ids.append(doc.get("id")) + + if folder_ids: + # Use the first folder ID found as pathQuery + pathQuery = folder_ids[0] + logger.info(f"Using folder ID from resultDocument: {pathQuery}") + else: + return ActionResult.isFailure(error="No folders found in resultDocument") + + except json.JSONDecodeError as e: + return ActionResult.isFailure(error=f"Invalid JSON in resultDocument: {str(e)}") + except Exception as e: + return ActionResult.isFailure(error=f"Error resolving resultDocument reference: {str(e)}") + # Get Microsoft connection connection = self._getMicrosoftConnection(connectionReference) if not connection: @@ -904,35 +1014,86 @@ class MethodSharepoint(MethodBase): Parameters: connectionReference (str): Reference to the Microsoft connection - pathQuery (str): Path query to list folders (e.g., "/Documents", "/Shared Documents/Project1", "*" for all sites) + searchQuery (str): [path:][type:][mode:]query - "Test Plan", "folders:Test Plan", "/Documents", "*" + Note: Use "folders:Name" to search for folders anywhere, not "path:/Name" which looks only in root + resultDocument (str, optional): JSON result document from findDocumentPath action (alternative to searchQuery) includeSubfolders (bool, optional): Whether to include subfolders (default: False) expectedDocumentFormats (list, optional): Expected document formats with extension, mimeType, description """ try: connectionReference = parameters.get("connectionReference") - pathQuery = parameters.get("pathQuery", "*") + searchQuery = parameters.get("searchQuery", "*") + resultDocument = parameters.get("resultDocument") includeSubfolders = parameters.get("includeSubfolders", False) # Default to False for better UX expectedDocumentFormats = parameters.get("expectedDocumentFormats", []) if not connectionReference: return ActionResult.isFailure(error="Connection reference is required") + # If resultDocument is provided, resolve the reference and extract folder IDs from it + if resultDocument: + try: + import json + # Resolve the reference label to get the actual document list + document_list = self.service.getChatDocumentsFromDocumentList([resultDocument]) + if not document_list or len(document_list) == 0: + return ActionResult.isFailure(error=f"No document list found for reference: {resultDocument}") + + # Get the first document's content (which should be the JSON) + first_document = document_list[0] + logger.info(f"Document fileId: {first_document.fileId}, fileName: {first_document.fileName}") + file_data = self.service.getFileData(first_document.fileId) + if not file_data: + return ActionResult.isFailure(error=f"No file data found for document: {resultDocument} (fileId: {first_document.fileId})") + logger.info(f"File data length: {len(file_data) if file_data else 0}") + + # Parse the JSON content + result_data = json.loads(file_data) + found_documents = result_data.get("foundDocuments", []) + + # Extract folder IDs from the result + folder_ids = [] + for doc in found_documents: + if doc.get("type") == "folder": + folder_ids.append(doc.get("id")) + + if folder_ids: + # Use the first folder ID found + searchQuery = folder_ids[0] + logger.info(f"Using folder ID from resultDocument: {searchQuery}") + else: + return ActionResult.isFailure(error="No folders found in resultDocument") + + except json.JSONDecodeError as e: + return ActionResult.isFailure(error=f"Invalid JSON in resultDocument: {str(e)}") + except Exception as e: + return ActionResult.isFailure(error=f"Error resolving resultDocument reference: {str(e)}") + # Get Microsoft connection connection = self._getMicrosoftConnection(connectionReference) if not connection: return ActionResult.isFailure(error="No valid Microsoft connection found for the provided connection reference") - logger.info(f"Starting SharePoint listDocuments for pathQuery: {pathQuery}") + logger.info(f"Starting SharePoint listDocuments for searchQuery: {searchQuery}") logger.debug(f"Connection ID: {connection['id']}") + # Parse searchQuery to extract path, search terms, search type, and options + pathQuery, fileQuery, searchType, searchOptions = self._parseSearchQuery(searchQuery) + # Discover all SharePoint sites accessible to the user sites = await self._discoverSharePointSites(connection["accessToken"]) if not sites: return ActionResult.isFailure(error="No SharePoint sites found or accessible") - # Resolve path query into folder paths - folder_paths = self._resolvePathQuery(pathQuery) - logger.info(f"Resolved folder paths: {folder_paths}") + # Check if searchQuery is a folder ID (starts with 01PPXICCB...) + if searchQuery.startswith('01PPXICCB') or searchQuery.startswith('01'): + # Direct folder ID - use it directly + folder_paths = [searchQuery] + logger.info(f"Using direct folder ID: {searchQuery}") + else: + # Resolve path query into folder paths + folder_paths = self._resolvePathQuery(pathQuery) + logger.info(f"Resolved folder paths: {folder_paths}") # Process each folder path across all sites list_results = [] @@ -952,8 +1113,11 @@ class MethodSharepoint(MethodBase): if folderPath in ["/", ""] or folderPath == "*": # Root folder endpoint = f"sites/{site_id}/drive/root/children" + elif folderPath.startswith('01PPXICCB') or folderPath.startswith('01'): + # Direct folder ID + endpoint = f"sites/{site_id}/drive/items/{folderPath}/children" else: - # Specific folder - remove leading slash if present + # Specific folder path - remove leading slash if present folder_path_clean = folderPath.lstrip('/') endpoint = f"sites/{site_id}/drive/root:/{folder_path_clean}:/children" @@ -1067,16 +1231,10 @@ class MethodSharepoint(MethodBase): # Create result data result_data = { - "connectionReference": connectionReference, - "pathQuery": pathQuery, + "searchQuery": searchQuery, "includeSubfolders": includeSubfolders, "sitesSearched": len(sites), "listResults": list_results, - "connection": { - "id": connection["id"], - "authority": "microsoft", - "reference": connectionReference - }, "timestamp": get_utc_timestamp() }