395 lines
19 KiB
Python
395 lines
19 KiB
Python
# Copyright (c) 2025 Patrick Motsch
|
|
# All rights reserved.
|
|
|
|
"""
|
|
SharePoint operations method module.
|
|
Handles SharePoint document operations using the SharePoint service.
|
|
"""
|
|
|
|
import logging
|
|
from modules.workflows.methods.methodBase import MethodBase
|
|
from modules.datamodels.datamodelWorkflowActions import WorkflowActionDefinition, WorkflowActionParameter
|
|
from modules.shared.frontendTypes import FrontendType
|
|
|
|
# Import helpers
|
|
from .helpers.connection import ConnectionHelper
|
|
from .helpers.siteDiscovery import SiteDiscoveryHelper
|
|
from .helpers.documentParsing import DocumentParsingHelper
|
|
from .helpers.pathProcessing import PathProcessingHelper
|
|
from .helpers.apiClient import ApiClientHelper
|
|
|
|
# Import actions
|
|
from .actions.findDocumentPath import findDocumentPath
|
|
from .actions.readDocuments import readDocuments
|
|
from .actions.uploadDocument import uploadDocument
|
|
from .actions.listDocuments import listDocuments
|
|
from .actions.analyzeFolderUsage import analyzeFolderUsage
|
|
from .actions.findSiteByUrl import findSiteByUrl
|
|
from .actions.downloadFileByPath import downloadFileByPath
|
|
from .actions.copyFile import copyFile
|
|
from .actions.uploadFile import uploadFile
|
|
logger = logging.getLogger(__name__)
|
|
|
|
class MethodSharepoint(MethodBase):
|
|
"""SharePoint operations methods."""
|
|
|
|
def __init__(self, services):
|
|
super().__init__(services)
|
|
self.name = "sharepoint"
|
|
self.description = "SharePoint operations methods"
|
|
|
|
# Initialize helper modules
|
|
self.connection = ConnectionHelper(self)
|
|
self.siteDiscovery = SiteDiscoveryHelper(self)
|
|
self.documentParsing = DocumentParsingHelper(self)
|
|
self.pathProcessing = PathProcessingHelper(self)
|
|
self.apiClient = ApiClientHelper(self)
|
|
|
|
# RBAC-Integration: Action-Definitionen mit actionId
|
|
self._actions = {
|
|
"findDocumentPath": WorkflowActionDefinition(
|
|
actionId="sharepoint.findDocumentPath",
|
|
description="Find documents and folders by name/path across sites",
|
|
dynamicMode=True,
|
|
parameters={
|
|
"connectionReference": WorkflowActionParameter(
|
|
name="connectionReference",
|
|
type="str",
|
|
frontendType=FrontendType.USER_CONNECTION,
|
|
required=True,
|
|
description="Microsoft connection label"
|
|
),
|
|
"site": WorkflowActionParameter(
|
|
name="site",
|
|
type="str",
|
|
frontendType=FrontendType.TEXT,
|
|
required=False,
|
|
description="Site hint"
|
|
),
|
|
"searchQuery": WorkflowActionParameter(
|
|
name="searchQuery",
|
|
type="str",
|
|
frontendType=FrontendType.TEXT,
|
|
required=True,
|
|
description="Search terms or path"
|
|
),
|
|
"maxResults": WorkflowActionParameter(
|
|
name="maxResults",
|
|
type="int",
|
|
frontendType=FrontendType.NUMBER,
|
|
required=False,
|
|
default=1000,
|
|
description="Maximum items to return",
|
|
validation={"min": 1, "max": 10000}
|
|
)
|
|
},
|
|
execute=findDocumentPath.__get__(self, self.__class__)
|
|
),
|
|
"readDocuments": WorkflowActionDefinition(
|
|
actionId="sharepoint.readDocuments",
|
|
description="Read documents from SharePoint and extract content/metadata",
|
|
dynamicMode=True,
|
|
parameters={
|
|
"connectionReference": WorkflowActionParameter(
|
|
name="connectionReference",
|
|
type="str",
|
|
frontendType=FrontendType.USER_CONNECTION,
|
|
required=True,
|
|
description="Microsoft connection label"
|
|
),
|
|
"documentList": WorkflowActionParameter(
|
|
name="documentList",
|
|
type="List[str]",
|
|
frontendType=FrontendType.DOCUMENT_REFERENCE,
|
|
required=False,
|
|
description="Document list reference(s) containing findDocumentPath result"
|
|
),
|
|
"pathQuery": WorkflowActionParameter(
|
|
name="pathQuery",
|
|
type="str",
|
|
frontendType=FrontendType.SHAREPOINT_FOLDER,
|
|
required=False,
|
|
description="Direct path query if no documentList (e.g., /sites/SiteName/FolderPath)"
|
|
),
|
|
"includeMetadata": WorkflowActionParameter(
|
|
name="includeMetadata",
|
|
type="bool",
|
|
frontendType=FrontendType.CHECKBOX,
|
|
required=False,
|
|
default=True,
|
|
description="Include metadata"
|
|
)
|
|
},
|
|
execute=readDocuments.__get__(self, self.__class__)
|
|
),
|
|
"uploadDocument": WorkflowActionDefinition(
|
|
actionId="sharepoint.uploadDocument",
|
|
description="Upload documents to SharePoint",
|
|
dynamicMode=True,
|
|
parameters={
|
|
"connectionReference": WorkflowActionParameter(
|
|
name="connectionReference",
|
|
type="str",
|
|
frontendType=FrontendType.USER_CONNECTION,
|
|
required=True,
|
|
description="Microsoft connection label"
|
|
),
|
|
"documentList": WorkflowActionParameter(
|
|
name="documentList",
|
|
type="List[str]",
|
|
frontendType=FrontendType.DOCUMENT_REFERENCE,
|
|
required=True,
|
|
description="Document reference(s) to upload. File names are taken from the documents"
|
|
),
|
|
"pathQuery": WorkflowActionParameter(
|
|
name="pathQuery",
|
|
type="str",
|
|
frontendType=FrontendType.SHAREPOINT_FOLDER,
|
|
required=False,
|
|
description="Direct upload target path if documentList doesn't contain findDocumentPath result (e.g., /sites/SiteName/FolderPath)"
|
|
)
|
|
},
|
|
execute=uploadDocument.__get__(self, self.__class__)
|
|
),
|
|
"listDocuments": WorkflowActionDefinition(
|
|
actionId="sharepoint.listDocuments",
|
|
description="List documents and folders in SharePoint paths across sites",
|
|
dynamicMode=True,
|
|
parameters={
|
|
"connectionReference": WorkflowActionParameter(
|
|
name="connectionReference",
|
|
type="str",
|
|
frontendType=FrontendType.USER_CONNECTION,
|
|
required=True,
|
|
description="Microsoft connection label"
|
|
),
|
|
"documentList": WorkflowActionParameter(
|
|
name="documentList",
|
|
type="List[str]",
|
|
frontendType=FrontendType.DOCUMENT_REFERENCE,
|
|
required=False,
|
|
description="Document list reference(s) containing findDocumentPath result"
|
|
),
|
|
"pathQuery": WorkflowActionParameter(
|
|
name="pathQuery",
|
|
type="str",
|
|
frontendType=FrontendType.SHAREPOINT_FOLDER,
|
|
required=False,
|
|
description="Direct path query if no documentList (e.g., /sites/SiteName/FolderPath)"
|
|
),
|
|
"includeSubfolders": WorkflowActionParameter(
|
|
name="includeSubfolders",
|
|
type="bool",
|
|
frontendType=FrontendType.CHECKBOX,
|
|
required=False,
|
|
default=False,
|
|
description="Include one level of subfolders"
|
|
)
|
|
},
|
|
execute=listDocuments.__get__(self, self.__class__)
|
|
),
|
|
"analyzeFolderUsage": WorkflowActionDefinition(
|
|
actionId="sharepoint.analyzeFolderUsage",
|
|
description="Analyze usage intensity of folders and files in SharePoint",
|
|
dynamicMode=True,
|
|
parameters={
|
|
"connectionReference": WorkflowActionParameter(
|
|
name="connectionReference",
|
|
type="str",
|
|
frontendType=FrontendType.USER_CONNECTION,
|
|
required=True,
|
|
description="Microsoft connection label"
|
|
),
|
|
"documentList": WorkflowActionParameter(
|
|
name="documentList",
|
|
type="List[str]",
|
|
frontendType=FrontendType.DOCUMENT_REFERENCE,
|
|
required=True,
|
|
description="Document list reference(s) containing findDocumentPath result"
|
|
),
|
|
"startDateTime": WorkflowActionParameter(
|
|
name="startDateTime",
|
|
type="str",
|
|
frontendType=FrontendType.DATETIME,
|
|
required=False,
|
|
description="Start date/time in ISO format (e.g., 2025-11-01T00:00:00Z). Default: 30 days ago"
|
|
),
|
|
"endDateTime": WorkflowActionParameter(
|
|
name="endDateTime",
|
|
type="str",
|
|
frontendType=FrontendType.DATETIME,
|
|
required=False,
|
|
description="End date/time in ISO format (e.g., 2025-11-30T23:59:59Z). Default: current time"
|
|
),
|
|
"interval": WorkflowActionParameter(
|
|
name="interval",
|
|
type="str",
|
|
frontendType=FrontendType.SELECT,
|
|
frontendOptions=["day", "week", "month"],
|
|
required=False,
|
|
default="day",
|
|
description="Time interval for grouping activities"
|
|
)
|
|
},
|
|
execute=analyzeFolderUsage.__get__(self, self.__class__)
|
|
),
|
|
"findSiteByUrl": WorkflowActionDefinition(
|
|
actionId="sharepoint.findSiteByUrl",
|
|
description="Find SharePoint site by hostname and site path",
|
|
dynamicMode=True,
|
|
parameters={
|
|
"connectionReference": WorkflowActionParameter(
|
|
name="connectionReference",
|
|
type="str",
|
|
frontendType=FrontendType.USER_CONNECTION,
|
|
required=True,
|
|
description="Microsoft connection label"
|
|
),
|
|
"hostname": WorkflowActionParameter(
|
|
name="hostname",
|
|
type="str",
|
|
frontendType=FrontendType.TEXT,
|
|
required=True,
|
|
description="SharePoint hostname (e.g., example.sharepoint.com)"
|
|
),
|
|
"sitePath": WorkflowActionParameter(
|
|
name="sitePath",
|
|
type="str",
|
|
frontendType=FrontendType.TEXT,
|
|
required=True,
|
|
description="Site path (e.g., SteeringBPM or /sites/SteeringBPM)"
|
|
)
|
|
},
|
|
execute=findSiteByUrl.__get__(self, self.__class__)
|
|
),
|
|
"downloadFileByPath": WorkflowActionDefinition(
|
|
actionId="sharepoint.downloadFileByPath",
|
|
description="Download file from SharePoint by exact file path",
|
|
dynamicMode=True,
|
|
parameters={
|
|
"connectionReference": WorkflowActionParameter(
|
|
name="connectionReference",
|
|
type="str",
|
|
frontendType=FrontendType.USER_CONNECTION,
|
|
required=True,
|
|
description="Microsoft connection label"
|
|
),
|
|
"pathQuery": WorkflowActionParameter(
|
|
name="pathQuery",
|
|
type="str",
|
|
frontendType=FrontendType.TEXT,
|
|
required=False,
|
|
description="Full SharePoint path (e.g. /sites/SiteName/Shared Documents/file.pdf). When provided, siteId and filePath are derived automatically."
|
|
),
|
|
"siteId": WorkflowActionParameter(
|
|
name="siteId",
|
|
type="str",
|
|
frontendType=FrontendType.TEXT,
|
|
required=False,
|
|
description="SharePoint site ID (optional when pathQuery is provided)"
|
|
),
|
|
"filePath": WorkflowActionParameter(
|
|
name="filePath",
|
|
type="str",
|
|
frontendType=FrontendType.TEXT,
|
|
required=False,
|
|
description="File path relative to site root (optional when pathQuery is provided)"
|
|
)
|
|
},
|
|
execute=downloadFileByPath.__get__(self, self.__class__)
|
|
),
|
|
"copyFile": WorkflowActionDefinition(
|
|
actionId="sharepoint.copyFile",
|
|
description="Copy file within SharePoint",
|
|
dynamicMode=True,
|
|
parameters={
|
|
"connectionReference": WorkflowActionParameter(
|
|
name="connectionReference",
|
|
type="str",
|
|
frontendType=FrontendType.USER_CONNECTION,
|
|
required=True,
|
|
description="Microsoft connection label"
|
|
),
|
|
"sourcePath": WorkflowActionParameter(
|
|
name="sourcePath",
|
|
type="str",
|
|
frontendType=FrontendType.TEXT,
|
|
required=True,
|
|
description="Full path to source file (e.g. /sites/.../folder/file.pdf)"
|
|
),
|
|
"destPath": WorkflowActionParameter(
|
|
name="destPath",
|
|
type="str",
|
|
frontendType=FrontendType.TEXT,
|
|
required=True,
|
|
description="Full path to destination folder (e.g. /sites/.../folder)"
|
|
)
|
|
},
|
|
execute=copyFile.__get__(self, self.__class__)
|
|
),
|
|
"uploadFile": WorkflowActionDefinition(
|
|
actionId="sharepoint.uploadFile",
|
|
description="Upload raw file content (bytes) to SharePoint",
|
|
dynamicMode=True,
|
|
parameters={
|
|
"connectionReference": WorkflowActionParameter(
|
|
name="connectionReference",
|
|
type="str",
|
|
frontendType=FrontendType.USER_CONNECTION,
|
|
required=True,
|
|
description="Microsoft connection label"
|
|
),
|
|
"pathQuery": WorkflowActionParameter(
|
|
name="pathQuery",
|
|
type="str",
|
|
frontendType=FrontendType.TEXT,
|
|
required=False,
|
|
description="Target folder path (e.g. /sites/.../Folder). When provided, siteId and folderPath are derived. Alternative to explicit siteId+folderPath."
|
|
),
|
|
"siteId": WorkflowActionParameter(
|
|
name="siteId",
|
|
type="str",
|
|
frontendType=FrontendType.TEXT,
|
|
required=False,
|
|
description="SharePoint site ID (when not using pathQuery)"
|
|
),
|
|
"folderPath": WorkflowActionParameter(
|
|
name="folderPath",
|
|
type="str",
|
|
frontendType=FrontendType.TEXT,
|
|
required=False,
|
|
description="Folder path relative to site root (when not using pathQuery)"
|
|
),
|
|
"fileName": WorkflowActionParameter(
|
|
name="fileName",
|
|
type="str",
|
|
frontendType=FrontendType.TEXT,
|
|
required=False,
|
|
description="File name (defaults to document name when content from context)"
|
|
),
|
|
"content": WorkflowActionParameter(
|
|
name="content",
|
|
type="Any",
|
|
frontendType=FrontendType.DOCUMENT_REFERENCE,
|
|
required=True,
|
|
description="File content from context (upstream document) or document reference"
|
|
)
|
|
},
|
|
execute=uploadFile.__get__(self, self.__class__)
|
|
)
|
|
}
|
|
|
|
# Validate actions after definition
|
|
self._validateActions()
|
|
|
|
# Register actions as methods (optional, für direkten Zugriff)
|
|
self.findDocumentPath = findDocumentPath.__get__(self, self.__class__)
|
|
self.readDocuments = readDocuments.__get__(self, self.__class__)
|
|
self.uploadDocument = uploadDocument.__get__(self, self.__class__)
|
|
self.listDocuments = listDocuments.__get__(self, self.__class__)
|
|
self.analyzeFolderUsage = analyzeFolderUsage.__get__(self, self.__class__)
|
|
self.findSiteByUrl = findSiteByUrl.__get__(self, self.__class__)
|
|
self.downloadFileByPath = downloadFileByPath.__get__(self, self.__class__)
|
|
self.copyFile = copyFile.__get__(self, self.__class__)
|
|
self.uploadFile = uploadFile.__get__(self, self.__class__)
|
|
|