saviialib 0.10.1__py3-none-any.whl → 0.11.0__py3-none-any.whl

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.

Potentially problematic release.


This version of saviialib might be problematic. Click here for more details.

Files changed (23) hide show
  1. saviialib/general_types/api/epii_api_types.py +0 -2
  2. saviialib/general_types/error_types/api/epii_api_error_types.py +12 -0
  3. saviialib/libs/ftp_client/clients/aioftp_client.py +9 -5
  4. saviialib/libs/ftp_client/ftp_client.py +4 -4
  5. saviialib/libs/ftp_client/ftp_client_contract.py +2 -2
  6. saviialib/libs/sharepoint_client/clients/sharepoint_rest_api.py +3 -2
  7. saviialib/libs/sharepoint_client/sharepoint_client.py +21 -1
  8. saviialib/services/epii/api.py +21 -11
  9. saviialib/services/epii/controllers/types/update_thies_data_types.py +2 -0
  10. saviialib/services/epii/controllers/types/upload_backup_to_sharepoint_types.py +2 -0
  11. saviialib/services/epii/controllers/update_thies_data.py +12 -2
  12. saviialib/services/epii/controllers/upload_backup_to_sharepoint.py +3 -3
  13. saviialib/services/epii/use_cases/constants/upload_backup_to_sharepoint_constants.py +0 -1
  14. saviialib/services/epii/use_cases/types/update_thies_data_types.py +3 -1
  15. saviialib/services/epii/use_cases/types/upload_backup_to_sharepoint_types.py +1 -1
  16. saviialib/services/epii/use_cases/update_thies_data.py +63 -28
  17. saviialib/services/epii/use_cases/upload_backup_to_sharepoint.py +103 -85
  18. saviialib/services/epii/utils/upload_backup_to_sharepoint_utils.py +7 -5
  19. {saviialib-0.10.1.dist-info → saviialib-0.11.0.dist-info}/METADATA +1 -1
  20. {saviialib-0.10.1.dist-info → saviialib-0.11.0.dist-info}/RECORD +22 -23
  21. saviialib/services/epii/use_cases/constants/update_thies_data_constants.py +0 -5
  22. {saviialib-0.10.1.dist-info → saviialib-0.11.0.dist-info}/LICENSE +0 -0
  23. {saviialib-0.10.1.dist-info → saviialib-0.11.0.dist-info}/WHEEL +0 -0
@@ -80,6 +80,4 @@ class EpiiSharepointBackupConfig:
80
80
  sharepoint_tenant_id: str
81
81
  sharepoint_tenant_name: str
82
82
  sharepoint_site_name: str
83
- local_backup_source_path: str
84
- destination_folders: str
85
83
  logger: Logger
@@ -43,6 +43,18 @@ class SharePointFetchingError(Exception):
43
43
  return self.reason.__str__()
44
44
 
45
45
 
46
+ class SharePointDirectoryError(Exception):
47
+ def __init__(self, *args, reason):
48
+ super().__init__(*args, reason)
49
+ self.reason = reason
50
+
51
+ def __str__(self):
52
+ return (
53
+ "An error occurred while fetching the folders from Microsoft SharePoint. "
54
+ + self.reason.__str__()
55
+ )
56
+
57
+
46
58
  class SharePointUploadError(Exception):
47
59
  """Raised when there is an error uploading files to the Microsoft SharePoint folder."""
48
60
 
@@ -34,12 +34,16 @@ class AioFTPClient(FTPClientContract):
34
34
  )
35
35
 
36
36
  async def list_files(self, args: FtpListFilesArgs) -> list[str]:
37
- await self._async_start()
38
- return [
39
- path.name async for path, _ in self.client.list(args.path, recursive=False)
40
- ]
37
+ try:
38
+ await self._async_start()
39
+ return [
40
+ path.name
41
+ async for path, _ in self.client.list(args.path, recursive=False) # type: ignore
42
+ ]
43
+ except StatusCodeError as error:
44
+ raise ConnectionAbortedError(error)
41
45
 
42
46
  async def read_file(self, args: FtpReadFileArgs) -> bytes:
43
47
  await self._async_start()
44
- async with self.client.download_stream(args.file_path) as stream:
48
+ async with self.client.download_stream(args.file_path) as stream: # type: ignore
45
49
  return await stream.read()
@@ -15,8 +15,8 @@ class FTPClient(FTPClientContract):
15
15
  self.client_obj = AioFTPClient(args)
16
16
  self.client_name = args.client_name
17
17
 
18
- def list_files(self, args: FtpListFilesArgs) -> list[str]:
19
- return self.client_obj.list_files(args)
18
+ async def list_files(self, args: FtpListFilesArgs) -> list[str]:
19
+ return await self.client_obj.list_files(args)
20
20
 
21
- def read_file(self, args: FtpReadFileArgs) -> bytes:
22
- return self.client_obj.read_file(args)
21
+ async def read_file(self, args: FtpReadFileArgs) -> bytes:
22
+ return await self.client_obj.read_file(args)
@@ -5,9 +5,9 @@ from .types.ftp_client_types import FtpListFilesArgs, FtpReadFileArgs
5
5
 
6
6
  class FTPClientContract(ABC):
7
7
  @abstractmethod
8
- def list_files(self, args: FtpListFilesArgs) -> list[str]:
8
+ async def list_files(self, args: FtpListFilesArgs) -> list[str]:
9
9
  pass
10
10
 
11
11
  @abstractmethod
12
- def read_file(self, args: FtpReadFileArgs) -> bytes:
12
+ async def read_file(self, args: FtpReadFileArgs) -> bytes:
13
13
  pass
@@ -104,10 +104,11 @@ class SharepointRestAPI(SharepointClientContract):
104
104
  folder_relative_url = (
105
105
  f"GetFolderByServerRelativeUrl('{args.folder_relative_url}')"
106
106
  )
107
- endpoint = f"web/{folder_relative_url}/Folder"
107
+ endpoint = f"web/{folder_relative_url}/Folders"
108
108
  response = await self.session.get(endpoint.lstrip("/"))
109
109
  response.raise_for_status()
110
- return await response.json()
110
+ response_json = await response.json()
111
+ return response_json
111
112
  except ClientError as error:
112
113
  raise ConnectionError(error) from error
113
114
 
@@ -18,6 +18,26 @@ class SharepointClient(SharepointClientContract):
18
18
  elif args.client_name == "sharepoint_rest_api":
19
19
  self.client_obj = SharepointRestAPI(args)
20
20
 
21
+ @property
22
+ def tenant_id(self):
23
+ return self.client_obj.tenant_id
24
+
25
+ @property
26
+ def tenant_name(self):
27
+ return self.client_obj.tenant_name
28
+
29
+ @property
30
+ def site_name(self):
31
+ return self.client_obj.site_name
32
+
33
+ @property
34
+ def client_id(self):
35
+ return self.client_obj.client_id
36
+
37
+ @property
38
+ def client_secret(self):
39
+ return self.client_obj.client_secret
40
+
21
41
  async def __aenter__(self):
22
42
  return await self.client_obj.__aenter__()
23
43
 
@@ -28,7 +48,7 @@ class SharepointClient(SharepointClientContract):
28
48
  return await self.client_obj.list_files(args)
29
49
 
30
50
  async def list_folders(self, args: SpListFoldersArgs) -> list:
31
- return await self.client_obj.list_files(args)
51
+ return await self.client_obj.list_folders(args)
32
52
 
33
53
  async def upload_file(self, args: SpUploadFileArgs) -> dict:
34
54
  return await self.client_obj.upload_file(args)
@@ -1,4 +1,4 @@
1
- from typing import Any, Dict
1
+ from typing import Any, Dict, List
2
2
 
3
3
  from .controllers.types.update_thies_data_types import UpdateThiesDataControllerInput
4
4
  from .controllers.types.upload_backup_to_sharepoint_types import (
@@ -28,15 +28,21 @@ class EpiiAPI:
28
28
  self.sharepoint_tenant_id = config.sharepoint_tenant_id
29
29
  self.sharepoint_tenant_name = config.sharepoint_tenant_name
30
30
  self.sharepoint_site_name = config.sharepoint_site_name
31
+
31
32
  self.logger = config.logger
32
33
 
33
- async def update_thies_data(self) -> Dict[str, Any]:
34
- """
35
- This method establishes a connection to an FTP server using the provided
36
- credentials and updates data related to THIES Data Logger.
34
+ async def update_thies_data(
35
+ self, sharepoint_folders_path: List[str], ftp_server_folders_path: List[str]
36
+ ) -> Dict[str, Any]:
37
+ """Updates data from a THIES Data Logger by connecting to an FTP server
38
+ and transferring data to specified Sharepoint folders.
39
+
40
+ Args:
41
+ sharepoint_folders_path (list): List of Sharepoint folder paths for AVG and EXT data.
42
+ ftp_server_folders_path (list): List of FTP server folder paths for AVG and EXT data.
37
43
 
38
44
  Returns:
39
- response (dict): A dictionary representation of the API response.
45
+ dict: A dictionary representation of the API response.
40
46
  """
41
47
  config = EpiiUpdateThiesConfig(
42
48
  ftp_port=self.ftp_port,
@@ -49,12 +55,16 @@ class EpiiAPI:
49
55
  sharepoint_tenant_id=self.sharepoint_tenant_id,
50
56
  sharepoint_tenant_name=self.sharepoint_tenant_name,
51
57
  )
52
- controller = UpdateThiesDataController(UpdateThiesDataControllerInput(config))
58
+ controller = UpdateThiesDataController(
59
+ UpdateThiesDataControllerInput(
60
+ config, sharepoint_folders_path, ftp_server_folders_path
61
+ )
62
+ )
53
63
  response = await controller.execute()
54
64
  return response.__dict__
55
65
 
56
66
  async def upload_backup_to_sharepoint(
57
- self, local_backup_source_path: str, destination_folders: dict[str, str]
67
+ self, local_backup_source_path: str, sharepoint_destination_path: str
58
68
  ) -> Dict[str, Any]:
59
69
  """Migrate a backup folder from Home assistant to Sharepoint directory.
60
70
  Args:
@@ -70,13 +80,13 @@ class EpiiAPI:
70
80
  sharepoint_site_name=self.sharepoint_site_name,
71
81
  sharepoint_tenant_id=self.sharepoint_tenant_id,
72
82
  sharepoint_tenant_name=self.sharepoint_tenant_name,
73
- local_backup_source_path=local_backup_source_path,
74
- destination_folders=destination_folders,
75
83
  logger=self.logger,
76
84
  )
77
85
 
78
86
  controller = UploadBackupToSharepointController(
79
- UploadBackupToSharepointControllerInput(config)
87
+ UploadBackupToSharepointControllerInput(
88
+ config, local_backup_source_path, sharepoint_destination_path
89
+ )
80
90
  )
81
91
  response = await controller.execute()
82
92
  return response.__dict__
@@ -8,6 +8,8 @@ from saviialib.general_types.api.epii_api_types import (
8
8
  @dataclass
9
9
  class UpdateThiesDataControllerInput:
10
10
  config: EpiiUpdateThiesConfig
11
+ sharepoint_folders_path: list
12
+ ftp_server_folders_path: list
11
13
 
12
14
 
13
15
  @dataclass
@@ -7,6 +7,8 @@ from saviialib.general_types.api.epii_api_types import EpiiSharepointBackupConfi
7
7
  @dataclass
8
8
  class UploadBackupToSharepointControllerInput:
9
9
  config: EpiiSharepointBackupConfig
10
+ local_backup_source_path: str
11
+ sharepoint_destination_path: str
10
12
 
11
13
 
12
14
  @dataclass
@@ -5,6 +5,7 @@ from saviialib.general_types.error_types.api.epii_api_error_types import (
5
5
  ThiesConnectionError,
6
6
  ThiesFetchingError,
7
7
  SharePointUploadError,
8
+ SharePointDirectoryError,
8
9
  )
9
10
  from saviialib.general_types.error_types.common.common_types import (
10
11
  EmptyDataError,
@@ -42,6 +43,8 @@ class UpdateThiesDataController:
42
43
  sharepoint_tenant_name=input.config.sharepoint_tenant_name,
43
44
  sharepoint_tenant_id=input.config.sharepoint_tenant_id,
44
45
  ),
46
+ sharepoint_folders_path=input.sharepoint_folders_path,
47
+ ftp_server_folders_path=input.ftp_server_folders_path,
45
48
  )
46
49
  )
47
50
 
@@ -51,7 +54,7 @@ class UpdateThiesDataController:
51
54
  return UpdateThiesDataControllerOutput(
52
55
  message="THIES was synced successfully",
53
56
  status=HTTPStatus.OK.value,
54
- metadata={"data": data},
57
+ metadata={"data": data}, # type: ignore
55
58
  )
56
59
  except EmptyDataError:
57
60
  return UpdateThiesDataControllerOutput(
@@ -87,7 +90,14 @@ class UpdateThiesDataController:
87
90
 
88
91
  except SharePointUploadError as error:
89
92
  return UpdateThiesDataControllerOutput(
90
- message="An error oucrred while uploading files to RCER Cloud",
93
+ message="An error ocurred while uploading files to RCER Cloud",
94
+ status=HTTPStatus.BAD_REQUEST.value,
95
+ metadata={"error": error.__str__()},
96
+ )
97
+
98
+ except SharePointDirectoryError as error:
99
+ return UpdateThiesDataControllerOutput(
100
+ message="An error ocurred while extracting folders from Microsoft Sharepoint",
91
101
  status=HTTPStatus.BAD_REQUEST.value,
92
102
  metadata={"error": error.__str__()},
93
103
  )
@@ -33,8 +33,8 @@ class UploadBackupToSharepointController:
33
33
  sharepoint_tenant_name=input.config.sharepoint_tenant_name,
34
34
  sharepoint_tenant_id=input.config.sharepoint_tenant_id,
35
35
  ),
36
- local_backup_source_path=input.config.local_backup_source_path,
37
- destination_folders=input.config.destination_folders,
36
+ local_backup_source_path=input.local_backup_source_path,
37
+ sharepoint_destination_path=input.sharepoint_destination_path,
38
38
  logger=input.config.logger,
39
39
  )
40
40
  )
@@ -45,7 +45,7 @@ class UploadBackupToSharepointController:
45
45
  return UploadBackupToSharepointControllerOutput(
46
46
  message="Local backup was migrated successfully",
47
47
  status=HTTPStatus.OK.value,
48
- metadata={"data": data},
48
+ metadata={"data": data}, # type: ignore
49
49
  )
50
50
  except EmptyDataError:
51
51
  return UploadBackupToSharepointControllerOutput(
@@ -1,6 +1,5 @@
1
1
  import logging
2
2
 
3
- SHAREPOINT_BASE_URL = "/sites/uc365_CentrosyEstacionesRegionalesUC/Shared%20Documents/General/Test_Raspberry"
4
3
 
5
4
  logging.basicConfig(level=logging.DEBUG)
6
5
  LOGGER = logging.getLogger(__package__)
@@ -1,5 +1,5 @@
1
1
  from dataclasses import dataclass, field
2
- from typing import Dict
2
+ from typing import Dict, List
3
3
  from saviialib.general_types.api.epii_api_types import FtpClientConfig, SharepointConfig
4
4
 
5
5
 
@@ -7,6 +7,8 @@ from saviialib.general_types.api.epii_api_types import FtpClientConfig, Sharepoi
7
7
  class UpdateThiesDataUseCaseInput:
8
8
  ftp_config: FtpClientConfig
9
9
  sharepoint_config: SharepointConfig
10
+ sharepoint_folders_path: List
11
+ ftp_server_folders_path: List
10
12
 
11
13
 
12
14
  @dataclass
@@ -7,5 +7,5 @@ from logging import Logger
7
7
  class UploadBackupToSharepointUseCaseInput:
8
8
  sharepoint_config: SharepointConfig
9
9
  local_backup_source_path: str
10
- destination_folders: dict
10
+ sharepoint_destination_path: str
11
11
  logger: Logger
@@ -1,6 +1,6 @@
1
- import saviialib.services.epii.use_cases.constants.update_thies_data_constants as c
2
1
  from saviialib.general_types.error_types.api.epii_api_error_types import (
3
2
  SharePointFetchingError,
3
+ SharePointDirectoryError,
4
4
  SharePointUploadError,
5
5
  ThiesConnectionError,
6
6
  ThiesFetchingError,
@@ -20,6 +20,7 @@ from saviialib.libs.sharepoint_client import (
20
20
  SharepointClient,
21
21
  SharepointClientInitArgs,
22
22
  SpListFilesArgs,
23
+ SpListFoldersArgs,
23
24
  SpUploadFileArgs,
24
25
  )
25
26
  from saviialib.services.epii.use_cases.types import (
@@ -38,6 +39,9 @@ class UpdateThiesDataUseCase:
38
39
  input.sharepoint_config
39
40
  )
40
41
  self.thies_ftp_client = self._initialize_thies_ftp_client(input.ftp_config)
42
+ self.sharepoint_folders_path = input.sharepoint_folders_path
43
+ self.ftp_server_folders_path = input.ftp_server_folders_path
44
+ self.sharepoint_base_url = f"/sites/{self.sharepoint_client.site_name}"
41
45
  self.uploading = set()
42
46
 
43
47
  def _initialize_sharepoint_client(
@@ -58,36 +62,56 @@ class UpdateThiesDataUseCase:
58
62
  except RuntimeError as error:
59
63
  raise FtpClientError(error)
60
64
 
65
+ async def _validate_sharepoint_current_folders(self):
66
+ async with self.sharepoint_client:
67
+ folder_base_path = "/".join(
68
+ self.sharepoint_folders_path[0].split("/")[0:-1]
69
+ )
70
+ relative_url = f"{self.sharepoint_base_url}/{folder_base_path}"
71
+ response = await self.sharepoint_client.list_folders(
72
+ SpListFoldersArgs(relative_url)
73
+ )
74
+
75
+ current_folders = [item["Name"] for item in response["value"]] # type: ignore
76
+
77
+ for folder_path in self.sharepoint_folders_path:
78
+ folder_name = folder_path.split("/")[-1]
79
+ if folder_name not in current_folders:
80
+ raise SharePointDirectoryError(
81
+ reason=f"The current folder '{folder_name}' doesn't exist."
82
+ )
83
+
61
84
  async def fetch_cloud_file_names(self) -> set[str]:
62
85
  """Fetch file names from the RCER cloud."""
63
-
86
+ await self._validate_sharepoint_current_folders()
64
87
  try:
65
88
  cloud_files = set()
66
89
  async with self.sharepoint_client:
67
- for folder in c.SHAREPOINT_THIES_FOLDERS:
68
- args = SpListFilesArgs(
69
- folder_relative_url=f"{c.SHAREPOINT_BASE_URL}/{folder}"
70
- )
90
+ for folder_path in self.sharepoint_folders_path:
91
+ folder_name = folder_path.split("/")[-1]
92
+ relative_url = f"{self.sharepoint_base_url}/{folder_path}"
93
+ args = SpListFilesArgs(folder_relative_url=relative_url)
71
94
  response = await self.sharepoint_client.list_files(args)
72
95
  cloud_files.update(
73
- {f"{folder}_{item['Name']}" for item in response["value"]}
96
+ {f"{folder_name}_{item['Name']}" for item in response["value"]} # type: ignore
74
97
  )
75
98
  return cloud_files
76
- except ConnectionError as error:
99
+ except Exception as error:
77
100
  raise SharePointFetchingError(reason=error)
78
101
 
79
102
  async def fetch_thies_file_names(self) -> set[str]:
80
103
  """Fetch file names from the THIES FTP server."""
81
104
  try:
82
- avg_files = await self.thies_ftp_client.list_files(
83
- FtpListFilesArgs(path=c.FTP_SERVER_PATH_AVG_FILES)
84
- )
85
- ext_files = await self.thies_ftp_client.list_files(
86
- FtpListFilesArgs(path=c.FTP_SERVER_PATH_EXT_FILES)
87
- )
88
- return {f"AVG_{name}" for name in avg_files} | {
89
- f"EXT_{name}" for name in ext_files
90
- }
105
+ thies_files = set()
106
+ for folder_path in self.ftp_server_folders_path:
107
+ # AV for average, and EXT for extreme.
108
+ prefix = "AVG" if "AV" in folder_path else "EXT"
109
+ files = await self.thies_ftp_client.list_files(
110
+ FtpListFilesArgs(path=folder_path)
111
+ )
112
+ files_names = {f"{prefix}_{name}" for name in files}
113
+ thies_files.update(files_names)
114
+ return thies_files
91
115
  except ConnectionRefusedError as error:
92
116
  raise ThiesConnectionError(reason=error)
93
117
  except ConnectionAbortedError as error:
@@ -98,16 +122,19 @@ class UpdateThiesDataUseCase:
98
122
  try:
99
123
  content_files = {}
100
124
  for file in self.uploading:
101
- origin, filename = file.split("_", 1)
102
- file_path = (
103
- f"{c.FTP_SERVER_PATH_AVG_FILES}/{filename}"
104
- if origin == "AVG"
105
- else f"{c.FTP_SERVER_PATH_EXT_FILES}/{filename}"
125
+ _, filename = file.split("_", 1)
126
+ folder_path = (
127
+ self.ftp_server_folders_path[0]
128
+ if "AV" in self.ftp_server_folders_path[0] # Folder with AVG prefix
129
+ else self.ftp_server_folders_path[1] # Folder with EXT prefix
106
130
  )
131
+ file_path = f"{folder_path}/{filename}"
107
132
  content = await self.thies_ftp_client.read_file(
108
133
  FtpReadFileArgs(file_path)
109
134
  )
110
- content_files[file] = content # Save the file with its prefix
135
+ content_files[file] = (
136
+ content # Save file content with its original name.
137
+ )
111
138
  return content_files
112
139
  except ConnectionRefusedError as error:
113
140
  raise ThiesConnectionError(reason=error)
@@ -123,9 +150,16 @@ class UpdateThiesDataUseCase:
123
150
  async with self.sharepoint_client:
124
151
  for file, file_content in files.items():
125
152
  try:
126
- folder, file_name = file.split("_", 1)
153
+ _, file_name = file.split("_", 1)
154
+ # Could be AVG or EXT.
155
+ if file_name in self.sharepoint_folders_path[0]:
156
+ folder_path = self.sharepoint_folders_path[0]
157
+ else:
158
+ folder_path = self.sharepoint_folders_path[1]
159
+ relative_url = f"{self.sharepoint_base_url}/{folder_path}"
160
+
127
161
  args = SpUploadFileArgs(
128
- folder_relative_url=f"{c.SHAREPOINT_BASE_URL}/{folder}",
162
+ folder_relative_url=relative_url,
129
163
  file_content=file_content,
130
164
  file_name=file_name,
131
165
  )
@@ -145,16 +179,17 @@ class UpdateThiesDataUseCase:
145
179
 
146
180
  return upload_results
147
181
 
148
- async def execute(self) -> dict:
182
+ async def execute(self):
149
183
  """Synchronize data from the THIES Center to the cloud."""
150
184
  try:
151
185
  thies_files = await self.fetch_thies_file_names()
152
186
  except RuntimeError as error:
153
187
  raise FtpClientError(error)
188
+
154
189
  try:
155
190
  cloud_files = await self.fetch_cloud_file_names()
156
191
  except RuntimeError as error:
157
- raise SharepointClient(error)
192
+ raise SharepointClient(error) # type: ignore
158
193
 
159
194
  self.uploading = thies_files - cloud_files
160
195
  if not self.uploading:
@@ -168,4 +203,4 @@ class UpdateThiesDataUseCase:
168
203
  thies_fetched_files
169
204
  )
170
205
 
171
- return parse_execute_response(thies_fetched_files, upload_statistics)
206
+ return parse_execute_response(thies_fetched_files, upload_statistics) # type: ignore
@@ -1,7 +1,6 @@
1
1
  import asyncio
2
2
  from time import time
3
3
  from logging import Logger
4
- import saviialib.services.epii.use_cases.constants.upload_backup_to_sharepoint_constants as c
5
4
  from saviialib.general_types.error_types.api.epii_api_error_types import (
6
5
  BackupEmptyError,
7
6
  BackupSourcePathError,
@@ -21,6 +20,7 @@ from saviialib.libs.sharepoint_client import (
21
20
  SharepointClient,
22
21
  SharepointClientInitArgs,
23
22
  SpUploadFileArgs,
23
+ SpListFoldersArgs,
24
24
  )
25
25
  from saviialib.services.epii.utils.upload_backup_to_sharepoint_utils import (
26
26
  calculate_percentage_uploaded,
@@ -39,13 +39,21 @@ class UploadBackupToSharepointUsecase:
39
39
  def __init__(self, input: UploadBackupToSharepointUseCaseInput):
40
40
  self.sharepoint_config = input.sharepoint_config
41
41
  self.local_backup_source_path = input.local_backup_source_path
42
- self.destination_folders = input.destination_folders
42
+ self.sharepoint_destination_path = input.sharepoint_destination_path
43
43
  self.files_client = self._initialize_files_client()
44
44
  self.dir_client = self._initialize_directory_client()
45
45
  self.log_history = []
46
46
  self.grouped_files_by_folder = None
47
47
  self.total_files = None
48
48
  self.logger: Logger = input.logger
49
+ self.sharepoint_client = self._initalize_sharepoint_client()
50
+
51
+ def _initalize_sharepoint_client(self):
52
+ return SharepointClient(
53
+ SharepointClientInitArgs(
54
+ self.sharepoint_config, client_name="sharepoint_rest_api"
55
+ )
56
+ )
49
57
 
50
58
  def _initialize_directory_client(self):
51
59
  return DirectoryClient(DirectoryClientArgs(client_name="os_client"))
@@ -53,7 +61,44 @@ class UploadBackupToSharepointUsecase:
53
61
  def _initialize_files_client(self):
54
62
  return FilesClient(FilesClientInitArgs(client_name="aiofiles_client"))
55
63
 
56
- async def _extract_filesnames_by_folder(self) -> dict[str, list[str]]:
64
+ async def _validate_backup_structure(self):
65
+ # Check if the local path exists in the main directory
66
+ if not await self.dir_client.path_exists(self.local_backup_source_path):
67
+ raise BackupSourcePathError(
68
+ reason=f"'{self.local_backup_source_path}' doesn't exist."
69
+ )
70
+
71
+ local_directories = (
72
+ list(self.grouped_files_by_folder.keys())
73
+ if self.grouped_files_by_folder
74
+ else []
75
+ )
76
+ async with self.sharepoint_client: # type: ignore
77
+ response = await self.sharepoint_client.list_folders(
78
+ SpListFoldersArgs(folder_relative_url=self.sharepoint_destination_path)
79
+ )
80
+ sharepoint_directories = [x["Name"] for x in response["value"]] # type: ignore
81
+
82
+ # Verify that all local directories exist in SharePoint
83
+ for local_dir in local_directories:
84
+ if local_dir not in sharepoint_directories:
85
+ error_message = f"Folder '{local_dir}' does not exist in SharePoint destination path '{self.sharepoint_destination_path}'."
86
+ self.log_history.append(error_message)
87
+ self.logger.error("[local_backup_lib] %s", error_message)
88
+ raise BackupSourcePathError(
89
+ reason=f"Folder '{local_dir}' does not exist in SharePoint destination path '{self.sharepoint_destination_path}'."
90
+ )
91
+
92
+ # Check if the current folder only have files and each folder exist in Microsoft Sharepoint.
93
+ if self.total_files == 0:
94
+ no_files_message = (
95
+ f"[local_backup_lib] {self.local_backup_source_path} has no files ⚠️"
96
+ )
97
+ self.log_history.append(no_files_message)
98
+ self.logger.debug(no_files_message)
99
+ raise BackupEmptyError
100
+
101
+ async def _group_files_by_folder(self) -> dict[str, list[str]]:
57
102
  """Groups files by their parent folder."""
58
103
  backup_folder_exists = await self.dir_client.path_exists(
59
104
  self.local_backup_source_path
@@ -62,17 +107,17 @@ class UploadBackupToSharepointUsecase:
62
107
  if not backup_folder_exists:
63
108
  return {}
64
109
  folder_names = await self.dir_client.listdir(self.local_backup_source_path)
65
- return {
66
- folder_name: [
67
- file_name
68
- for file_name in await self.dir_client.listdir(
69
- self.dir_client.join_paths(
70
- self.local_backup_source_path, folder_name
71
- )
72
- )
73
- ]
74
- for folder_name in folder_names
75
- }
110
+ grouped = {}
111
+ for folder_name in folder_names:
112
+ is_folder = await self.dir_client.isdir(
113
+ self.dir_client.join_paths(self.local_backup_source_path, folder_name)
114
+ )
115
+ if not is_folder:
116
+ continue
117
+ grouped[folder_name] = await self.dir_client.listdir(
118
+ self.dir_client.join_paths(self.local_backup_source_path, folder_name)
119
+ )
120
+ return grouped
76
121
 
77
122
  async def _save_log_history(self) -> None:
78
123
  await self.files_client.write(
@@ -83,6 +128,30 @@ class UploadBackupToSharepointUsecase:
83
128
  )
84
129
  )
85
130
 
131
+ async def _generate_tasks(self) -> list:
132
+ tasks = []
133
+ for folder_name in self.grouped_files_by_folder: # type: ignore
134
+ count_files_in_dir = await count_files_in_directory(
135
+ self.local_backup_source_path, folder_name
136
+ )
137
+ if count_files_in_dir == 0:
138
+ empty_folder_message = (
139
+ f"[local_backup_lib] The folder '{folder_name}' is empty ⚠️"
140
+ )
141
+ self.logger.debug(empty_folder_message)
142
+ self.log_history.append(empty_folder_message)
143
+ continue
144
+ extracting_files_message = (
145
+ "[local_backup_lib]"
146
+ + f" Extracting files from '{folder_name} ".center(15, "*")
147
+ )
148
+ self.log_history.append(extracting_files_message)
149
+ self.logger.debug(extracting_files_message)
150
+ for file_name in self.grouped_files_by_folder[folder_name]: # type: ignore
151
+ tasks.append(self._upload_and_log_progress_task(folder_name, file_name))
152
+
153
+ return tasks
154
+
86
155
  async def export_file_to_sharepoint(
87
156
  self, folder_name: str, file_name: str, file_content: bytes
88
157
  ) -> tuple[bool, str]:
@@ -101,10 +170,7 @@ class UploadBackupToSharepointUsecase:
101
170
 
102
171
  async with sharepoint_client:
103
172
  try:
104
- destination_folder = self.destination_folders.get(
105
- folder_name, folder_name
106
- )
107
- folder_url = f"{c.SHAREPOINT_BASE_URL}/{destination_folder}"
173
+ folder_url = f"{self.sharepoint_destination_path}/{folder_name}"
108
174
  args = SpUploadFileArgs(
109
175
  folder_relative_url=folder_url,
110
176
  file_content=file_content,
@@ -121,7 +187,7 @@ class UploadBackupToSharepointUsecase:
121
187
  async def _upload_and_log_progress_task(self, folder_name, file_name) -> dict:
122
188
  """Task for uploads a file and logs progress."""
123
189
  uploading_message = (
124
- f"[BACKUP] Uploading file '{file_name}' from '{folder_name}' "
190
+ f"[local_backup_lib] Uploading file '{file_name}' from '{folder_name}' "
125
191
  )
126
192
  self.log_history.append(uploading_message)
127
193
  self.logger.debug(uploading_message)
@@ -130,7 +196,9 @@ class UploadBackupToSharepointUsecase:
130
196
  )
131
197
  file_content = await self.files_client.read(ReadArgs(file_path, mode="rb"))
132
198
  uploaded, error_message = await self.export_file_to_sharepoint(
133
- folder_name, file_name, file_content
199
+ folder_name,
200
+ file_name,
201
+ file_content, # type: ignore
134
202
  )
135
203
  result_message = show_upload_result(uploaded, file_name)
136
204
  self.logger.debug(result_message)
@@ -145,9 +213,7 @@ class UploadBackupToSharepointUsecase:
145
213
  async def retry_upload_failed_files(self, results) -> None:
146
214
  failed_files = [item for item in results if not item["uploaded"]]
147
215
  tasks = []
148
- retry_message = (
149
- f"[BACKUP] Retrying upload for {len(failed_files)} failed files... 🚨"
150
- )
216
+ retry_message = f"[local_backup_lib] Retrying upload for {len(failed_files)} failed files... 🚨"
151
217
  self.log_history.append(retry_message)
152
218
  self.logger.debug(retry_message)
153
219
  for file in failed_files:
@@ -157,100 +223,52 @@ class UploadBackupToSharepointUsecase:
157
223
  )
158
224
  )
159
225
  results = await asyncio.gather(*tasks, return_exceptions=True)
160
- success = calculate_percentage_uploaded(results, self.total_files)
226
+ success = calculate_percentage_uploaded(results, self.total_files) # type: ignore
161
227
  if success < 100.0:
162
228
  raise BackupUploadError(
163
- reason=extract_error_message(self.logger, results, success)
229
+ reason=extract_error_message(self.logger, results, success) # type: ignore
164
230
  )
165
231
  else:
166
232
  successful_upload_retry = (
167
- "[BACKUP] All files uploaded successfully after retry."
233
+ "[local_backup_lib] All files uploaded successfully after retry."
168
234
  )
169
235
  self.log_history.append(successful_upload_retry)
170
236
  self.logger.debug(successful_upload_retry)
171
237
  await self._save_log_history()
172
- return parse_execute_response(results)
238
+ return parse_execute_response(results) # type: ignore
173
239
 
174
240
  async def execute(self):
175
241
  """Exports all files from the local backup folder to SharePoint cloud."""
176
- self.grouped_files_by_folder = await self._extract_filesnames_by_folder()
242
+ start_time = time()
243
+ self.grouped_files_by_folder = await self._group_files_by_folder()
177
244
  self.total_files = sum(
178
245
  len(files) for files in self.grouped_files_by_folder.values()
179
246
  )
180
- tasks = []
181
- start_time = time()
182
-
183
- # Check if the local path exists in the main directory
184
- if not await self.dir_client.path_exists(self.local_backup_source_path):
185
- raise BackupSourcePathError(
186
- reason=f"'{self.local_backup_source_path}' doesn't exist."
187
- )
188
-
189
- # Check if the current folder only have files.
190
- items = [
191
- item
192
- for item in await self.dir_client.listdir(self.local_backup_source_path)
193
- ]
194
- for item in items:
195
- folder_included = item in self.destination_folders.keys()
196
- is_file = not await self.dir_client.isdir(
197
- self.dir_client.join_paths(self.local_backup_source_path, item)
198
- )
199
247
 
200
- if not folder_included and not is_file:
201
- raise BackupSourcePathError(
202
- reason=(
203
- f"'{item}' must be included in the destination folders dictionary",
204
- )
205
- )
206
- elif folder_included and is_file:
207
- print(folder_included, is_file)
208
- raise BackupSourcePathError(reason=(f"'{item}' must be a directory.",))
248
+ # Check if the current folder only have files and each folder exist in Microsoft Sharepoint.
249
+ await self._validate_backup_structure()
209
250
 
210
- if self.total_files == 0:
211
- no_files_message = (
212
- f"[BACKUP] {self.local_backup_source_path} has no files ⚠️"
213
- )
214
- self.log_history.append(no_files_message)
215
- self.logger.debug(no_files_message)
216
- raise BackupEmptyError
217
251
  # Create task for each file stored in the the local backup folder.
218
- for folder_name in self.grouped_files_by_folder:
219
- if (
220
- await count_files_in_directory(
221
- self.local_backup_source_path, folder_name
222
- )
223
- == 0
224
- ):
225
- empty_folder_message = f"[BACKUP] The folder '{folder_name}' is empty ⚠️"
226
- self.logger.debug(empty_folder_message)
227
- self.log_history.append(empty_folder_message)
228
- continue
229
- extracting_files_message = (
230
- "[BACKUP]" + f" Extracting files from '{folder_name} ".center(15, "*")
231
- )
232
- self.log_history.append(extracting_files_message)
233
- self.logger.debug(extracting_files_message)
234
- for file_name in self.grouped_files_by_folder[folder_name]:
235
- tasks.append(self._upload_and_log_progress_task(folder_name, file_name))
252
+ tasks = await self._generate_tasks()
236
253
 
237
254
  # Execution of multiple asynchronous tasks for files migration.
238
255
  results = await asyncio.gather(*tasks, return_exceptions=True)
239
- success = calculate_percentage_uploaded(results, self.total_files)
256
+ success = calculate_percentage_uploaded(results, self.total_files) # type: ignore
257
+
240
258
  if success < 100.0:
241
259
  await self.retry_upload_failed_files(results)
242
260
  else:
243
261
  end_time = time()
244
262
  backup_time = end_time - start_time
245
263
  successful_backup_message = (
246
- f"[BACKUP] Migration time: {backup_time:.2f} seconds ✨"
264
+ f"[local_backup_lib] Migration time: {backup_time:.2f} seconds ✨"
247
265
  )
248
266
  self.log_history.append(successful_backup_message)
249
267
 
250
268
  finished_backup_message = (
251
- "[BACKUP] All the files were uploaded successfully 🎉"
269
+ "[local_backup_lib] All the files were uploaded successfully 🎉"
252
270
  )
253
271
  self.log_history.append(finished_backup_message)
254
272
 
255
273
  await self._save_log_history()
256
- return parse_execute_response(results)
274
+ return parse_execute_response(results) # type: ignore
@@ -31,8 +31,8 @@ def explain_status_code(status_code: int) -> str:
31
31
 
32
32
  def extract_error_message(logger: Logger, results: List[Dict], success: float) -> str:
33
33
  logger.info(
34
- "[BACKUP] Not all files uploaded ⚠️\n"
35
- f"[BACKUP] Files failed to upload: {(1 - success):.2%}"
34
+ "[local_backup_lib] Not all files uploaded ⚠️\n"
35
+ f"[local_backup_lib] Files failed to upload: {(1 - success):.2%}"
36
36
  )
37
37
 
38
38
  failed_files = [item for item in results if not item.get("uploaded")]
@@ -58,10 +58,12 @@ def extract_error_message(logger: Logger, results: List[Dict], success: float) -
58
58
 
59
59
  # Summary
60
60
  for code, items in grouped_errors.items():
61
- logger.info(f"[BACKUP] Status code {code} - {explain_status_code(int(code))}")
61
+ logger.info(
62
+ f"[local_backup_lib] Status code {code} - {explain_status_code(int(code))}"
63
+ )
62
64
  for item in items:
63
65
  logger.info(
64
- f"[BACKUP] File {item['file_name']}, url: {item['url']}, message: {item['message']}"
66
+ f"[local_backup_lib] File {item['file_name']}, url: {item['url']}, message: {item['message']}"
65
67
  )
66
68
 
67
69
  failed_file_names = [item["file_name"] for item in failed_files]
@@ -82,7 +84,7 @@ def parse_execute_response(results: List[Dict]) -> Dict[str, List[str]]:
82
84
  def show_upload_result(uploaded: bool, file_name: str) -> str:
83
85
  status = "✅" if uploaded else "❌"
84
86
  message = "was uploaded successfully" if uploaded else "failed to upload"
85
- result = f"[BACKUP] File {file_name} {message} {status}"
87
+ result = f"[local_backup_lib] File {file_name} {message} {status}"
86
88
  return result
87
89
 
88
90
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: saviialib
3
- Version: 0.10.1
3
+ Version: 0.11.0
4
4
  Summary: A client library for IoT projects in the RCER initiative
5
5
  License: MIT
6
6
  Author: pedropablozavalat
@@ -1,10 +1,10 @@
1
1
  saviialib/__init__.py,sha256=TMsEY8OOjo9KOz-0jf3QBh6WFOhCY07Rd7W2PK7C-1A,253
2
2
  saviialib/general_types/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  saviialib/general_types/api/__init__.py,sha256=jXhoMlbSv7UCizW_Fm2mqR_3n99qkocVwg6CF7s3w7w,145
4
- saviialib/general_types/api/epii_api_types.py,sha256=H4oUMnkYnl75mdCO4kyOqOdJ5jIh-J9tgGU_ZK2m7V8,2389
4
+ saviialib/general_types/api/epii_api_types.py,sha256=0_YzFLvv7asSZJ_K4FFqLeJsCFMMHRpHTQehmUok8b8,2326
5
5
  saviialib/general_types/error_types/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
6
  saviialib/general_types/error_types/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
- saviialib/general_types/error_types/api/epii_api_error_types.py,sha256=j1b2gE8zRTlh4gCB4kf9-JNlBzcZ9AmMKxRiFVbSqQ0,2722
7
+ saviialib/general_types/error_types/api/epii_api_error_types.py,sha256=iprpNvVoNA3vakMm7-dQdjCv7ZrRs6tRiXK1uaV3DNU,3049
8
8
  saviialib/general_types/error_types/common/__init__.py,sha256=yOBLZbt64Ki9Q0IJ0tMAubgq7PtrQ7XQ3RgtAzyOjiE,170
9
9
  saviialib/general_types/error_types/common/common_types.py,sha256=n5yuw-gVtkrtNfmaZ83ZkYxYHGl4jynOLUB9C8Tr32w,474
10
10
  saviialib/libs/directory_client/__init__.py,sha256=ys07nzp74fHew2mUkbGpntp5w4t_PnhZIS6D4_mJw2A,162
@@ -19,36 +19,35 @@ saviialib/libs/files_client/files_client_contract.py,sha256=fYvd68IMpc1OFkxbzNSm
19
19
  saviialib/libs/files_client/types/files_client_types.py,sha256=8OHm4nvZTW9K3ryeIUvthE_Cj7wF4zVcqG0KCi_vQIU,718
20
20
  saviialib/libs/ftp_client/__init__.py,sha256=dW2Yutgc7mJJJzgKLhWKXMgQ6KIWJYfFa1sGpjHH5xU,191
21
21
  saviialib/libs/ftp_client/clients/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
- saviialib/libs/ftp_client/clients/aioftp_client.py,sha256=gcPhLX1EE8_iiAGQ1eTWxzJ-qd3yjP9Ug1LJPibqGn8,1613
23
- saviialib/libs/ftp_client/ftp_client.py,sha256=RhWnGwfU8SN0tRqfDc3u6NKDj9qla4cOI2IANyb-S2s,820
24
- saviialib/libs/ftp_client/ftp_client_contract.py,sha256=2x1MPZNFVw3l-sVd65Z6kZYkXlk_8isH_ykzRZB9Cv8,326
22
+ saviialib/libs/ftp_client/clients/aioftp_client.py,sha256=npkB2IBTTcHg-_zXTv1OlRagxR6irT33TvFVSvtPqXU,1779
23
+ saviialib/libs/ftp_client/ftp_client.py,sha256=UWpuIrfO27A1M40YaBvAUdkdwPYJ4Ty4q55x7H4y1F8,844
24
+ saviialib/libs/ftp_client/ftp_client_contract.py,sha256=tymkugDzsJ5PzUXIaSkwX1h7T0naR15qAkjrqswqDyM,338
25
25
  saviialib/libs/ftp_client/types/__init__.py,sha256=syfwf9feP4QK7fkCTfl4j8l11ic-jHtfi1DE2chaWbs,155
26
26
  saviialib/libs/ftp_client/types/ftp_client_types.py,sha256=e4SmYkewldulaD8ms2q75zVgLFXyBxBqoa_L-IQOmso,256
27
27
  saviialib/libs/sharepoint_client/__init__.py,sha256=v7h-cNsK-BaPp-hTU3NWRNXYRD9ztU-hsCk0eNRPIKA,334
28
- saviialib/libs/sharepoint_client/clients/sharepoint_rest_api.py,sha256=6TGw2svGZ9QiABJdiUNzTIjmla3f70-hVxPK0cOZEVc,5252
29
- saviialib/libs/sharepoint_client/sharepoint_client.py,sha256=lzzRk-5YzScNL15TzHp8dAcdhiAtRVCfY7L2GEqoccM,1246
28
+ saviialib/libs/sharepoint_client/clients/sharepoint_rest_api.py,sha256=oGqNQcPL0HX-WYqO26JuIi9PDYPIZAoyDYMl965L_0c,5295
29
+ saviialib/libs/sharepoint_client/sharepoint_client.py,sha256=LMQFti0Ulc4FCPQy17mrTLNJkO2Qp3i-KR0VbjPyPG4,1665
30
30
  saviialib/libs/sharepoint_client/sharepoint_client_contract.py,sha256=xqNHzCjp7GvUGGUox9YTJj2QJgTc5819t2etOk8X26o,485
31
31
  saviialib/libs/sharepoint_client/types/sharepoint_client_types.py,sha256=OmPlCJ9rLrAFBeG6aDp5cxMiQ5BZlDyGVx5S4GN4aqg,414
32
32
  saviialib/libs/zero_dependency/utils/datetime_utils.py,sha256=NFPHxOTuCtfkYjUnsbRqw9ZK87UGAK-Eira2CwG8rJ8,754
33
33
  saviialib/services/epii/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
- saviialib/services/epii/api.py,sha256=ykS32tt2X3ocuHtEe8oyyg94a0l7IcMhxCMrqZ6Mc4U,3557
34
+ saviialib/services/epii/api.py,sha256=kd4kL475C8CtEj0Yg8Eg1ig8J90GbIbdl9A8pqPtc58,3901
35
35
  saviialib/services/epii/controllers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
36
36
  saviialib/services/epii/controllers/types/__init__.py,sha256=xzky-oTSojLNkWETp_k8a4dcXYvYSQY0VhWo23Yhb8U,195
37
- saviialib/services/epii/controllers/types/update_thies_data_types.py,sha256=Id86QaFt6A2EJgHJvmm3rvWGUkT2SM8D5OTxZGS-aTs,380
38
- saviialib/services/epii/controllers/types/upload_backup_to_sharepoint_types.py,sha256=k_vfqI4UfdSS62HY5pi8eq2PxYXRp4LexDgRB3V2lrc,400
39
- saviialib/services/epii/controllers/update_thies_data.py,sha256=5vi-CEXV9maCTHgyZRnGs8zlc2xkEQ3TJMVza4xr-Qw,4334
40
- saviialib/services/epii/controllers/upload_backup_to_sharepoint.py,sha256=2op1yGEy9DNJW5ryzBNTniVQZqdc8twAs3VIsGsnidg,3799
41
- saviialib/services/epii/use_cases/constants/update_thies_data_constants.py,sha256=38f2WKV-zBO9O-CV8mh3tW3MFMiaJrrv4_FfQiyHApc,275
42
- saviialib/services/epii/use_cases/constants/upload_backup_to_sharepoint_constants.py,sha256=8JwqAU1KP-WMUcZ67oSQY1_5I47jlaJnOpwKyTKdN_Y,208
37
+ saviialib/services/epii/controllers/types/update_thies_data_types.py,sha256=kmt18vq7RLEAfIJj9MYz62fJH9etuU1WqZJ5MYmjiIg,448
38
+ saviialib/services/epii/controllers/types/upload_backup_to_sharepoint_types.py,sha256=5mDMLy3J5grACl1ezBGYZPOyhIkWYeIWWBOklaP2IlQ,471
39
+ saviialib/services/epii/controllers/update_thies_data.py,sha256=Bq00uqcu26Ro1gCpFGqNys88kzMTnnJvEmxOBitLUks,4840
40
+ saviialib/services/epii/controllers/upload_backup_to_sharepoint.py,sha256=7-ABo89yXhrWv-iOFjCkBGX-y_I62eFaOi1LtO5Gb4k,3817
41
+ saviialib/services/epii/use_cases/constants/upload_backup_to_sharepoint_constants.py,sha256=erkn-3E8YwBMFs25o7exXoK7s73NdgP9IYDXeWzALcI,98
43
42
  saviialib/services/epii/use_cases/types/__init__.py,sha256=u6fyodOEJE2j6FMqJux40Xf9ccYAi-UUYxqT-Kzc0kE,199
44
- saviialib/services/epii/use_cases/types/update_thies_data_types.py,sha256=BoT6N9YoVw3f8Cyb88T7fJTCCnkVybOh1K1u2fJ3X7k,419
45
- saviialib/services/epii/use_cases/types/upload_backup_to_sharepoint_types.py,sha256=v2CEvohTqkhKmmKn2upgaGWFbWrkL817Gt3T-bnlMcQ,313
46
- saviialib/services/epii/use_cases/update_thies_data.py,sha256=WLBpdAUkxAL_XdDnc49scmst1xMjrdScjr6Cmgg3UEE,6494
47
- saviialib/services/epii/use_cases/upload_backup_to_sharepoint.py,sha256=V-O4x2du-lvTJRarvXbt4NjSGJ2jYWGTRrodiKPYIOU,10039
43
+ saviialib/services/epii/use_cases/types/update_thies_data_types.py,sha256=VQM8oJxrwvmH7NeBpJ6JYZtDV_MujMRWwFazsSgHY_M,493
44
+ saviialib/services/epii/use_cases/types/upload_backup_to_sharepoint_types.py,sha256=J_sGhqSaPoMZA0GIrzCx6pmgSKgIkGi0uyrsltU_H8w,320
45
+ saviialib/services/epii/use_cases/update_thies_data.py,sha256=EPzRCo4X7khTp7afX3jCpHdQTCjk7a-PmYnm4Br2vTI,8246
46
+ saviialib/services/epii/use_cases/upload_backup_to_sharepoint.py,sha256=UZ2Pe_mavdquYG00_GYtANY4nn0wHjT_Z0HLUvtfW2c,11143
48
47
  saviialib/services/epii/utils/__init__.py,sha256=cYt2tvq65_OMjFaqb8-CCC7IGCQgFd4ziEUWJV7s1iY,98
49
48
  saviialib/services/epii/utils/update_thies_data_utils.py,sha256=EpjYWXqyHxJ-dO3MHhdXp-rGV7WyUckeFko-nnfnNac,555
50
- saviialib/services/epii/utils/upload_backup_to_sharepoint_utils.py,sha256=p1LIEz_iSnNSv5SxebfiR5ry5HY83ttJ7vJ97TEw2mk,3456
51
- saviialib-0.10.1.dist-info/LICENSE,sha256=NWpf6b38xgBWPBo5HZsCbdfp9hZSliEbRqWQgm0fkOo,1076
52
- saviialib-0.10.1.dist-info/METADATA,sha256=7Ru4sGRBiK6gcfnKPTUSMQeqp-OvNfAtlJJ6LK-WsrI,4083
53
- saviialib-0.10.1.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
54
- saviialib-0.10.1.dist-info/RECORD,,
49
+ saviialib/services/epii/utils/upload_backup_to_sharepoint_utils.py,sha256=hEeV4_kcG8YL6t_3V8AlhgDHtHiUNsdYpilfgTLaQMc,3528
50
+ saviialib-0.11.0.dist-info/LICENSE,sha256=NWpf6b38xgBWPBo5HZsCbdfp9hZSliEbRqWQgm0fkOo,1076
51
+ saviialib-0.11.0.dist-info/METADATA,sha256=diHGwoPOT3vsY78ni4-ON6Aom5jTnWgQwO3QPY3E-z4,4083
52
+ saviialib-0.11.0.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
53
+ saviialib-0.11.0.dist-info/RECORD,,
@@ -1,5 +0,0 @@
1
- SHAREPOINT_BASE_URL = "/sites/uc365_CentrosyEstacionesRegionalesUC/Shared%20Documents/General/Test_Raspberry/THIES"
2
- SHAREPOINT_THIES_FOLDERS = ["AVG", "EXT"]
3
-
4
- FTP_SERVER_PATH_AVG_FILES = "ftp/thies/BINFILES/ARCH_AV1"
5
- FTP_SERVER_PATH_EXT_FILES = "ftp/thies/BINFILES/ARCH_EX1"