mbu-dev-shared-components 0.0.48__tar.gz → 0.0.50__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. mbu_dev_shared_components-0.0.50/.github/workflows/pylint.yml +32 -0
  2. mbu_dev_shared_components-0.0.50/.pylintrc +8 -0
  3. {mbu_dev_shared_components-0.0.48/mbu_dev_shared_components.egg-info → mbu_dev_shared_components-0.0.50}/PKG-INFO +13 -2
  4. {mbu_dev_shared_components-0.0.48 → mbu_dev_shared_components-0.0.50}/README.md +10 -0
  5. {mbu_dev_shared_components-0.0.48 → mbu_dev_shared_components-0.0.50}/mbu_dev_shared_components/getorganized/documents.py +32 -1
  6. mbu_dev_shared_components-0.0.50/mbu_dev_shared_components/office365/sharepoint_api/files.py +159 -0
  7. {mbu_dev_shared_components-0.0.48 → mbu_dev_shared_components-0.0.50}/mbu_dev_shared_components/os2forms/documents.py +2 -2
  8. {mbu_dev_shared_components-0.0.48 → mbu_dev_shared_components-0.0.50}/mbu_dev_shared_components/sap/create_invoice.py +0 -3
  9. {mbu_dev_shared_components-0.0.48 → mbu_dev_shared_components-0.0.50}/mbu_dev_shared_components/utils/db_stored_procedure_executor.py +1 -1
  10. mbu_dev_shared_components-0.0.50/mbu_dev_shared_components/utils/fernet_encryptor.py +65 -0
  11. {mbu_dev_shared_components-0.0.48 → mbu_dev_shared_components-0.0.50/mbu_dev_shared_components.egg-info}/PKG-INFO +13 -2
  12. {mbu_dev_shared_components-0.0.48 → mbu_dev_shared_components-0.0.50}/mbu_dev_shared_components.egg-info/SOURCES.txt +3 -0
  13. {mbu_dev_shared_components-0.0.48 → mbu_dev_shared_components-0.0.50}/mbu_dev_shared_components.egg-info/requires.txt +2 -1
  14. {mbu_dev_shared_components-0.0.48 → mbu_dev_shared_components-0.0.50}/pyproject.toml +3 -2
  15. mbu_dev_shared_components-0.0.48/mbu_dev_shared_components/office365/sharepoint_api/files.py +0 -191
  16. {mbu_dev_shared_components-0.0.48 → mbu_dev_shared_components-0.0.50}/.gitignore +0 -0
  17. {mbu_dev_shared_components-0.0.48 → mbu_dev_shared_components-0.0.50}/LICENSE +0 -0
  18. {mbu_dev_shared_components-0.0.48 → mbu_dev_shared_components-0.0.50}/mbu_dev_shared_components/getorganized/__init__.py +0 -0
  19. {mbu_dev_shared_components-0.0.48 → mbu_dev_shared_components-0.0.50}/mbu_dev_shared_components/getorganized/auth.py +0 -0
  20. {mbu_dev_shared_components-0.0.48 → mbu_dev_shared_components-0.0.50}/mbu_dev_shared_components/getorganized/cases.py +0 -0
  21. {mbu_dev_shared_components-0.0.48 → mbu_dev_shared_components-0.0.50}/mbu_dev_shared_components/getorganized/contacts.py +0 -0
  22. {mbu_dev_shared_components-0.0.48 → mbu_dev_shared_components-0.0.50}/mbu_dev_shared_components/getorganized/objects.py +0 -0
  23. {mbu_dev_shared_components-0.0.48 → mbu_dev_shared_components-0.0.50}/mbu_dev_shared_components/google/__init__.py +0 -0
  24. {mbu_dev_shared_components-0.0.48 → mbu_dev_shared_components-0.0.50}/mbu_dev_shared_components/google/api/__init__.py +0 -0
  25. {mbu_dev_shared_components-0.0.48 → mbu_dev_shared_components-0.0.50}/mbu_dev_shared_components/google/api/auth.py +0 -0
  26. {mbu_dev_shared_components-0.0.48 → mbu_dev_shared_components-0.0.50}/mbu_dev_shared_components/google/workspace/__init__.py +0 -0
  27. {mbu_dev_shared_components-0.0.48 → mbu_dev_shared_components-0.0.50}/mbu_dev_shared_components/google/workspace/alerts.py +0 -0
  28. {mbu_dev_shared_components-0.0.48 → mbu_dev_shared_components-0.0.50}/mbu_dev_shared_components/office365/__init__.py +0 -0
  29. {mbu_dev_shared_components-0.0.48 → mbu_dev_shared_components-0.0.50}/mbu_dev_shared_components/office365/excel/__init__.py +0 -0
  30. {mbu_dev_shared_components-0.0.48 → mbu_dev_shared_components-0.0.50}/mbu_dev_shared_components/office365/excel/excel_reader.py +0 -0
  31. {mbu_dev_shared_components-0.0.48 → mbu_dev_shared_components-0.0.50}/mbu_dev_shared_components/office365/sharepoint_api/__init__.py +0 -0
  32. {mbu_dev_shared_components-0.0.48 → mbu_dev_shared_components-0.0.50}/mbu_dev_shared_components/os2forms/__init__.py +0 -0
  33. {mbu_dev_shared_components-0.0.48 → mbu_dev_shared_components-0.0.50}/mbu_dev_shared_components/os2forms/forms.py +0 -0
  34. {mbu_dev_shared_components-0.0.48 → mbu_dev_shared_components-0.0.50}/mbu_dev_shared_components/sap/__init__.py +0 -0
  35. {mbu_dev_shared_components-0.0.48 → mbu_dev_shared_components-0.0.50}/mbu_dev_shared_components/utils/__init__.py +0 -0
  36. {mbu_dev_shared_components-0.0.48 → mbu_dev_shared_components-0.0.50}/mbu_dev_shared_components/utils/json_handler.py +0 -0
  37. {mbu_dev_shared_components-0.0.48 → mbu_dev_shared_components-0.0.50}/mbu_dev_shared_components.egg-info/dependency_links.txt +0 -0
  38. {mbu_dev_shared_components-0.0.48 → mbu_dev_shared_components-0.0.50}/mbu_dev_shared_components.egg-info/top_level.txt +0 -0
  39. {mbu_dev_shared_components-0.0.48 → mbu_dev_shared_components-0.0.50}/setup.cfg +0 -0
@@ -0,0 +1,32 @@
1
+ name: Linting
2
+
3
+ on: [push]
4
+
5
+ jobs:
6
+ build:
7
+ runs-on: windows-latest
8
+ strategy:
9
+ matrix:
10
+ python-version: ["3.11"]
11
+ fail-fast: false
12
+ steps:
13
+ - uses: actions/checkout@v3
14
+ - name: Set up Python ${{ matrix.python-version }}
15
+ uses: actions/setup-python@v3
16
+ with:
17
+ python-version: ${{ matrix.python-version }}
18
+
19
+ - name: Install dependencies
20
+ run: |
21
+ python -m pip install --upgrade pip
22
+ pip install pylint
23
+ pip install flake8
24
+ pip install .
25
+
26
+ - name: Analysing the code with pylint
27
+ run: |
28
+ pylint --rcfile=.pylintrc $(git ls-files '*.py')
29
+
30
+ - name: Analysing the code with flake8
31
+ run: |
32
+ flake8 --extend-ignore=E501,E251 $(git ls-files '*.py')
@@ -0,0 +1,8 @@
1
+ [pylint.messages_control]
2
+ disable =
3
+ C0301, # Line too long
4
+ I1101, E1101, # C-modules members
5
+ R0913, # Too many arguments
6
+ R0914, # Too many local variables
7
+ W0718, # Catching too general exception Exception (broad-exception-caught)
8
+ R0903, # Too few public methods
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mbu_dev_shared_components
3
- Version: 0.0.48
3
+ Version: 0.0.50
4
4
  Summary: Shared components to use in RPA projects
5
5
  Author-email: MBU <rpa@mbu.aarhus.dk>
6
6
  Classifier: Programming Language :: Python :: 3
@@ -9,11 +9,12 @@ Classifier: Operating System :: Microsoft :: Windows
9
9
  Requires-Python: >=3.7
10
10
  Description-Content-Type: text/markdown
11
11
  License-File: LICENSE
12
- Requires-Dist: Office365-REST-Python-Client>=2.5.9
12
+ Requires-Dist: shareplum
13
13
  Requires-Dist: openpyxl>=3.1.2
14
14
  Requires-Dist: pyodbc>=5.1.0
15
15
  Requires-Dist: requests_ntlm>=1.2.0
16
16
  Requires-Dist: python-dateutil==2.9.*
17
+ Requires-Dist: cryptography>=43.0.0
17
18
 
18
19
  # mbu-dev-shared-components
19
20
 
@@ -75,3 +76,13 @@ converting lists associated with keys in a JSON object into dictionaries.
75
76
 
76
77
  - Transform all lists
77
78
  - Insert key value pairs
79
+
80
+
81
+ #### - Fernet Encryptor
82
+ This module provides a class for encrypting and decrypting data using the
83
+ Fernet symmetric encryption algorithm.
84
+
85
+ - Encrypts
86
+ - Decrypts
87
+
88
+
@@ -58,3 +58,13 @@ converting lists associated with keys in a JSON object into dictionaries.
58
58
 
59
59
  - Transform all lists
60
60
  - Insert key value pairs
61
+
62
+
63
+ #### - Fernet Encryptor
64
+ This module provides a class for encrypting and decrypting data using the
65
+ Fernet symmetric encryption algorithm.
66
+
67
+ - Encrypts
68
+ - Decrypts
69
+
70
+
@@ -46,7 +46,38 @@ def mark_file_as_case_record(documents_id: list, api_endpoint: str, api_username
46
46
  """
47
47
  headers = {'Content-Type': 'application/json'}
48
48
  payload = {"DocumentIds": documents_id}
49
- print(payload)
49
+
50
+ response = requests.request(method='POST', url=api_endpoint, headers=headers, json=payload, auth=get_ntlm_go_api_credentials(api_username, api_password), timeout=60)
51
+ response.raise_for_status()
52
+
53
+ return response
54
+
55
+
56
+ def finalize_file(documents_id: list, api_endpoint: str, api_username: str, api_password: str) -> requests.Response:
57
+ """
58
+ Marks one or more documents by their IDs as finalized in the system via a POST request to a specific API endpoint.
59
+ This operation modifies the status of the documents to reflect their new role as finalized case records.
60
+ The function constructs the JSON payload by encapsulating the document IDs within a list under the 'DocumentIds' key.
61
+
62
+ Parameters:
63
+ documents_id (list): A list of integers representing document IDs that should be marked as case records.
64
+ api_endpoint (str): GetOrganized API endpoint.
65
+ api_username (str): The API username for GetOrganized API.
66
+ api_password (str): The API password for GetOrganized API.
67
+
68
+ Returns:
69
+ Dict[str, Any]: The JSON response from the API, which includes the status of the operation and potentially updated document details.
70
+
71
+ Raises:
72
+ requests.RequestException: If the HTTP request fails for any reason.
73
+ """
74
+ headers = {'Content-Type': 'application/json'}
75
+ payload = {
76
+ "DocumentIds": documents_id,
77
+ "ShouldCloseOpenTasks": False
78
+ }
79
+
50
80
  response = requests.request(method='POST', url=api_endpoint, headers=headers, json=payload, auth=get_ntlm_go_api_credentials(api_username, api_password), timeout=60)
81
+ response.raise_for_status()
51
82
 
52
83
  return response
@@ -0,0 +1,159 @@
1
+ """
2
+ This module defines a Sharepoint class that facilitates interactions with a SharePoint site.
3
+ It provides methods for authenticating with the site, listing files in a specified document
4
+ library folder, downloading files, and saving them to a local directory. The class is designed
5
+ to encapsulate all necessary functionalities for handling files on a SharePoint site, making it
6
+ suitable for scripts or applications that require automated access to SharePoint resources.
7
+
8
+ The Sharepoint class uses the SharePlum library to communicate with SharePoint, handling common
9
+ tasks such as authentication, file retrieval, and file management. This includes methods to
10
+ authenticate users, fetch file lists from specific library folders, download individual files,
11
+ and save them locally. The class is initialized with user credentials and site details, which
12
+ are used throughout the class to manage SharePoint interactions.
13
+
14
+ Usage:
15
+ After creating an instance of the Sharepoint class with the necessary credentials and site details,
16
+ users can call methods to list files in a folder, download a specific file, or retrieve and save
17
+ all files from a folder to a local directory. This makes it easy to integrate SharePoint file
18
+ management into automated workflows or systems.
19
+
20
+ Example:
21
+ sharepoint_details = {
22
+ "username": "john@do.e",
23
+ "password": "johndoe",
24
+ "site_url": "https://site_url",
25
+ "site_name": "department123",
26
+ "document_library": "Shared documents"
27
+ }
28
+ sp = Sharepoint(**sharepoint_details)
29
+ sp.download_files("FolderName", "C:\\LocalPath")
30
+ """
31
+
32
+ from pathlib import PurePath
33
+ from typing import Optional
34
+ from shareplum import Site, Office365
35
+ from shareplum.site import Version
36
+
37
+
38
+ class Sharepoint:
39
+ """
40
+ A class to interact with a SharePoint site, enabling authentication, file listing,
41
+ downloading, and saving functionalities within a specified SharePoint document library.
42
+
43
+ Attributes:
44
+ username (str): Username for authentication.
45
+ password (str): Password for authentication.
46
+ site_url (str): URL of the SharePoint site.
47
+ site_name (str): Name of the SharePoint site.
48
+ document_library (str): Document library path.
49
+ """
50
+
51
+ def __init__(self, username: str, password: str, site_url: str, site_name: str, document_library: str):
52
+ """Initializes the Sharepoint class with credentials and site details."""
53
+ self.username = username
54
+ self.password = password
55
+ self.site_url = site_url
56
+ self.site_name = site_name
57
+ self.document_library = document_library
58
+ self.site = self._auth()
59
+
60
+ def _auth(self) -> Optional[Site]:
61
+ """
62
+ Authenticates to the SharePoint site and returns the site object.
63
+
64
+ Returns:
65
+ Optional[Site]: A SharePlum Site object for interacting with the SharePoint site if authentication is successful,
66
+ otherwise None.
67
+ """
68
+ try:
69
+ authcookie = Office365(self.site_url, username=self.username, password=self.password).GetCookies()
70
+ site = Site(f'{self.site_url}/sites/{self.site_name}', version=Version.v365, authcookie=authcookie)
71
+ return site
72
+ except Exception as e:
73
+ print(f"Failed to authenticate: {e}")
74
+ return None
75
+
76
+ def fetch_files_list(self, folder_name: str) -> Optional[list]:
77
+ """
78
+ Retrieves a list of files from a specified folder within the document library.
79
+
80
+ Args:
81
+ folder_name (str): The name of the folder within the document library.
82
+
83
+ Returns:
84
+ list: A list of file dictionaries in the specified folder, or an empty list if an error occurs or if the site is not authenticated.
85
+ """
86
+ if self.site:
87
+ try:
88
+ folder = self.site.Folder(f'{self.document_library}/{folder_name}')
89
+ files = folder.files
90
+ return files
91
+ except Exception as e:
92
+ print(f"Error retrieving files: {e}")
93
+ return None
94
+ return None
95
+
96
+ def fetch_file_content(self, file_name: str, folder_name: str) -> Optional[bytes]:
97
+ """
98
+ Downloads a file from a specified folder within the document library.
99
+
100
+ Args:
101
+ file_name (str): The name of the file to be downloaded.
102
+ folder_name (str): The name of the folder where the file is located.
103
+
104
+ Returns:
105
+ bytes (Optional): The binary content of the file if successful, otherwise None.
106
+ """
107
+ if self.site:
108
+ try:
109
+ folder = self.site.Folder(f'{self.document_library}/{folder_name}')
110
+ file_content = folder.get_file(file_name)
111
+ return file_content
112
+ except Exception as e:
113
+ print(f"Failed to download file: {e}")
114
+ return None
115
+ return None
116
+
117
+ def _write_file(self, folder_destination: str, file_name: str, file_content: bytes):
118
+ """
119
+ Saves the binary content of a file to a specified local destination.
120
+
121
+ Args:
122
+ folder_destination (str): The local folder path where the file will be saved.
123
+ file_name (str): The name of the file to be saved.
124
+ file_content (bytes): The binary content of the file.
125
+ """
126
+ file_directory_path = PurePath(folder_destination, file_name)
127
+ with open(file_directory_path, 'wb') as file:
128
+ file.write(file_content)
129
+
130
+ def download_file(self, folder: str, filename: str, folder_destination: str):
131
+ """
132
+ Downloads a specified file from a specified folder and saves it to a local destination.
133
+
134
+ Args:
135
+ folder (str): The name of the folder in the document library containing the file.
136
+ filename (str): The name of the file to download.
137
+ folder_destination (str): The local folder path where the downloaded file will be saved.
138
+ """
139
+ file_content = self.fetch_file_content(filename, folder)
140
+ if file_content:
141
+ self._write_file(folder_destination, filename, file_content)
142
+ else:
143
+ print(f"Failed to download {filename}")
144
+
145
+ def download_files(self, folder: str, folder_destination: str):
146
+ """
147
+ Downloads all files from a specified folder and saves them to a local destination.
148
+
149
+ Args:
150
+ folder (str): The name of the folder in the document library containing the files.
151
+ folder_destination (str): The local folder path where the downloaded files will be saved.
152
+ """
153
+ files_list = self.fetch_files_list(folder)
154
+ for file in files_list:
155
+ file_content = self.fetch_file_content(file['Name'], folder)
156
+ if file_content:
157
+ self._write_file(folder_destination, file['Name'], file_content)
158
+ else:
159
+ print(f"Failed to download {file['Name']}")
@@ -17,8 +17,8 @@ def download_file_bytes(url: str, os2_api_key: str) -> bytes:
17
17
  requests.RequestException: If the HTTP request fails for any reason.
18
18
  """
19
19
  headers = {
20
- 'Content-Type': 'application/json',
21
- 'api-key': f'{os2_api_key}'
20
+ 'Content-Type': 'application/json',
21
+ 'api-key': f'{os2_api_key}'
22
22
  }
23
23
  response = requests.request(method='GET', url=url, headers=headers, timeout=60)
24
24
  response.raise_for_status()
@@ -100,7 +100,6 @@ class InvoiceCreator:
100
100
  name_person: str,
101
101
  start_date: str,
102
102
  end_date: str,
103
- institution_number: str,
104
103
  main_transaction_id: str,
105
104
  main_transaction_amount: str,
106
105
  sub_transaction_id: str,
@@ -128,8 +127,6 @@ class InvoiceCreator:
128
127
  Start date of the transaction period.
129
128
  end_date : str
130
129
  End date of the transaction period.
131
- institution_number : str
132
- Institution number.
133
130
  main_transaction_id : str
134
131
  ID of the main transaction.
135
132
  main_transaction_amount : str
@@ -32,7 +32,7 @@ def execute_stored_procedure(connection_string: str, stored_procedure: str, para
32
32
  "str": str,
33
33
  "int": int,
34
34
  "float": float,
35
- "datetime": lambda x: parser.isoparse(x),
35
+ "datetime": parser.isoparse,
36
36
  "json": lambda x: json.dumps(x, ensure_ascii=False)
37
37
  }
38
38
 
@@ -0,0 +1,65 @@
1
+ """
2
+ This module provides a class for encrypting and decrypting data using the
3
+ Fernet symmetric encryption algorithm.
4
+ """
5
+
6
+ import os
7
+ import base64
8
+ import hashlib
9
+ from cryptography.fernet import Fernet
10
+
11
+
12
+ class Encryptor:
13
+ """
14
+ A class for encrypting and decrypting data using the Fernet symmetric encryption algorithm.
15
+ """
16
+
17
+ def __init__(self):
18
+ self.key = os.getenv("OpenOrchestratorKey")
19
+ if not self.key:
20
+ raise ValueError("Environment variable 'OpenOrchestratorKey' is not set or is empty.")
21
+ self.cipher_suite = self.generate_cipher_suite()
22
+
23
+ def generate_cipher_suite(self) -> Fernet:
24
+ """
25
+ Generates a Fernet cipher suite using a SHA-256 hash of the provided key.
26
+
27
+ Returns:
28
+ Fernet: An instance of the Fernet cipher suite.
29
+ """
30
+ hashed_key = hashlib.sha256(self.key.encode()).digest()
31
+ base64_key = base64.urlsafe_b64encode(hashed_key[:32])
32
+ return Fernet(base64_key)
33
+
34
+ def encrypt(self, data: str) -> bytes:
35
+ """
36
+ Encrypts a string.
37
+
38
+ Args:
39
+ data (str): The string to be encrypted.
40
+
41
+ Returns:
42
+ bytes: The encrypted data.
43
+ """
44
+ if not isinstance(data, str):
45
+ raise TypeError("Data must be a string.")
46
+ encrypted_data = self.cipher_suite.encrypt(data.encode())
47
+ return encrypted_data
48
+
49
+ def decrypt(self, cipherdata: bytes) -> str:
50
+ """
51
+ Decrypts data that was encrypted.
52
+
53
+ Args:
54
+ cipherdata (bytes): The data to be decrypted.
55
+
56
+ Returns:
57
+ str: The decrypted plaintext string.
58
+ """
59
+ if not isinstance(cipherdata, bytes):
60
+ raise TypeError("Cipherdata must be bytes.")
61
+ try:
62
+ decrypted_data = self.cipher_suite.decrypt(cipherdata).decode()
63
+ return decrypted_data
64
+ except Exception as e:
65
+ raise ValueError("Decryption failed. Ensure the cipherdata is valid.") from e
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mbu_dev_shared_components
3
- Version: 0.0.48
3
+ Version: 0.0.50
4
4
  Summary: Shared components to use in RPA projects
5
5
  Author-email: MBU <rpa@mbu.aarhus.dk>
6
6
  Classifier: Programming Language :: Python :: 3
@@ -9,11 +9,12 @@ Classifier: Operating System :: Microsoft :: Windows
9
9
  Requires-Python: >=3.7
10
10
  Description-Content-Type: text/markdown
11
11
  License-File: LICENSE
12
- Requires-Dist: Office365-REST-Python-Client>=2.5.9
12
+ Requires-Dist: shareplum
13
13
  Requires-Dist: openpyxl>=3.1.2
14
14
  Requires-Dist: pyodbc>=5.1.0
15
15
  Requires-Dist: requests_ntlm>=1.2.0
16
16
  Requires-Dist: python-dateutil==2.9.*
17
+ Requires-Dist: cryptography>=43.0.0
17
18
 
18
19
  # mbu-dev-shared-components
19
20
 
@@ -75,3 +76,13 @@ converting lists associated with keys in a JSON object into dictionaries.
75
76
 
76
77
  - Transform all lists
77
78
  - Insert key value pairs
79
+
80
+
81
+ #### - Fernet Encryptor
82
+ This module provides a class for encrypting and decrypting data using the
83
+ Fernet symmetric encryption algorithm.
84
+
85
+ - Encrypts
86
+ - Decrypts
87
+
88
+
@@ -1,7 +1,9 @@
1
1
  .gitignore
2
+ .pylintrc
2
3
  LICENSE
3
4
  README.md
4
5
  pyproject.toml
6
+ .github/workflows/pylint.yml
5
7
  mbu_dev_shared_components.egg-info/PKG-INFO
6
8
  mbu_dev_shared_components.egg-info/SOURCES.txt
7
9
  mbu_dev_shared_components.egg-info/dependency_links.txt
@@ -30,4 +32,5 @@ mbu_dev_shared_components/sap/__init__.py
30
32
  mbu_dev_shared_components/sap/create_invoice.py
31
33
  mbu_dev_shared_components/utils/__init__.py
32
34
  mbu_dev_shared_components/utils/db_stored_procedure_executor.py
35
+ mbu_dev_shared_components/utils/fernet_encryptor.py
33
36
  mbu_dev_shared_components/utils/json_handler.py
@@ -1,5 +1,6 @@
1
- Office365-REST-Python-Client>=2.5.9
1
+ shareplum
2
2
  openpyxl>=3.1.2
3
3
  pyodbc>=5.1.0
4
4
  requests_ntlm>=1.2.0
5
5
  python-dateutil==2.9.*
6
+ cryptography>=43.0.0
@@ -17,11 +17,12 @@ classifiers = [
17
17
  "Operating System :: Microsoft :: Windows",
18
18
  ]
19
19
  dependencies = [
20
- "Office365-REST-Python-Client >= 2.5.9",
20
+ "shareplum",
21
21
  "openpyxl >= 3.1.2",
22
22
  "pyodbc >= 5.1.0",
23
23
  "requests_ntlm >= 1.2.0",
24
- "python-dateutil == 2.9.*"
24
+ "python-dateutil == 2.9.*",
25
+ "cryptography >= 43.0.0"
25
26
  ]
26
27
 
27
28
  [tool.setuptools_scm]
@@ -1,191 +0,0 @@
1
- """This module defines a Sharepoint class that facilitates interactions with a SharePoint site.
2
- It provides methods for authenticating with the site, listing files in a specified document
3
- library folder, downloading files, and saving them to a local directory. The class is designed
4
- to encapsulate all necessary functionalities for handling files on a SharePoint site, making it
5
- suitable for scripts or applications that require automated access to SharePoint resources.
6
-
7
- The Sharepoint class uses the Office365-REST-Python-Client library to communicate with SharePoint,
8
- handling common tasks such as authentication, file retrieval, and file management. This includes
9
- methods to authenticate users, fetch file lists from specific library folders, download individual
10
- files, and save them locally. The class is initialized with user credentials and site details, which
11
- are used throughout the class to manage SharePoint interactions.
12
-
13
- Usage:
14
- After creating an instance of the Sharepoint class with the necessary credentials and site details,
15
- users can call methods to list files in a folder, download a specific file, or retrieve and save
16
- all files from a folder to a local directory. This makes it easy to integrate SharePoint file
17
- management into automated workflows or systems.
18
-
19
- Example:
20
- sharepoint_details = {
21
- "username": "john@do.e",
22
- "password": "johndoe",
23
- "site_url": "https://site_url",
24
- "site_name": "department123",
25
- "document_library": "Shared documents"
26
- }
27
- sp = Sharepoint(**sharepoint_details)
28
- sp.get_files(sp, "FolderName", "C:\\LocalPath")
29
-
30
- This module requires the `office365.sharepoint.client_context`, `office365.runtime.auth.user_credential`,
31
- and `office365.sharepoint.files.file` modules from Office365-REST-Python-Client.
32
- """
33
- from pathlib import PurePath
34
- from office365.sharepoint.client_context import ClientContext
35
- from office365.runtime.auth.user_credential import UserCredential
36
- from office365.sharepoint.files.file import File
37
-
38
-
39
- class Sharepoint:
40
- """
41
- A class to interact with a SharePoint site, enabling authentication, file listing,
42
- downloading, and saving functionalities within a specified SharePoint document library.
43
-
44
- Attributes:
45
- username (str): Username for authentication.
46
- password (str): Password for authentication.
47
- site_url (str): URL of the SharePoint site.
48
- site_name (str): Name of the site.
49
- document_library (str): Document library path.
50
- """
51
- def __init__(self, username: str, password, site_url, site_name, document_library):
52
- """Initializes the Sharepoint class with credentials and site details.
53
- """
54
- self.username = username
55
- self.password = password
56
- self.site_url = site_url
57
- self.site_name = site_name
58
- self.document_library = document_library
59
-
60
- def _auth(self):
61
- """
62
- Authenticates to the SharePoint site and returns the client context.
63
- """
64
- try:
65
- conn = ClientContext(self.site_url).with_credentials(
66
- UserCredential(self.username, self.password)
67
- )
68
- return conn
69
- except Exception as e:
70
- print(f"Failed to authenticate: {e}")
71
- return None
72
-
73
- def fetch_files_list(self, folder_name: str) -> list:
74
- """
75
- Retrieve a list of files from a specified folder within the document library.
76
-
77
- This method authenticates the user and constructs the URL to the target folder using
78
- the document library and folder name. It then attempts to retrieve and return the list
79
- of files in the folder. If any errors occur during the process, an error message is
80
- printed and an empty list is returned.
81
-
82
- Args:
83
- folder_name (str): The name of the folder within the document library from which to retrieve files.
84
-
85
- Returns:
86
- list: A list of file objects in the specified folder if the retrieval is successful, otherwise an empty list.
87
- """
88
- conn = self._auth()
89
- if conn:
90
- try:
91
- target_folder_url = f'{self.document_library}/{folder_name}'
92
- root_folder = conn.web.get_folder_by_server_relative_url(target_folder_url)
93
- root_folder.expand(["Files", "Folders"]).get().execute_query()
94
- return root_folder.files
95
- except Exception as e:
96
- print(f"Error retrieving files: {e}")
97
- return []
98
- return []
99
-
100
- def fetch_file_content(self, file_name: str, folder_name: str) -> bytes:
101
- """
102
- Download a file from a specified folder within the document library of the current site.
103
-
104
- This method authenticates the user, constructs the URL to the file using the site name,
105
- document library, folder name, and file name. It then attempts to open and download
106
- the file as binary. If successful, the binary content of the file is returned. If
107
- any errors occur during the download process, an error message is printed and the
108
- method returns None.
109
-
110
- Args:
111
- file_name (str): The name of the file to be downloaded.
112
- folder_name (str): The folder name where the file is stored.
113
-
114
- Returns:
115
- bytes: The binary content of the file if the download is successful, otherwise None.
116
- """
117
- conn = self._auth()
118
- if conn:
119
- try:
120
- file_url = f'/sites/{self.site_name}/{self.document_library}/{folder_name}/{file_name}'
121
- file_binary = File.open_binary(conn, file_url)
122
- return file_binary.content
123
- except Exception as e:
124
- print(f"Failed to download file: {e}")
125
- return None
126
-
127
- def _write_file(self, folder_destination: str, file_name: str, file_content: bytes) -> None:
128
- """
129
- Save the binary content of a file to a specified local destination.
130
-
131
- This method takes the binary content of a file and writes it to a file in the specified
132
- local destination folder. The full path to the file is constructed using the destination
133
- folder and the file name.
134
-
135
- Args:
136
- folder_destination (str): The local folder path where the file will be saved.
137
- file_name (str): The name of the file to be saved.
138
- file_content (bytes): The binary content of the file to be written to disk.
139
-
140
- Returns:
141
- None
142
- """
143
- file_directory_path = PurePath(folder_destination, file_name)
144
- with open(file_directory_path, 'wb') as file:
145
- file.write(file_content)
146
-
147
- def download_file(self, folder: str, filename: str, folder_destination: str) -> None:
148
- """
149
- Download a specified file from a specified folder and save it to a local destination.
150
-
151
- This method retrieves the specified file from the folder in the document library,
152
- attempts to download it, and saves it to the specified local destination folder.
153
- If the file cannot be downloaded, an error message is printed.
154
-
155
- Args:
156
- folder (str): The name of the folder in the document library from which to download the file.
157
- filename (str): The name of the file to download.
158
- folder_destination (str): The local folder path where the downloaded file will be saved.
159
-
160
- Returns:
161
- None
162
- """
163
- file_content = self.fetch_file_content(filename, folder)
164
- if file_content:
165
- self._write_file(folder_destination, filename, file_content)
166
- else:
167
- print(f"Failed to download {filename}")
168
-
169
- def download_files(self, folder: str, folder_destination: str) -> None:
170
- """
171
- Download all files from a specified folder and save them to a local destination.
172
-
173
- This method retrieves a list of files from the specified folder in the document library,
174
- attempts to download each file, and saves it to the specified local destination folder.
175
- If a file cannot be downloaded, an error message is printed, but the process continues
176
- with the next file.
177
-
178
- Args:
179
- folder (str): The name of the folder in the document library from which to download files.
180
- folder_destination (str): The local folder path where the downloaded files will be saved.
181
-
182
- Returns:
183
- None
184
- """
185
- files_list = self.fetch_files_list(folder)
186
- for file in files_list:
187
- file_content = self.fetch_file_content(file.name, folder)
188
- if file_content:
189
- self._write_file(folder_destination, file.name, file_content)
190
- else:
191
- print(f"Failed to download {file.name}")