217 lines
No EOL
8.9 KiB
Python
217 lines
No EOL
8.9 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, AuthSource, 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"
|
|
self.auth_source = AuthSource.MICROSOFT
|
|
|
|
@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}
|
|
}
|
|
}
|
|
}
|
|
|
|
async def execute(self, action: str, parameters: Dict[str, Any], auth_data: Optional[Dict[str, Any]] = None) -> MethodResult:
|
|
"""Execute SharePoint method"""
|
|
try:
|
|
# Validate parameters
|
|
if not await self.validate_parameters(action, parameters):
|
|
return self._create_result(
|
|
success=False,
|
|
data={"error": f"Invalid parameters for {action}"}
|
|
)
|
|
|
|
# Get UserConnection from auth_data
|
|
if not auth_data or "userConnection" not in auth_data:
|
|
return self._create_result(
|
|
success=False,
|
|
data={"error": "UserConnection required for SharePoint operations"}
|
|
)
|
|
|
|
user_connection: UserConnection = auth_data["userConnection"]
|
|
|
|
# Execute action
|
|
if action == "search":
|
|
return await self._search_documents(parameters, user_connection)
|
|
elif action == "read":
|
|
return await self._read_document(parameters, user_connection)
|
|
elif action == "write":
|
|
return await self._write_document(parameters, user_connection)
|
|
else:
|
|
return self._create_result(
|
|
success=False,
|
|
data={"error": f"Unknown action: {action}"}
|
|
)
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error executing SharePoint {action}: {e}")
|
|
return self._create_result(
|
|
success=False,
|
|
data={"error": str(e)}
|
|
)
|
|
|
|
async def _search_documents(self, parameters: Dict[str, Any], user_connection: UserConnection) -> MethodResult:
|
|
"""Search SharePoint documents"""
|
|
try:
|
|
site_url = parameters["siteUrl"]
|
|
query = parameters["query"]
|
|
list_name = parameters.get("listName")
|
|
max_results = parameters.get("maxResults", 10)
|
|
|
|
# Create SharePoint context
|
|
ctx = ClientContext(site_url).with_credentials(
|
|
UserCredential(user_connection.authToken, user_connection.refreshToken)
|
|
)
|
|
|
|
# Search in specific list or entire site
|
|
if list_name:
|
|
target_list = ctx.web.lists.get_by_title(list_name)
|
|
items = target_list.items.filter(f"Title eq '{query}'").top(max_results).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[:max_results]]
|
|
|
|
return self._create_result(
|
|
success=True,
|
|
data={
|
|
"query": query,
|
|
"results": results
|
|
}
|
|
)
|
|
except Exception as e:
|
|
logger.error(f"Error searching SharePoint documents: {e}")
|
|
return self._create_result(
|
|
success=False,
|
|
data={"error": f"Search failed: {str(e)}"}
|
|
)
|
|
|
|
async def _read_document(self, parameters: Dict[str, Any], user_connection: UserConnection) -> MethodResult:
|
|
"""Read SharePoint document content"""
|
|
try:
|
|
site_url = parameters["siteUrl"]
|
|
file_url = parameters["fileUrl"]
|
|
|
|
# Create SharePoint context
|
|
ctx = ClientContext(site_url).with_credentials(
|
|
UserCredential(user_connection.authToken, user_connection.refreshToken)
|
|
)
|
|
|
|
# Get file
|
|
file = ctx.web.get_file_by_server_relative_url(file_url)
|
|
file_content = file.read().execute_query()
|
|
|
|
return self._create_result(
|
|
success=True,
|
|
data={
|
|
"url": file_url,
|
|
"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._create_result(
|
|
success=False,
|
|
data={"error": f"Read failed: {str(e)}"}
|
|
)
|
|
|
|
async def _write_document(self, parameters: Dict[str, Any], user_connection: UserConnection) -> MethodResult:
|
|
"""Write content to SharePoint document"""
|
|
try:
|
|
site_url = parameters["siteUrl"]
|
|
file_url = parameters["fileUrl"]
|
|
content = parameters["content"]
|
|
content_type = parameters.get("contentType", "text/plain")
|
|
|
|
# Create SharePoint context
|
|
ctx = ClientContext(site_url).with_credentials(
|
|
UserCredential(user_connection.authToken, user_connection.refreshToken)
|
|
)
|
|
|
|
# Get or create file
|
|
try:
|
|
file = ctx.web.get_file_by_server_relative_url(file_url)
|
|
except:
|
|
# Create new file
|
|
folder_url = "/".join(file_url.split("/")[:-1])
|
|
file_name = file_url.split("/")[-1]
|
|
folder = ctx.web.get_folder_by_server_relative_url(folder_url)
|
|
file = folder.upload_file(file_name, content.encode('utf-8')).execute_query()
|
|
|
|
# Update file content
|
|
file.write(content.encode('utf-8')).execute_query()
|
|
|
|
return self._create_result(
|
|
success=True,
|
|
data={
|
|
"url": file_url,
|
|
"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._create_result(
|
|
success=False,
|
|
data={"error": f"Write failed: {str(e)}"}
|
|
) |