saviialib 0.9.1__py3-none-any.whl → 0.10.2__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.
- saviialib/general_types/api/epii_api_types.py +3 -0
- saviialib/libs/directory_client/__init__.py +4 -0
- saviialib/libs/directory_client/client/os_client.py +23 -0
- saviialib/libs/directory_client/directory_client.py +28 -0
- saviialib/libs/directory_client/directory_client_contract.py +19 -0
- saviialib/libs/directory_client/types/directory_client_types.py +6 -0
- saviialib/libs/files_client/__init__.py +2 -2
- saviialib/libs/files_client/clients/aiofiles_client.py +12 -3
- saviialib/libs/files_client/types/files_client_types.py +2 -1
- saviialib/services/epii/api.py +3 -1
- saviialib/services/epii/controllers/upload_backup_to_sharepoint.py +2 -1
- saviialib/services/epii/use_cases/constants/upload_backup_to_sharepoint_constants.py +1 -0
- saviialib/services/epii/use_cases/types/upload_backup_to_sharepoint_types.py +2 -0
- saviialib/services/epii/use_cases/upload_backup_to_sharepoint.py +62 -46
- saviialib/services/epii/utils/upload_backup_to_sharepoint_utils.py +15 -18
- {saviialib-0.9.1.dist-info → saviialib-0.10.2.dist-info}/METADATA +1 -1
- {saviialib-0.9.1.dist-info → saviialib-0.10.2.dist-info}/RECORD +19 -14
- {saviialib-0.9.1.dist-info → saviialib-0.10.2.dist-info}/LICENSE +0 -0
- {saviialib-0.9.1.dist-info → saviialib-0.10.2.dist-info}/WHEEL +0 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
from dataclasses import dataclass
|
|
2
|
+
from logging import Logger
|
|
2
3
|
|
|
3
4
|
|
|
4
5
|
@dataclass
|
|
@@ -27,6 +28,7 @@ class EpiiAPIConfig:
|
|
|
27
28
|
sharepoint_tenant_id: str
|
|
28
29
|
sharepoint_tenant_name: str
|
|
29
30
|
sharepoint_site_name: str
|
|
31
|
+
logger: Logger
|
|
30
32
|
|
|
31
33
|
|
|
32
34
|
@dataclass
|
|
@@ -80,3 +82,4 @@ class EpiiSharepointBackupConfig:
|
|
|
80
82
|
sharepoint_site_name: str
|
|
81
83
|
local_backup_source_path: str
|
|
82
84
|
destination_folders: str
|
|
85
|
+
logger: Logger
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from saviialib.libs.directory_client.directory_client_contract import (
|
|
2
|
+
DirectoryClientContract,
|
|
3
|
+
)
|
|
4
|
+
import os
|
|
5
|
+
import asyncio
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class OsClient(DirectoryClientContract):
|
|
9
|
+
@staticmethod
|
|
10
|
+
def join_paths(*paths: str) -> str:
|
|
11
|
+
return os.path.join(*paths)
|
|
12
|
+
|
|
13
|
+
@staticmethod
|
|
14
|
+
async def path_exists(path: str) -> bool:
|
|
15
|
+
return await asyncio.to_thread(os.path.exists, path)
|
|
16
|
+
|
|
17
|
+
@staticmethod
|
|
18
|
+
async def listdir(path: str) -> list:
|
|
19
|
+
return await asyncio.to_thread(os.listdir, path)
|
|
20
|
+
|
|
21
|
+
@staticmethod
|
|
22
|
+
async def isdir(path: str) -> list:
|
|
23
|
+
return await asyncio.to_thread(os.path.isdir, path)
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
from .client.os_client import OsClient
|
|
2
|
+
from .directory_client_contract import DirectoryClientContract
|
|
3
|
+
from .types.directory_client_types import DirectoryClientArgs
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class DirectoryClient(DirectoryClientContract):
|
|
7
|
+
CLIENTS = {"os_client"}
|
|
8
|
+
|
|
9
|
+
def __init__(self, args: DirectoryClientArgs) -> None:
|
|
10
|
+
if args.client_name not in DirectoryClient.CLIENTS:
|
|
11
|
+
msg = f"Unsupported client {args.client_name}"
|
|
12
|
+
raise KeyError(msg)
|
|
13
|
+
|
|
14
|
+
if args.client_name == "os_client":
|
|
15
|
+
self.client_obj = OsClient()
|
|
16
|
+
self.client_name = args.client_name
|
|
17
|
+
|
|
18
|
+
def join_paths(self, *paths: str) -> str:
|
|
19
|
+
return self.client_obj.join_paths(*paths)
|
|
20
|
+
|
|
21
|
+
async def path_exists(self, path: str) -> bool:
|
|
22
|
+
return await self.client_obj.path_exists(path)
|
|
23
|
+
|
|
24
|
+
async def listdir(self, path: str) -> list:
|
|
25
|
+
return await self.client_obj.listdir(path)
|
|
26
|
+
|
|
27
|
+
async def isdir(self, path: str) -> bool:
|
|
28
|
+
return await self.client_obj.isdir(path)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class DirectoryClientContract(ABC):
|
|
5
|
+
@abstractmethod
|
|
6
|
+
def join_paths(self, *paths: str) -> str:
|
|
7
|
+
pass
|
|
8
|
+
|
|
9
|
+
@abstractmethod
|
|
10
|
+
async def path_exists(self, path: str) -> bool:
|
|
11
|
+
pass
|
|
12
|
+
|
|
13
|
+
@abstractmethod
|
|
14
|
+
async def listdir(self, path: str) -> list:
|
|
15
|
+
pass
|
|
16
|
+
|
|
17
|
+
@abstractmethod
|
|
18
|
+
async def isdir(self, path) -> bool:
|
|
19
|
+
pass
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
from .files_client import FilesClient
|
|
2
|
-
from .types.files_client_types import FilesClientInitArgs, ReadArgs
|
|
2
|
+
from .types.files_client_types import FilesClientInitArgs, ReadArgs, WriteArgs
|
|
3
3
|
|
|
4
|
-
__all__ = ["FilesClient", "FilesClientInitArgs", "ReadArgs"]
|
|
4
|
+
__all__ = ["FilesClient", "FilesClientInitArgs", "ReadArgs", "WriteArgs"]
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import aiofiles
|
|
2
|
-
|
|
2
|
+
from saviialib.libs.directory_client.directory_client import (
|
|
3
|
+
DirectoryClient,
|
|
4
|
+
DirectoryClientArgs,
|
|
5
|
+
)
|
|
3
6
|
from saviialib.libs.files_client.files_client_contract import FilesClientContract
|
|
4
7
|
from saviialib.libs.files_client.types.files_client_types import (
|
|
5
8
|
FilesClientInitArgs,
|
|
@@ -10,7 +13,7 @@ from saviialib.libs.files_client.types.files_client_types import (
|
|
|
10
13
|
|
|
11
14
|
class AioFilesClient(FilesClientContract):
|
|
12
15
|
def __init__(self, args: FilesClientInitArgs):
|
|
13
|
-
|
|
16
|
+
self.dir_client = DirectoryClient(DirectoryClientArgs(client_name="os_client"))
|
|
14
17
|
|
|
15
18
|
async def read(self, args: ReadArgs) -> str | bytes:
|
|
16
19
|
encoding = None if args.mode == "rb" else args.encoding
|
|
@@ -18,4 +21,10 @@ class AioFilesClient(FilesClientContract):
|
|
|
18
21
|
return await file.read()
|
|
19
22
|
|
|
20
23
|
async def write(self, args: WriteArgs) -> None:
|
|
21
|
-
|
|
24
|
+
file_path = (
|
|
25
|
+
self.dir_client.join_paths(args.destination_path, args.file_name)
|
|
26
|
+
if args.destination_path
|
|
27
|
+
else args.file_name
|
|
28
|
+
)
|
|
29
|
+
async with aiofiles.open(file_path, args.mode) as file:
|
|
30
|
+
await file.write(args.file_content)
|
saviialib/services/epii/api.py
CHANGED
|
@@ -28,6 +28,7 @@ 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
|
+
self.logger = config.logger
|
|
31
32
|
|
|
32
33
|
async def update_thies_data(self) -> Dict[str, Any]:
|
|
33
34
|
"""
|
|
@@ -70,7 +71,8 @@ class EpiiAPI:
|
|
|
70
71
|
sharepoint_tenant_id=self.sharepoint_tenant_id,
|
|
71
72
|
sharepoint_tenant_name=self.sharepoint_tenant_name,
|
|
72
73
|
local_backup_source_path=local_backup_source_path,
|
|
73
|
-
destination_folders=destination_folders
|
|
74
|
+
destination_folders=destination_folders,
|
|
75
|
+
logger=self.logger,
|
|
74
76
|
)
|
|
75
77
|
|
|
76
78
|
controller = UploadBackupToSharepointController(
|
|
@@ -34,7 +34,8 @@ class UploadBackupToSharepointController:
|
|
|
34
34
|
sharepoint_tenant_id=input.config.sharepoint_tenant_id,
|
|
35
35
|
),
|
|
36
36
|
local_backup_source_path=input.config.local_backup_source_path,
|
|
37
|
-
destination_folders=input.config.destination_folders
|
|
37
|
+
destination_folders=input.config.destination_folders,
|
|
38
|
+
logger=input.config.logger,
|
|
38
39
|
)
|
|
39
40
|
)
|
|
40
41
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from dataclasses import dataclass
|
|
2
2
|
from saviialib.general_types.api.epii_api_types import SharepointConfig
|
|
3
|
+
from logging import Logger
|
|
3
4
|
|
|
4
5
|
|
|
5
6
|
@dataclass
|
|
@@ -7,3 +8,4 @@ class UploadBackupToSharepointUseCaseInput:
|
|
|
7
8
|
sharepoint_config: SharepointConfig
|
|
8
9
|
local_backup_source_path: str
|
|
9
10
|
destination_folders: dict
|
|
11
|
+
logger: Logger
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import asyncio
|
|
2
|
-
import os
|
|
3
2
|
from time import time
|
|
3
|
+
from logging import Logger
|
|
4
4
|
import saviialib.services.epii.use_cases.constants.upload_backup_to_sharepoint_constants as c
|
|
5
5
|
from saviialib.general_types.error_types.api.epii_api_error_types import (
|
|
6
6
|
BackupEmptyError,
|
|
@@ -10,7 +10,13 @@ from saviialib.general_types.error_types.api.epii_api_error_types import (
|
|
|
10
10
|
from saviialib.general_types.error_types.common import (
|
|
11
11
|
SharepointClientError,
|
|
12
12
|
)
|
|
13
|
-
from saviialib.libs.
|
|
13
|
+
from saviialib.libs.directory_client import DirectoryClient, DirectoryClientArgs
|
|
14
|
+
from saviialib.libs.files_client import (
|
|
15
|
+
FilesClient,
|
|
16
|
+
FilesClientInitArgs,
|
|
17
|
+
ReadArgs,
|
|
18
|
+
WriteArgs,
|
|
19
|
+
)
|
|
14
20
|
from saviialib.libs.sharepoint_client import (
|
|
15
21
|
SharepointClient,
|
|
16
22
|
SharepointClientInitArgs,
|
|
@@ -19,7 +25,6 @@ from saviialib.libs.sharepoint_client import (
|
|
|
19
25
|
from saviialib.services.epii.utils.upload_backup_to_sharepoint_utils import (
|
|
20
26
|
calculate_percentage_uploaded,
|
|
21
27
|
count_files_in_directory,
|
|
22
|
-
directory_exists,
|
|
23
28
|
extract_error_message,
|
|
24
29
|
parse_execute_response,
|
|
25
30
|
show_upload_result,
|
|
@@ -28,7 +33,6 @@ from saviialib.services.epii.utils.upload_backup_to_sharepoint_utils import (
|
|
|
28
33
|
from .types.upload_backup_to_sharepoint_types import (
|
|
29
34
|
UploadBackupToSharepointUseCaseInput,
|
|
30
35
|
)
|
|
31
|
-
from .constants.upload_backup_to_sharepoint_constants import LOGGER
|
|
32
36
|
|
|
33
37
|
|
|
34
38
|
class UploadBackupToSharepointUsecase:
|
|
@@ -37,38 +41,47 @@ class UploadBackupToSharepointUsecase:
|
|
|
37
41
|
self.local_backup_source_path = input.local_backup_source_path
|
|
38
42
|
self.destination_folders = input.destination_folders
|
|
39
43
|
self.files_client = self._initialize_files_client()
|
|
44
|
+
self.dir_client = self._initialize_directory_client()
|
|
40
45
|
self.log_history = []
|
|
41
46
|
self.grouped_files_by_folder = None
|
|
42
47
|
self.total_files = None
|
|
48
|
+
self.logger: Logger = input.logger
|
|
49
|
+
|
|
50
|
+
def _initialize_directory_client(self):
|
|
51
|
+
return DirectoryClient(DirectoryClientArgs(client_name="os_client"))
|
|
43
52
|
|
|
44
53
|
def _initialize_files_client(self):
|
|
45
54
|
return FilesClient(FilesClientInitArgs(client_name="aiofiles_client"))
|
|
46
55
|
|
|
47
56
|
async def _extract_filesnames_by_folder(self) -> dict[str, list[str]]:
|
|
48
57
|
"""Groups files by their parent folder."""
|
|
49
|
-
backup_folder_exists = await
|
|
50
|
-
|
|
58
|
+
backup_folder_exists = await self.dir_client.path_exists(
|
|
59
|
+
self.local_backup_source_path
|
|
51
60
|
)
|
|
61
|
+
|
|
52
62
|
if not backup_folder_exists:
|
|
53
63
|
return {}
|
|
54
|
-
folder_names = await
|
|
55
|
-
os.listdir, self.local_backup_source_path
|
|
56
|
-
)
|
|
64
|
+
folder_names = await self.dir_client.listdir(self.local_backup_source_path)
|
|
57
65
|
return {
|
|
58
66
|
folder_name: [
|
|
59
67
|
file_name
|
|
60
|
-
for file_name in await
|
|
61
|
-
|
|
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
|
+
)
|
|
62
72
|
)
|
|
63
73
|
]
|
|
64
74
|
for folder_name in folder_names
|
|
65
75
|
}
|
|
66
76
|
|
|
67
|
-
def _save_log_history(self) -> None:
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
77
|
+
async def _save_log_history(self) -> None:
|
|
78
|
+
await self.files_client.write(
|
|
79
|
+
WriteArgs(
|
|
80
|
+
file_name="BACKUP_LOG_HISTORY.log",
|
|
81
|
+
file_content="\n".join(self.log_history),
|
|
82
|
+
mode="w",
|
|
83
|
+
)
|
|
84
|
+
)
|
|
72
85
|
|
|
73
86
|
async def export_file_to_sharepoint(
|
|
74
87
|
self, folder_name: str, file_name: str, file_content: bytes
|
|
@@ -105,20 +118,22 @@ class UploadBackupToSharepointUsecase:
|
|
|
105
118
|
|
|
106
119
|
return uploaded, error_message
|
|
107
120
|
|
|
108
|
-
async def
|
|
121
|
+
async def _upload_and_log_progress_task(self, folder_name, file_name) -> dict:
|
|
109
122
|
"""Task for uploads a file and logs progress."""
|
|
110
123
|
uploading_message = (
|
|
111
|
-
f"[
|
|
124
|
+
f"[local_backup_lib] Uploading file '{file_name}' from '{folder_name}' "
|
|
112
125
|
)
|
|
113
126
|
self.log_history.append(uploading_message)
|
|
114
|
-
|
|
115
|
-
file_path =
|
|
127
|
+
self.logger.debug(uploading_message)
|
|
128
|
+
file_path = self.dir_client.join_paths(
|
|
129
|
+
self.local_backup_source_path, folder_name, file_name
|
|
130
|
+
)
|
|
116
131
|
file_content = await self.files_client.read(ReadArgs(file_path, mode="rb"))
|
|
117
132
|
uploaded, error_message = await self.export_file_to_sharepoint(
|
|
118
133
|
folder_name, file_name, file_content
|
|
119
134
|
)
|
|
120
135
|
result_message = show_upload_result(uploaded, file_name)
|
|
121
|
-
|
|
136
|
+
self.logger.debug(result_message)
|
|
122
137
|
self.log_history.append(result_message)
|
|
123
138
|
return {
|
|
124
139
|
"parent_folder": folder_name,
|
|
@@ -130,28 +145,28 @@ class UploadBackupToSharepointUsecase:
|
|
|
130
145
|
async def retry_upload_failed_files(self, results) -> None:
|
|
131
146
|
failed_files = [item for item in results if not item["uploaded"]]
|
|
132
147
|
tasks = []
|
|
133
|
-
retry_message = (
|
|
134
|
-
f"[BACKUP] Retrying upload for {len(failed_files)} failed files... 🚨"
|
|
135
|
-
)
|
|
148
|
+
retry_message = f"[local_backup_lib] Retrying upload for {len(failed_files)} failed files... 🚨"
|
|
136
149
|
self.log_history.append(retry_message)
|
|
137
|
-
|
|
150
|
+
self.logger.debug(retry_message)
|
|
138
151
|
for file in failed_files:
|
|
139
152
|
tasks.append(
|
|
140
|
-
self.
|
|
153
|
+
self._upload_and_log_progress_task(
|
|
141
154
|
file["parent_folder"], file["file_name"]
|
|
142
155
|
)
|
|
143
156
|
)
|
|
144
157
|
results = await asyncio.gather(*tasks, return_exceptions=True)
|
|
145
158
|
success = calculate_percentage_uploaded(results, self.total_files)
|
|
146
159
|
if success < 100.0:
|
|
147
|
-
raise BackupUploadError(
|
|
160
|
+
raise BackupUploadError(
|
|
161
|
+
reason=extract_error_message(self.logger, results, success)
|
|
162
|
+
)
|
|
148
163
|
else:
|
|
149
164
|
successful_upload_retry = (
|
|
150
|
-
"[
|
|
165
|
+
"[local_backup_lib] All files uploaded successfully after retry."
|
|
151
166
|
)
|
|
152
167
|
self.log_history.append(successful_upload_retry)
|
|
153
|
-
|
|
154
|
-
self._save_log_history()
|
|
168
|
+
self.logger.debug(successful_upload_retry)
|
|
169
|
+
await self._save_log_history()
|
|
155
170
|
return parse_execute_response(results)
|
|
156
171
|
|
|
157
172
|
async def execute(self):
|
|
@@ -164,7 +179,7 @@ class UploadBackupToSharepointUsecase:
|
|
|
164
179
|
start_time = time()
|
|
165
180
|
|
|
166
181
|
# Check if the local path exists in the main directory
|
|
167
|
-
if not await
|
|
182
|
+
if not await self.dir_client.path_exists(self.local_backup_source_path):
|
|
168
183
|
raise BackupSourcePathError(
|
|
169
184
|
reason=f"'{self.local_backup_source_path}' doesn't exist."
|
|
170
185
|
)
|
|
@@ -172,14 +187,12 @@ class UploadBackupToSharepointUsecase:
|
|
|
172
187
|
# Check if the current folder only have files.
|
|
173
188
|
items = [
|
|
174
189
|
item
|
|
175
|
-
for item in await
|
|
176
|
-
os.listdir, self.local_backup_source_path
|
|
177
|
-
)
|
|
190
|
+
for item in await self.dir_client.listdir(self.local_backup_source_path)
|
|
178
191
|
]
|
|
179
192
|
for item in items:
|
|
180
193
|
folder_included = item in self.destination_folders.keys()
|
|
181
|
-
is_file = not await
|
|
182
|
-
|
|
194
|
+
is_file = not await self.dir_client.isdir(
|
|
195
|
+
self.dir_client.join_paths(self.local_backup_source_path, item)
|
|
183
196
|
)
|
|
184
197
|
|
|
185
198
|
if not folder_included and not is_file:
|
|
@@ -194,10 +207,10 @@ class UploadBackupToSharepointUsecase:
|
|
|
194
207
|
|
|
195
208
|
if self.total_files == 0:
|
|
196
209
|
no_files_message = (
|
|
197
|
-
f"[
|
|
210
|
+
f"[local_backup_lib] {self.local_backup_source_path} has no files ⚠️"
|
|
198
211
|
)
|
|
199
212
|
self.log_history.append(no_files_message)
|
|
200
|
-
|
|
213
|
+
self.logger.debug(no_files_message)
|
|
201
214
|
raise BackupEmptyError
|
|
202
215
|
# Create task for each file stored in the the local backup folder.
|
|
203
216
|
for folder_name in self.grouped_files_by_folder:
|
|
@@ -207,17 +220,20 @@ class UploadBackupToSharepointUsecase:
|
|
|
207
220
|
)
|
|
208
221
|
== 0
|
|
209
222
|
):
|
|
210
|
-
empty_folder_message =
|
|
211
|
-
|
|
223
|
+
empty_folder_message = (
|
|
224
|
+
f"[local_backup_lib] The folder '{folder_name}' is empty ⚠️"
|
|
225
|
+
)
|
|
226
|
+
self.logger.debug(empty_folder_message)
|
|
212
227
|
self.log_history.append(empty_folder_message)
|
|
213
228
|
continue
|
|
214
229
|
extracting_files_message = (
|
|
215
|
-
"[
|
|
230
|
+
"[local_backup_lib]"
|
|
231
|
+
+ f" Extracting files from '{folder_name} ".center(15, "*")
|
|
216
232
|
)
|
|
217
233
|
self.log_history.append(extracting_files_message)
|
|
218
|
-
|
|
234
|
+
self.logger.debug(extracting_files_message)
|
|
219
235
|
for file_name in self.grouped_files_by_folder[folder_name]:
|
|
220
|
-
tasks.append(self.
|
|
236
|
+
tasks.append(self._upload_and_log_progress_task(folder_name, file_name))
|
|
221
237
|
|
|
222
238
|
# Execution of multiple asynchronous tasks for files migration.
|
|
223
239
|
results = await asyncio.gather(*tasks, return_exceptions=True)
|
|
@@ -228,14 +244,14 @@ class UploadBackupToSharepointUsecase:
|
|
|
228
244
|
end_time = time()
|
|
229
245
|
backup_time = end_time - start_time
|
|
230
246
|
successful_backup_message = (
|
|
231
|
-
f"[
|
|
247
|
+
f"[local_backup_lib] Migration time: {backup_time:.2f} seconds ✨"
|
|
232
248
|
)
|
|
233
249
|
self.log_history.append(successful_backup_message)
|
|
234
250
|
|
|
235
251
|
finished_backup_message = (
|
|
236
|
-
"[
|
|
252
|
+
"[local_backup_lib] All the files were uploaded successfully 🎉"
|
|
237
253
|
)
|
|
238
254
|
self.log_history.append(finished_backup_message)
|
|
239
255
|
|
|
240
|
-
self._save_log_history()
|
|
256
|
+
await self._save_log_history()
|
|
241
257
|
return parse_execute_response(results)
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import re
|
|
2
|
+
from logging import Logger
|
|
2
3
|
from typing import List, Dict, Optional
|
|
3
|
-
import asyncio
|
|
4
|
-
import os
|
|
5
4
|
from saviialib.general_types.error_types.api.epii_api_error_types import (
|
|
6
5
|
BackupSourcePathError,
|
|
7
6
|
)
|
|
8
|
-
from saviialib.
|
|
9
|
-
|
|
10
|
-
)
|
|
7
|
+
from saviialib.libs.directory_client import DirectoryClient, DirectoryClientArgs
|
|
8
|
+
|
|
9
|
+
dir_client = DirectoryClient(DirectoryClientArgs(client_name="os_client"))
|
|
11
10
|
|
|
12
11
|
|
|
13
12
|
def extract_error_information(error: str) -> Optional[Dict[str, str]]:
|
|
@@ -30,10 +29,10 @@ def explain_status_code(status_code: int) -> str:
|
|
|
30
29
|
return explanations.get(status_code, "Unknown error occurred.")
|
|
31
30
|
|
|
32
31
|
|
|
33
|
-
def extract_error_message(results: List[Dict], success: float) -> str:
|
|
34
|
-
|
|
35
|
-
"[
|
|
36
|
-
f"[
|
|
32
|
+
def extract_error_message(logger: Logger, results: List[Dict], success: float) -> str:
|
|
33
|
+
logger.info(
|
|
34
|
+
"[local_backup_lib] Not all files uploaded ⚠️\n"
|
|
35
|
+
f"[local_backup_lib] Files failed to upload: {(1 - success):.2%}"
|
|
37
36
|
)
|
|
38
37
|
|
|
39
38
|
failed_files = [item for item in results if not item.get("uploaded")]
|
|
@@ -59,10 +58,12 @@ def extract_error_message(results: List[Dict], success: float) -> str:
|
|
|
59
58
|
|
|
60
59
|
# Summary
|
|
61
60
|
for code, items in grouped_errors.items():
|
|
62
|
-
|
|
61
|
+
logger.info(
|
|
62
|
+
f"[local_backup_lib] Status code {code} - {explain_status_code(int(code))}"
|
|
63
|
+
)
|
|
63
64
|
for item in items:
|
|
64
|
-
|
|
65
|
-
f"[
|
|
65
|
+
logger.info(
|
|
66
|
+
f"[local_backup_lib] File {item['file_name']}, url: {item['url']}, message: {item['message']}"
|
|
66
67
|
)
|
|
67
68
|
|
|
68
69
|
failed_file_names = [item["file_name"] for item in failed_files]
|
|
@@ -83,7 +84,7 @@ def parse_execute_response(results: List[Dict]) -> Dict[str, List[str]]:
|
|
|
83
84
|
def show_upload_result(uploaded: bool, file_name: str) -> str:
|
|
84
85
|
status = "✅" if uploaded else "❌"
|
|
85
86
|
message = "was uploaded successfully" if uploaded else "failed to upload"
|
|
86
|
-
result = f"[
|
|
87
|
+
result = f"[local_backup_lib] File {file_name} {message} {status}"
|
|
87
88
|
return result
|
|
88
89
|
|
|
89
90
|
|
|
@@ -94,9 +95,5 @@ def calculate_percentage_uploaded(results: List[Dict], total_files: int) -> floa
|
|
|
94
95
|
return (uploaded_count / total_files) * 100 if total_files > 0 else 0
|
|
95
96
|
|
|
96
97
|
|
|
97
|
-
async def directory_exists(path: str) -> bool:
|
|
98
|
-
return await asyncio.to_thread(os.path.exists, path)
|
|
99
|
-
|
|
100
|
-
|
|
101
98
|
async def count_files_in_directory(path: str, folder_name: str) -> int:
|
|
102
|
-
return len(await
|
|
99
|
+
return len(await dir_client.listdir(dir_client.join_paths(path, folder_name)))
|
|
@@ -1,17 +1,22 @@
|
|
|
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=
|
|
4
|
+
saviialib/general_types/api/epii_api_types.py,sha256=H4oUMnkYnl75mdCO4kyOqOdJ5jIh-J9tgGU_ZK2m7V8,2389
|
|
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
7
|
saviialib/general_types/error_types/api/epii_api_error_types.py,sha256=j1b2gE8zRTlh4gCB4kf9-JNlBzcZ9AmMKxRiFVbSqQ0,2722
|
|
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
|
-
saviialib/libs/
|
|
11
|
-
saviialib/libs/
|
|
10
|
+
saviialib/libs/directory_client/__init__.py,sha256=ys07nzp74fHew2mUkbGpntp5w4t_PnhZIS6D4_mJw2A,162
|
|
11
|
+
saviialib/libs/directory_client/client/os_client.py,sha256=cL1ocxfLu6csBg7RKhP7sbpgCUr6_Me5cMOs4wrXmhw,628
|
|
12
|
+
saviialib/libs/directory_client/directory_client.py,sha256=mcYA2AY0f44ae39ImsetVRU8YW7xI25xTFTY5HmWivY,984
|
|
13
|
+
saviialib/libs/directory_client/directory_client_contract.py,sha256=eRTKPkpArMSi7gEDoowJ15hupLB_gr4ztO1Zc1BoXpc,396
|
|
14
|
+
saviialib/libs/directory_client/types/directory_client_types.py,sha256=ncMwVs_o6EYMuypXXmVInsjVDKJsdxVkmwj1M-LEInA,109
|
|
15
|
+
saviialib/libs/files_client/__init__.py,sha256=sIi9ne7Z3EfxnqGTaSmH-cZ8QsKyu0hoOz61GyA3njs,192
|
|
16
|
+
saviialib/libs/files_client/clients/aiofiles_client.py,sha256=Mu5pSnnEa3dT3GONmt1O-lCQstuQNXHtJHM3D2L6TU8,1107
|
|
12
17
|
saviialib/libs/files_client/files_client.py,sha256=eoByr7ZzOJ3b4NWlrEH0jKO1i-Rv3hSJV2s2JLhaOJ0,1081
|
|
13
18
|
saviialib/libs/files_client/files_client_contract.py,sha256=fYvd68IMpc1OFkxbzNSmRUoTWVctf3hkNVQ7QZV0m6I,304
|
|
14
|
-
saviialib/libs/files_client/types/files_client_types.py,sha256=
|
|
19
|
+
saviialib/libs/files_client/types/files_client_types.py,sha256=8OHm4nvZTW9K3ryeIUvthE_Cj7wF4zVcqG0KCi_vQIU,718
|
|
15
20
|
saviialib/libs/ftp_client/__init__.py,sha256=dW2Yutgc7mJJJzgKLhWKXMgQ6KIWJYfFa1sGpjHH5xU,191
|
|
16
21
|
saviialib/libs/ftp_client/clients/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
17
22
|
saviialib/libs/ftp_client/clients/aioftp_client.py,sha256=gcPhLX1EE8_iiAGQ1eTWxzJ-qd3yjP9Ug1LJPibqGn8,1613
|
|
@@ -26,24 +31,24 @@ saviialib/libs/sharepoint_client/sharepoint_client_contract.py,sha256=xqNHzCjp7G
|
|
|
26
31
|
saviialib/libs/sharepoint_client/types/sharepoint_client_types.py,sha256=OmPlCJ9rLrAFBeG6aDp5cxMiQ5BZlDyGVx5S4GN4aqg,414
|
|
27
32
|
saviialib/libs/zero_dependency/utils/datetime_utils.py,sha256=NFPHxOTuCtfkYjUnsbRqw9ZK87UGAK-Eira2CwG8rJ8,754
|
|
28
33
|
saviialib/services/epii/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
29
|
-
saviialib/services/epii/api.py,sha256=
|
|
34
|
+
saviialib/services/epii/api.py,sha256=ykS32tt2X3ocuHtEe8oyyg94a0l7IcMhxCMrqZ6Mc4U,3557
|
|
30
35
|
saviialib/services/epii/controllers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
31
36
|
saviialib/services/epii/controllers/types/__init__.py,sha256=xzky-oTSojLNkWETp_k8a4dcXYvYSQY0VhWo23Yhb8U,195
|
|
32
37
|
saviialib/services/epii/controllers/types/update_thies_data_types.py,sha256=Id86QaFt6A2EJgHJvmm3rvWGUkT2SM8D5OTxZGS-aTs,380
|
|
33
38
|
saviialib/services/epii/controllers/types/upload_backup_to_sharepoint_types.py,sha256=k_vfqI4UfdSS62HY5pi8eq2PxYXRp4LexDgRB3V2lrc,400
|
|
34
39
|
saviialib/services/epii/controllers/update_thies_data.py,sha256=5vi-CEXV9maCTHgyZRnGs8zlc2xkEQ3TJMVza4xr-Qw,4334
|
|
35
|
-
saviialib/services/epii/controllers/upload_backup_to_sharepoint.py,sha256=
|
|
40
|
+
saviialib/services/epii/controllers/upload_backup_to_sharepoint.py,sha256=2op1yGEy9DNJW5ryzBNTniVQZqdc8twAs3VIsGsnidg,3799
|
|
36
41
|
saviialib/services/epii/use_cases/constants/update_thies_data_constants.py,sha256=38f2WKV-zBO9O-CV8mh3tW3MFMiaJrrv4_FfQiyHApc,275
|
|
37
|
-
saviialib/services/epii/use_cases/constants/upload_backup_to_sharepoint_constants.py,sha256=
|
|
42
|
+
saviialib/services/epii/use_cases/constants/upload_backup_to_sharepoint_constants.py,sha256=8JwqAU1KP-WMUcZ67oSQY1_5I47jlaJnOpwKyTKdN_Y,208
|
|
38
43
|
saviialib/services/epii/use_cases/types/__init__.py,sha256=u6fyodOEJE2j6FMqJux40Xf9ccYAi-UUYxqT-Kzc0kE,199
|
|
39
44
|
saviialib/services/epii/use_cases/types/update_thies_data_types.py,sha256=BoT6N9YoVw3f8Cyb88T7fJTCCnkVybOh1K1u2fJ3X7k,419
|
|
40
|
-
saviialib/services/epii/use_cases/types/upload_backup_to_sharepoint_types.py,sha256=
|
|
45
|
+
saviialib/services/epii/use_cases/types/upload_backup_to_sharepoint_types.py,sha256=v2CEvohTqkhKmmKn2upgaGWFbWrkL817Gt3T-bnlMcQ,313
|
|
41
46
|
saviialib/services/epii/use_cases/update_thies_data.py,sha256=WLBpdAUkxAL_XdDnc49scmst1xMjrdScjr6Cmgg3UEE,6494
|
|
42
|
-
saviialib/services/epii/use_cases/upload_backup_to_sharepoint.py,sha256=
|
|
47
|
+
saviialib/services/epii/use_cases/upload_backup_to_sharepoint.py,sha256=gL2acEi9WH-HRbGPxZdZxZLg67itAP65KH5yPpC68II,10151
|
|
43
48
|
saviialib/services/epii/utils/__init__.py,sha256=cYt2tvq65_OMjFaqb8-CCC7IGCQgFd4ziEUWJV7s1iY,98
|
|
44
49
|
saviialib/services/epii/utils/update_thies_data_utils.py,sha256=EpjYWXqyHxJ-dO3MHhdXp-rGV7WyUckeFko-nnfnNac,555
|
|
45
|
-
saviialib/services/epii/utils/upload_backup_to_sharepoint_utils.py,sha256=
|
|
46
|
-
saviialib-0.
|
|
47
|
-
saviialib-0.
|
|
48
|
-
saviialib-0.
|
|
49
|
-
saviialib-0.
|
|
50
|
+
saviialib/services/epii/utils/upload_backup_to_sharepoint_utils.py,sha256=hEeV4_kcG8YL6t_3V8AlhgDHtHiUNsdYpilfgTLaQMc,3528
|
|
51
|
+
saviialib-0.10.2.dist-info/LICENSE,sha256=NWpf6b38xgBWPBo5HZsCbdfp9hZSliEbRqWQgm0fkOo,1076
|
|
52
|
+
saviialib-0.10.2.dist-info/METADATA,sha256=_VBG9mtIJQr60KrfFPAyz-jHGNtUEwDJDUseN_M3YKM,4083
|
|
53
|
+
saviialib-0.10.2.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
54
|
+
saviialib-0.10.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|