618 lines
No EOL
22 KiB
Python
618 lines
No EOL
22 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.methods.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 userConnection and userConnection.authority == "microsoft" and userConnection.enabled:
|
|
return {
|
|
"id": userConnection.id,
|
|
"accessToken": userConnection.accessToken,
|
|
"refreshToken": userConnection.refreshToken,
|
|
"scopes": userConnection.scopes
|
|
}
|
|
return None
|
|
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)
|
|
) |