389 lines
No EOL
15 KiB
Python
389 lines
No EOL
15 KiB
Python
from typing import Dict, Any, Optional
|
|
import logging
|
|
from datetime import datetime, UTC
|
|
from office365.runtime.auth.user_credential import UserCredential
|
|
from office365.sharepoint.client_context import ClientContext
|
|
from office365.sharepoint.files.file import File
|
|
from office365.sharepoint.lists.list import List
|
|
from office365.sharepoint.lists.list_creation_information import ListCreationInformation
|
|
|
|
from modules.methods.methodBase import MethodBase, MethodResult
|
|
from modules.models.userConnection import UserConnection
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
class MethodSharepoint(MethodBase):
|
|
"""SharePoint method implementation for document operations"""
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
self.name = "sharepoint"
|
|
self.description = "Handle SharePoint document operations like search, read, and write"
|
|
|
|
@property
|
|
def actions(self) -> Dict[str, Dict[str, Any]]:
|
|
"""Available actions and their parameters"""
|
|
return {
|
|
"search": {
|
|
"description": "Search SharePoint documents",
|
|
"retryMax": 3,
|
|
"timeout": 30,
|
|
"parameters": {
|
|
"query": {"type": "string", "required": True},
|
|
"siteUrl": {"type": "string", "required": True},
|
|
"listName": {"type": "string", "required": False},
|
|
"maxResults": {"type": "number", "required": False}
|
|
}
|
|
},
|
|
"read": {
|
|
"description": "Read SharePoint document content",
|
|
"retryMax": 2,
|
|
"timeout": 30,
|
|
"parameters": {
|
|
"fileUrl": {"type": "string", "required": True},
|
|
"siteUrl": {"type": "string", "required": True}
|
|
}
|
|
},
|
|
"write": {
|
|
"description": "Write content to SharePoint document",
|
|
"retryMax": 2,
|
|
"timeout": 30,
|
|
"parameters": {
|
|
"fileUrl": {"type": "string", "required": True},
|
|
"siteUrl": {"type": "string", "required": True},
|
|
"content": {"type": "string", "required": True},
|
|
"contentType": {"type": "string", "required": False}
|
|
}
|
|
},
|
|
"readList": {
|
|
"description": "Read items from SharePoint list",
|
|
"retryMax": 2,
|
|
"timeout": 30,
|
|
"parameters": {
|
|
"siteUrl": {"type": "string", "required": True},
|
|
"listName": {"type": "string", "required": True},
|
|
"query": {"type": "string", "required": False},
|
|
"fields": {"type": "array", "required": False}
|
|
}
|
|
},
|
|
"writeList": {
|
|
"description": "Write items to SharePoint list",
|
|
"retryMax": 2,
|
|
"timeout": 30,
|
|
"parameters": {
|
|
"siteUrl": {"type": "string", "required": True},
|
|
"listName": {"type": "string", "required": True},
|
|
"items": {"type": "array", "required": True}
|
|
}
|
|
},
|
|
"createList": {
|
|
"description": "Create a new SharePoint list",
|
|
"retryMax": 2,
|
|
"timeout": 30,
|
|
"parameters": {
|
|
"siteUrl": {"type": "string", "required": True},
|
|
"listName": {"type": "string", "required": True},
|
|
"description": {"type": "string", "required": False},
|
|
"template": {"type": "string", "required": False},
|
|
"fields": {"type": "array", "required": False}
|
|
}
|
|
}
|
|
}
|
|
|
|
async def execute(self, action: str, parameters: Dict[str, Any], authData: Optional[Dict[str, Any]] = None) -> MethodResult:
|
|
"""Execute SharePoint method"""
|
|
try:
|
|
# Validate parameters
|
|
if not await self.validateParameters(action, parameters):
|
|
return self._createResult(
|
|
success=False,
|
|
data={"error": f"Invalid parameters for {action}"}
|
|
)
|
|
|
|
# Get UserConnection from auth_data
|
|
if not authData or "userConnection" not in authData:
|
|
return self._createResult(
|
|
success=False,
|
|
data={"error": "UserConnection required for SharePoint operations"}
|
|
)
|
|
|
|
userConnection: UserConnection = authData["userConnection"]
|
|
|
|
# Execute action
|
|
if action == "search":
|
|
return await self._search_documents(parameters, userConnection)
|
|
elif action == "read":
|
|
return await self._read_document(parameters, userConnection)
|
|
elif action == "write":
|
|
return await self._write_document(parameters, userConnection)
|
|
elif action == "readList":
|
|
return await self._readList(parameters, userConnection)
|
|
elif action == "writeList":
|
|
return await self._writeList(parameters, userConnection)
|
|
elif action == "createList":
|
|
return await self._createList(parameters, userConnection)
|
|
else:
|
|
return self._createResult(
|
|
success=False,
|
|
data={"error": f"Unknown action: {action}"}
|
|
)
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error executing SharePoint {action}: {e}")
|
|
return self._createResult(
|
|
success=False,
|
|
data={"error": str(e)}
|
|
)
|
|
|
|
async def _search_documents(self, parameters: Dict[str, Any], userConnection: UserConnection) -> MethodResult:
|
|
"""Search SharePoint documents"""
|
|
try:
|
|
siteUrl = parameters["siteUrl"]
|
|
query = parameters["query"]
|
|
listName = parameters.get("listName")
|
|
maxResults = parameters.get("maxResults", 10)
|
|
|
|
# Create SharePoint context
|
|
ctx = ClientContext(siteUrl).with_credentials(
|
|
UserCredential(userConnection.authToken, userConnection.refreshToken)
|
|
)
|
|
|
|
# Search in specific list or entire site
|
|
if listName:
|
|
targetList = ctx.web.lists.get_by_title(listName)
|
|
items = targetList.items.filter(f"Title eq '{query}'").top(maxResults).get().execute_query()
|
|
results = [{
|
|
"title": item.properties["Title"],
|
|
"url": item.properties["FileRef"],
|
|
"modified": item.properties["Modified"],
|
|
"created": item.properties["Created"]
|
|
} for item in items]
|
|
else:
|
|
# Search entire site
|
|
search_results = ctx.search(query).execute_query()
|
|
results = [{
|
|
"title": result.properties["Title"],
|
|
"url": result.properties["Path"],
|
|
"modified": result.properties["LastModifiedTime"],
|
|
"created": result.properties["Created"]
|
|
} for result in search_results[:maxResults]]
|
|
|
|
return self._createResult(
|
|
success=True,
|
|
data={
|
|
"query": query,
|
|
"results": results
|
|
}
|
|
)
|
|
except Exception as e:
|
|
logger.error(f"Error searching SharePoint documents: {e}")
|
|
return self._createResult(
|
|
success=False,
|
|
data={"error": f"Search failed: {str(e)}"}
|
|
)
|
|
|
|
async def _read_document(self, parameters: Dict[str, Any], userConnection: UserConnection) -> MethodResult:
|
|
"""Read SharePoint document content"""
|
|
try:
|
|
siteUrl = parameters["siteUrl"]
|
|
fileUrl = parameters["fileUrl"]
|
|
|
|
# Create SharePoint context
|
|
ctx = ClientContext(siteUrl).with_credentials(
|
|
UserCredential(userConnection.authToken, userConnection.refreshToken)
|
|
)
|
|
|
|
# Get file
|
|
file = ctx.web.get_file_by_server_relative_url(fileUrl)
|
|
file_content = file.read().execute_query()
|
|
|
|
return self._createResult(
|
|
success=True,
|
|
data={
|
|
"url": fileUrl,
|
|
"content": file_content.content.decode('utf-8'),
|
|
"modified": file.properties["TimeLastModified"],
|
|
"size": file.properties["Length"]
|
|
}
|
|
)
|
|
except Exception as e:
|
|
logger.error(f"Error reading SharePoint document: {e}")
|
|
return self._createResult(
|
|
success=False,
|
|
data={"error": f"Read failed: {str(e)}"}
|
|
)
|
|
|
|
async def _write_document(self, parameters: Dict[str, Any], userConnection: UserConnection) -> MethodResult:
|
|
"""Write content to SharePoint document"""
|
|
try:
|
|
siteUrl = parameters["siteUrl"]
|
|
fileUrl = parameters["fileUrl"]
|
|
content = parameters["content"]
|
|
contentType = parameters.get("contentType", "text/plain")
|
|
|
|
# Create SharePoint context
|
|
ctx = ClientContext(siteUrl).with_credentials(
|
|
UserCredential(userConnection.authToken, userConnection.refreshToken)
|
|
)
|
|
|
|
# Get or create file
|
|
try:
|
|
file = ctx.web.get_file_by_server_relative_url(fileUrl)
|
|
except:
|
|
# Create new file
|
|
folderUrl = "/".join(fileUrl.split("/")[:-1])
|
|
fileName = fileUrl.split("/")[-1]
|
|
folder = ctx.web.get_folder_by_server_relative_url(folderUrl)
|
|
file = folder.upload_file(fileName, content.encode('utf-8')).execute_query()
|
|
|
|
# Update file content
|
|
file.write(content.encode('utf-8')).execute_query()
|
|
|
|
return self._createResult(
|
|
success=True,
|
|
data={
|
|
"url": fileUrl,
|
|
"modified": datetime.now(UTC).isoformat(),
|
|
"size": len(content.encode('utf-8'))
|
|
}
|
|
)
|
|
except Exception as e:
|
|
logger.error(f"Error writing SharePoint document: {e}")
|
|
return self._createResult(
|
|
success=False,
|
|
data={"error": f"Write failed: {str(e)}"}
|
|
)
|
|
|
|
async def _readList(self, parameters: Dict[str, Any], userConnection: UserConnection) -> MethodResult:
|
|
"""Read items from SharePoint list"""
|
|
try:
|
|
siteUrl = parameters["siteUrl"]
|
|
listName = parameters["listName"]
|
|
query = parameters.get("query")
|
|
fields = parameters.get("fields", ["*"])
|
|
|
|
# Create SharePoint account
|
|
account = Account(
|
|
credentials=(userConnection.authToken, userConnection.refreshToken),
|
|
protocol=MSGraphProtocol()
|
|
)
|
|
|
|
# Get site
|
|
site = account.get_site(siteUrl)
|
|
|
|
# Get list
|
|
list = site.get_list(listName)
|
|
|
|
# Get items
|
|
if query:
|
|
items = list.get_items(query=query, fields=fields)
|
|
else:
|
|
items = list.get_items(fields=fields)
|
|
|
|
return self._createResult(
|
|
success=True,
|
|
data={
|
|
"siteUrl": siteUrl,
|
|
"listName": listName,
|
|
"items": items
|
|
}
|
|
)
|
|
except Exception as e:
|
|
logger.error(f"Error reading SharePoint list: {e}")
|
|
return self._createResult(
|
|
success=False,
|
|
data={"error": f"Read failed: {str(e)}"}
|
|
)
|
|
|
|
async def _writeList(self, parameters: Dict[str, Any], userConnection: UserConnection) -> MethodResult:
|
|
"""Write items to SharePoint list"""
|
|
try:
|
|
siteUrl = parameters["siteUrl"]
|
|
listName = parameters["listName"]
|
|
items = parameters["items"]
|
|
|
|
# Create SharePoint account
|
|
account = Account(
|
|
credentials=(userConnection.authToken, userConnection.refreshToken),
|
|
protocol=MSGraphProtocol()
|
|
)
|
|
|
|
# Get site
|
|
site = account.get_site(siteUrl)
|
|
|
|
# Get list
|
|
list = site.get_list(listName)
|
|
|
|
# Add items
|
|
results = []
|
|
for item in items:
|
|
result = list.add_item(item)
|
|
results.append({
|
|
"id": result.id,
|
|
"status": "success"
|
|
})
|
|
|
|
return self._createResult(
|
|
success=True,
|
|
data={
|
|
"siteUrl": siteUrl,
|
|
"listName": listName,
|
|
"results": results
|
|
}
|
|
)
|
|
except Exception as e:
|
|
logger.error(f"Error writing to SharePoint list: {e}")
|
|
return self._createResult(
|
|
success=False,
|
|
data={"error": f"Write failed: {str(e)}"}
|
|
)
|
|
|
|
async def _createList(self, parameters: Dict[str, Any], userConnection: UserConnection) -> MethodResult:
|
|
"""Create a new SharePoint list"""
|
|
try:
|
|
siteUrl = parameters["siteUrl"]
|
|
listName = parameters["listName"]
|
|
description = parameters.get("description")
|
|
template = parameters.get("template", "generic")
|
|
fields = parameters.get("fields", [])
|
|
|
|
# Create SharePoint account
|
|
account = Account(
|
|
credentials=(userConnection.authToken, userConnection.refreshToken),
|
|
protocol=MSGraphProtocol()
|
|
)
|
|
|
|
# Get site
|
|
site = account.get_site(siteUrl)
|
|
|
|
# Create list
|
|
list = site.create_list(
|
|
name=listName,
|
|
description=description,
|
|
template=template
|
|
)
|
|
|
|
# Add fields
|
|
for field in fields:
|
|
list.add_field(
|
|
name=field["name"],
|
|
field_type=field["type"],
|
|
required=field.get("required", False),
|
|
description=field.get("description")
|
|
)
|
|
|
|
return self._createResult(
|
|
success=True,
|
|
data={
|
|
"siteUrl": siteUrl,
|
|
"listName": listName,
|
|
"id": list.id,
|
|
"webUrl": list.web_url
|
|
}
|
|
)
|
|
except Exception as e:
|
|
logger.error(f"Error creating SharePoint list: {e}")
|
|
return self._createResult(
|
|
success=False,
|
|
data={"error": f"Create failed: {str(e)}"}
|
|
) |