gateway/modules/methods/methodSharepoint.py
2025-06-21 03:06:00 +02:00

625 lines
No EOL
23 KiB
Python

"""
SharePoint method module.
Handles SharePoint operations using the SharePoint service.
"""
import logging
from typing import Dict, Any, List, Optional
from datetime import datetime, UTC
import json
from modules.workflow.methodBase import MethodBase, ActionResult, action
logger = logging.getLogger(__name__)
class SharepointService:
"""Service for Microsoft SharePoint operations using Graph API"""
def __init__(self, serviceContainer: Any):
self.serviceContainer = serviceContainer
def _getMicrosoftConnection(self, connectionReference: str) -> Optional[Dict[str, Any]]:
"""Get Microsoft connection from connection reference"""
try:
userConnection = self.serviceContainer.getUserConnectionFromConnectionReference(connectionReference)
if not userConnection or userConnection.authority != "msft" or userConnection.status != "active":
return None
# Get the corresponding token for this user and authority
token = self.serviceContainer.interfaceApp.getToken(userConnection.authority)
if not token:
logger.warning(f"No token found for user {userConnection.userId} and authority {userConnection.authority}")
return None
return {
"id": userConnection.id,
"accessToken": token.tokenAccess,
"refreshToken": token.tokenRefresh,
"scopes": ["Mail.ReadWrite", "User.Read"] # Default Microsoft scopes
}
except Exception as e:
logger.error(f"Error getting Microsoft connection: {str(e)}")
return None
async def searchContent(self, connectionReference: str, query: str, siteId: str = None, contentType: str = None, maxResults: int = 10) -> Dict[str, Any]:
"""Search SharePoint content using Microsoft Graph API"""
try:
connection = self._getMicrosoftConnection(connectionReference)
if not connection:
return {
"error": "No valid Microsoft connection found for the provided connection reference",
"connectionReference": connectionReference
}
# For now, simulate SharePoint search
# In a real implementation, you would use Microsoft Graph API
search_prompt = f"""
Search SharePoint content for the following query.
Query: {query}
Site ID: {siteId or 'All sites'}
Content Type: {contentType or 'All types'}
Max Results: {maxResults}
Please provide:
1. Relevant search results
2. Content summaries
3. File and document information
4. Site and list references
5. Metadata and properties
"""
# Use AI to simulate search results
search_results = await self.serviceContainer.interfaceAiCalls.callAiTextAdvanced(search_prompt)
return {
"query": query,
"siteId": siteId,
"contentType": contentType,
"maxResults": maxResults,
"results": search_results,
"connection": {
"id": connection["id"],
"authority": "microsoft",
"reference": connectionReference
}
}
except Exception as e:
logger.error(f"Error searching SharePoint: {str(e)}")
return {
"error": str(e)
}
async def readItem(self, connectionReference: str, itemId: str, siteId: str = None, listId: str = None) -> Dict[str, Any]:
"""Read SharePoint item using Microsoft Graph API"""
try:
connection = self._getMicrosoftConnection(connectionReference)
if not connection:
return {
"error": "No valid Microsoft connection found for the provided connection reference",
"itemId": itemId,
"connectionReference": connectionReference
}
# For now, simulate item reading
# In a real implementation, you would use Microsoft Graph API
read_prompt = f"""
Read SharePoint item details.
Item ID: {itemId}
Site ID: {siteId or 'Default site'}
List ID: {listId or 'Default list'}
Please provide:
1. Item properties and metadata
2. Content and attachments
3. Permissions and access rights
4. Version history if available
5. Related items and links
"""
# Use AI to simulate item data
item_data = await self.serviceContainer.interfaceAiCalls.callAiTextAdvanced(read_prompt)
return {
"itemId": itemId,
"siteId": siteId,
"listId": listId,
"data": item_data,
"connection": {
"id": connection["id"],
"authority": "microsoft",
"reference": connectionReference
}
}
except Exception as e:
logger.error(f"Error reading SharePoint item: {str(e)}")
return {
"error": str(e),
"itemId": itemId
}
async def writeItem(self, connectionReference: str, siteId: str, listId: str, item: Dict[str, Any]) -> Dict[str, Any]:
"""Write SharePoint item using Microsoft Graph API"""
try:
connection = self._getMicrosoftConnection(connectionReference)
if not connection:
return {
"error": "No valid Microsoft connection found for the provided connection reference",
"connectionReference": connectionReference
}
# For now, simulate item writing
# In a real implementation, you would use Microsoft Graph API
write_prompt = f"""
Write item to SharePoint list.
Site ID: {siteId}
List ID: {listId}
Item data: {json.dumps(item, indent=2)}
Please provide:
1. Item creation/update details
2. Validation and formatting
3. Permission settings
4. Workflow triggers if applicable
5. Success confirmation
"""
# Use AI to simulate item creation
write_result = await self.serviceContainer.interfaceAiCalls.callAiTextAdvanced(write_prompt)
return {
"siteId": siteId,
"listId": listId,
"item": item,
"result": write_result,
"connection": {
"id": connection["id"],
"authority": "microsoft",
"reference": connectionReference
}
}
except Exception as e:
logger.error(f"Error writing SharePoint item: {str(e)}")
return {
"error": str(e)
}
async def readList(self, connectionReference: str, listId: str, siteId: str = None, query: str = None, maxResults: int = 10) -> Dict[str, Any]:
"""Read SharePoint list using Microsoft Graph API"""
try:
connection = self._getMicrosoftConnection(connectionReference)
if not connection:
return {
"error": "No valid Microsoft connection found for the provided connection reference",
"listId": listId,
"connectionReference": connectionReference
}
# For now, simulate list reading
# In a real implementation, you would use Microsoft Graph API
list_prompt = f"""
Read SharePoint list items.
List ID: {listId}
Site ID: {siteId or 'Default site'}
Query: {query or 'All items'}
Max Results: {maxResults}
Please provide:
1. List structure and columns
2. Item data and properties
3. Sorting and filtering options
4. Pagination information
5. List metadata and settings
"""
# Use AI to simulate list data
list_data = await self.serviceContainer.interfaceAiCalls.callAiTextAdvanced(list_prompt)
return {
"listId": listId,
"siteId": siteId,
"query": query,
"maxResults": maxResults,
"data": list_data,
"connection": {
"id": connection["id"],
"authority": "microsoft",
"reference": connectionReference
}
}
except Exception as e:
logger.error(f"Error reading SharePoint list: {str(e)}")
return {
"error": str(e),
"listId": listId
}
async def writeList(self, connectionReference: str, siteId: str, listId: str, items: List[Dict[str, Any]]) -> Dict[str, Any]:
"""Write multiple items to SharePoint list using Microsoft Graph API"""
try:
connection = self._getMicrosoftConnection(connectionReference)
if not connection:
return {
"error": "No valid Microsoft connection found for the provided connection reference",
"connectionReference": connectionReference
}
# For now, simulate bulk writing
# In a real implementation, you would use Microsoft Graph API
bulk_prompt = f"""
Write multiple items to SharePoint list.
Site ID: {siteId}
List ID: {listId}
Number of items: {len(items)}
Items data: {json.dumps(items[:3], indent=2)} # Show first 3 items
Please provide:
1. Bulk operation details
2. Validation and error handling
3. Performance optimization
4. Success/failure status for each item
5. Batch processing results
"""
# Use AI to simulate bulk operation
bulk_result = await self.serviceContainer.interfaceAiCalls.callAiTextAdvanced(bulk_prompt)
return {
"siteId": siteId,
"listId": listId,
"items": items,
"result": bulk_result,
"connection": {
"id": connection["id"],
"authority": "microsoft",
"reference": connectionReference
}
}
except Exception as e:
logger.error(f"Error writing to SharePoint list: {str(e)}")
return {
"error": str(e)
}
async def createList(self, connectionReference: str, siteId: str, name: str, description: str = None, template: str = "genericList", fields: List[Dict[str, Any]] = None) -> Dict[str, Any]:
"""Create SharePoint list using Microsoft Graph API"""
try:
connection = self._getMicrosoftConnection(connectionReference)
if not connection:
return {
"error": "No valid Microsoft connection found for the provided connection reference",
"connectionReference": connectionReference
}
# For now, simulate list creation
# In a real implementation, you would use Microsoft Graph API
create_prompt = f"""
Create a new SharePoint list.
Site ID: {siteId}
Name: {name}
Description: {description or 'No description'}
Template: {template}
Fields: {json.dumps(fields, indent=2) if fields else 'Default fields'}
Please provide:
1. List structure and configuration
2. Column definitions and types
3. Default views and permissions
4. Workflow and automation settings
5. Creation confirmation and next steps
"""
# Use AI to simulate list creation
creation_result = await self.serviceContainer.interfaceAiCalls.callAiTextAdvanced(create_prompt)
return {
"siteId": siteId,
"name": name,
"description": description,
"template": template,
"fields": fields,
"result": creation_result,
"connection": {
"id": connection["id"],
"authority": "microsoft",
"reference": connectionReference
}
}
except Exception as e:
logger.error(f"Error creating SharePoint list: {str(e)}")
return {
"error": str(e)
}
class MethodSharepoint(MethodBase):
"""SharePoint method implementation for site operations"""
def __init__(self, serviceContainer: Any):
"""Initialize the SharePoint method"""
super().__init__(serviceContainer)
self.name = "sharepoint"
self.description = "Handle SharePoint site operations like reading and writing lists"
self.sharepointService = SharepointService(serviceContainer)
@action
async def search(self, parameters: Dict[str, Any]) -> ActionResult:
"""Search SharePoint content"""
try:
connectionReference = parameters.get("connectionReference")
query = parameters.get("query")
siteId = parameters.get("siteId")
contentType = parameters.get("contentType")
maxResults = parameters.get("maxResults", 10)
if not connectionReference:
return self._createResult(
success=False,
data={},
error="Connection reference is required"
)
if not query:
return self._createResult(
success=False,
data={},
error="Search query is required"
)
# Search content
results = await self.sharepointService.searchContent(
connectionReference=connectionReference,
query=query,
siteId=siteId,
contentType=contentType,
maxResults=maxResults
)
return self._createResult(
success=True,
data=results
)
except Exception as e:
logger.error(f"Error searching SharePoint: {str(e)}")
return self._createResult(
success=False,
data={},
error=str(e)
)
@action
async def read(self, parameters: Dict[str, Any]) -> ActionResult:
"""Read SharePoint item"""
try:
connectionReference = parameters.get("connectionReference")
itemId = parameters.get("itemId")
siteId = parameters.get("siteId")
listId = parameters.get("listId")
if not connectionReference:
return self._createResult(
success=False,
data={},
error="Connection reference is required"
)
if not itemId:
return self._createResult(
success=False,
data={},
error="Item ID is required"
)
# Read item
item = await self.sharepointService.readItem(
connectionReference=connectionReference,
itemId=itemId,
siteId=siteId,
listId=listId
)
return self._createResult(
success=True,
data=item
)
except Exception as e:
logger.error(f"Error reading SharePoint item: {str(e)}")
return self._createResult(
success=False,
data={},
error=str(e)
)
@action
async def write(self, parameters: Dict[str, Any]) -> ActionResult:
"""Write SharePoint item"""
try:
connectionReference = parameters.get("connectionReference")
siteId = parameters.get("siteId")
listId = parameters.get("listId")
item = parameters.get("item", {})
if not connectionReference:
return self._createResult(
success=False,
data={},
error="Connection reference is required"
)
if not siteId or not listId:
return self._createResult(
success=False,
data={},
error="Site ID and list ID are required"
)
# Write item
result = await self.sharepointService.writeItem(
connectionReference=connectionReference,
siteId=siteId,
listId=listId,
item=item
)
return self._createResult(
success=True,
data=result
)
except Exception as e:
logger.error(f"Error writing SharePoint item: {str(e)}")
return self._createResult(
success=False,
data={},
error=str(e)
)
@action
async def readList(self, parameters: Dict[str, Any]) -> ActionResult:
"""Read SharePoint list"""
try:
connectionReference = parameters.get("connectionReference")
listId = parameters.get("listId")
siteId = parameters.get("siteId")
query = parameters.get("query")
maxResults = parameters.get("maxResults", 10)
if not connectionReference:
return self._createResult(
success=False,
data={},
error="Connection reference is required"
)
if not listId:
return self._createResult(
success=False,
data={},
error="List ID is required"
)
# Read list
items = await self.sharepointService.readList(
connectionReference=connectionReference,
listId=listId,
siteId=siteId,
query=query,
maxResults=maxResults
)
return self._createResult(
success=True,
data=items
)
except Exception as e:
logger.error(f"Error reading SharePoint list: {str(e)}")
return self._createResult(
success=False,
data={},
error=str(e)
)
@action
async def writeList(self, parameters: Dict[str, Any]) -> ActionResult:
"""Write multiple items to SharePoint list"""
try:
connectionReference = parameters.get("connectionReference")
siteId = parameters.get("siteId")
listId = parameters.get("listId")
items = parameters.get("items", [])
if not connectionReference:
return self._createResult(
success=False,
data={},
error="Connection reference is required"
)
if not siteId or not listId:
return self._createResult(
success=False,
data={},
error="Site ID and list ID are required"
)
# Write items
result = await self.sharepointService.writeList(
connectionReference=connectionReference,
siteId=siteId,
listId=listId,
items=items
)
return self._createResult(
success=True,
data=result
)
except Exception as e:
logger.error(f"Error writing to SharePoint list: {str(e)}")
return self._createResult(
success=False,
data={},
error=str(e)
)
@action
async def createList(self, parameters: Dict[str, Any]) -> ActionResult:
"""Create SharePoint list"""
try:
connectionReference = parameters.get("connectionReference")
siteId = parameters.get("siteId")
name = parameters.get("name")
description = parameters.get("description")
template = parameters.get("template", "genericList")
fields = parameters.get("fields", [])
if not connectionReference:
return self._createResult(
success=False,
data={},
error="Connection reference is required"
)
if not siteId or not name:
return self._createResult(
success=False,
data={},
error="Site ID and list name are required"
)
# Create list
list = await self.sharepointService.createList(
connectionReference=connectionReference,
siteId=siteId,
name=name,
description=description,
template=template,
fields=fields
)
return self._createResult(
success=True,
data=list
)
except Exception as e:
logger.error(f"Error creating SharePoint list: {str(e)}")
return self._createResult(
success=False,
data={},
error=str(e)
)