saviialib 1.6.1__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.
- saviialib/__init__.py +79 -0
- saviialib/general_types/__init__.py +0 -0
- saviialib/general_types/api/__init__.py +0 -0
- saviialib/general_types/api/saviia_api_types.py +48 -0
- saviialib/general_types/api/saviia_backup_api_types.py +24 -0
- saviialib/general_types/api/saviia_netcamera_api_types.py +11 -0
- saviialib/general_types/api/saviia_shakes_api_types.py +21 -0
- saviialib/general_types/api/saviia_thies_api_types.py +31 -0
- saviialib/general_types/error_types/__init__.py +0 -0
- saviialib/general_types/error_types/api/__init__.py +0 -0
- saviialib/general_types/error_types/api/saviia_api_error_types.py +113 -0
- saviialib/general_types/error_types/api/saviia_netcamera_error_types.py +7 -0
- saviialib/general_types/error_types/common/__init__.py +7 -0
- saviialib/general_types/error_types/common/common_types.py +26 -0
- saviialib/libs/directory_client/__init__.py +4 -0
- saviialib/libs/directory_client/client/os_client.py +55 -0
- saviialib/libs/directory_client/directory_client.py +44 -0
- saviialib/libs/directory_client/directory_client_contract.py +40 -0
- saviialib/libs/directory_client/types/directory_client_types.py +6 -0
- saviialib/libs/files_client/__init__.py +4 -0
- saviialib/libs/files_client/clients/aiofiles_client.py +44 -0
- saviialib/libs/files_client/clients/csv_client.py +42 -0
- saviialib/libs/files_client/files_client.py +26 -0
- saviialib/libs/files_client/files_client_contract.py +13 -0
- saviialib/libs/files_client/types/files_client_types.py +32 -0
- saviialib/libs/ftp_client/__init__.py +4 -0
- saviialib/libs/ftp_client/clients/__init__.py +0 -0
- saviialib/libs/ftp_client/clients/aioftp_client.py +52 -0
- saviialib/libs/ftp_client/clients/ftplib_client.py +58 -0
- saviialib/libs/ftp_client/ftp_client.py +25 -0
- saviialib/libs/ftp_client/ftp_client_contract.py +13 -0
- saviialib/libs/ftp_client/types/__init__.py +3 -0
- saviialib/libs/ftp_client/types/ftp_client_types.py +18 -0
- saviialib/libs/log_client/__init__.py +19 -0
- saviialib/libs/log_client/log_client.py +46 -0
- saviialib/libs/log_client/log_client_contract.py +28 -0
- saviialib/libs/log_client/logging_client/logging_client.py +58 -0
- saviialib/libs/log_client/types/__init__.py +0 -0
- saviialib/libs/log_client/types/log_client_types.py +47 -0
- saviialib/libs/log_client/utils/log_client_utils.py +6 -0
- saviialib/libs/sftp_client/__init__.py +8 -0
- saviialib/libs/sftp_client/clients/asyncssh_sftp_client.py +83 -0
- saviialib/libs/sftp_client/sftp_client.py +26 -0
- saviialib/libs/sftp_client/sftp_client_contract.py +13 -0
- saviialib/libs/sftp_client/types/sftp_client_types.py +24 -0
- saviialib/libs/sharepoint_client/__init__.py +17 -0
- saviialib/libs/sharepoint_client/clients/sharepoint_rest_api.py +160 -0
- saviialib/libs/sharepoint_client/sharepoint_client.py +58 -0
- saviialib/libs/sharepoint_client/sharepoint_client_contract.py +26 -0
- saviialib/libs/sharepoint_client/types/sharepoint_client_types.py +30 -0
- saviialib/libs/zero_dependency/utils/booleans_utils.py +2 -0
- saviialib/libs/zero_dependency/utils/datetime_utils.py +25 -0
- saviialib/libs/zero_dependency/utils/strings_utils.py +5 -0
- saviialib/services/backup/__init__.py +0 -0
- saviialib/services/backup/api.py +36 -0
- saviialib/services/backup/controllers/__init__.py +0 -0
- saviialib/services/backup/controllers/types/__init__.py +6 -0
- saviialib/services/backup/controllers/types/upload_backup_to_sharepoint_types.py +18 -0
- saviialib/services/backup/controllers/upload_backup_to_sharepoint.py +87 -0
- saviialib/services/backup/use_cases/constants/upload_backup_to_sharepoint_constants.py +5 -0
- saviialib/services/backup/use_cases/types/__init__.py +7 -0
- saviialib/services/backup/use_cases/types/upload_backup_to_sharepoint_types.py +11 -0
- saviialib/services/backup/use_cases/upload_backup_to_sharepoint.py +474 -0
- saviialib/services/backup/utils/__init__.py +3 -0
- saviialib/services/backup/utils/upload_backup_to_sharepoint_utils.py +100 -0
- saviialib/services/netcamera/api.py +30 -0
- saviialib/services/netcamera/controllers/get_media_files.py +40 -0
- saviialib/services/netcamera/controllers/types/get_media_files_types.py +16 -0
- saviialib/services/netcamera/use_cases/get_media_files.py +76 -0
- saviialib/services/netcamera/use_cases/types/get_media_files_types.py +18 -0
- saviialib/services/shakes/__init__.py +0 -0
- saviialib/services/shakes/api.py +31 -0
- saviialib/services/shakes/controllers/get_miniseed_files.py +48 -0
- saviialib/services/shakes/controllers/types/get_miniseed_files_types.py +16 -0
- saviialib/services/shakes/use_cases/get_miniseed_files.py +79 -0
- saviialib/services/shakes/use_cases/types/get_miniseed_files_types.py +18 -0
- saviialib/services/shakes/use_cases/utils/get_miniseed_files_utils.py +11 -0
- saviialib/services/thies/__init__.py +0 -0
- saviialib/services/thies/api.py +42 -0
- saviialib/services/thies/constants/update_thies_data_constants.py +67 -0
- saviialib/services/thies/controllers/types/update_thies_data_types.py +18 -0
- saviialib/services/thies/controllers/update_thies_data.py +119 -0
- saviialib/services/thies/use_cases/components/create_thies_statistics_file.py +115 -0
- saviialib/services/thies/use_cases/components/thies_bp.py +442 -0
- saviialib/services/thies/use_cases/types/update_thies_data_types.py +24 -0
- saviialib/services/thies/use_cases/update_thies_data.py +391 -0
- saviialib/services/thies/utils/update_thies_data_utils.py +21 -0
- saviialib-1.6.1.dist-info/METADATA +126 -0
- saviialib-1.6.1.dist-info/RECORD +91 -0
- saviialib-1.6.1.dist-info/WHEEL +4 -0
- saviialib-1.6.1.dist-info/licenses/LICENSE +22 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
import json
|
|
3
|
+
from aiohttp import ClientError, ClientSession, TCPConnector
|
|
4
|
+
from dotenv import load_dotenv
|
|
5
|
+
import ssl
|
|
6
|
+
import certifi
|
|
7
|
+
|
|
8
|
+
from saviialib.libs.sharepoint_client.sharepoint_client_contract import (
|
|
9
|
+
SharepointClientContract,
|
|
10
|
+
)
|
|
11
|
+
from saviialib.libs.sharepoint_client.types.sharepoint_client_types import (
|
|
12
|
+
SpListFilesArgs,
|
|
13
|
+
SpListFoldersArgs,
|
|
14
|
+
SpUploadFileArgs,
|
|
15
|
+
SpCreateFolderArgs,
|
|
16
|
+
SharepointClientInitArgs,
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
load_dotenv()
|
|
20
|
+
ssl_context = ssl.create_default_context(cafile=certifi.where())
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class SharepointRestAPI(SharepointClientContract):
|
|
24
|
+
def __init__(self, args: SharepointClientInitArgs):
|
|
25
|
+
self.session: ClientSession | None = None
|
|
26
|
+
self.base_headers = {}
|
|
27
|
+
self.credentials = {}
|
|
28
|
+
self.base_url = ""
|
|
29
|
+
self.tenant_id = args.config.sharepoint_tenant_id
|
|
30
|
+
self.tenant_name = args.config.sharepoint_tenant_name
|
|
31
|
+
self.client_secret = args.config.sharepoint_client_secret
|
|
32
|
+
self.client_id = args.config.sharepoint_client_id
|
|
33
|
+
self.site_name = args.config.sharepoint_site_name
|
|
34
|
+
|
|
35
|
+
async def _load_form_digest_value(self) -> str:
|
|
36
|
+
try:
|
|
37
|
+
response = await self.session.post("contextinfo")
|
|
38
|
+
response_json = await response.json()
|
|
39
|
+
return response_json["FormDigestValue"]
|
|
40
|
+
except ClientError as error:
|
|
41
|
+
raise ConnectionError(error) from error
|
|
42
|
+
|
|
43
|
+
async def _load_credentials(self) -> dict:
|
|
44
|
+
resource_base = "00000003-0000-0ff1-ce00-000000000000"
|
|
45
|
+
resource = f"{resource_base}/{self.tenant_name}.sharepoint.com@{self.tenant_id}"
|
|
46
|
+
url = f"https://accounts.accesscontrol.windows.net/{self.tenant_id}/tokens/OAuth/2"
|
|
47
|
+
payload = {
|
|
48
|
+
"grant_type": "client_credentials",
|
|
49
|
+
"client_id": f"{self.client_id}@{self.tenant_id}",
|
|
50
|
+
"client_secret": self.client_secret,
|
|
51
|
+
"resource": resource,
|
|
52
|
+
}
|
|
53
|
+
headers = {
|
|
54
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async with ClientSession(connector=TCPConnector(ssl=ssl_context)) as session:
|
|
58
|
+
# Load access token
|
|
59
|
+
response = await session.post(url, data=payload, headers=headers)
|
|
60
|
+
if response.status != 200:
|
|
61
|
+
raise ClientError(
|
|
62
|
+
f"Failed to fetch credentials: {response.status}, {await response.text()}"
|
|
63
|
+
)
|
|
64
|
+
response_json = await response.json()
|
|
65
|
+
|
|
66
|
+
return {
|
|
67
|
+
"access_token": response_json["access_token"],
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
async def __aenter__(self) -> "SharepointRestAPI":
|
|
71
|
+
try:
|
|
72
|
+
self.credentials = await self._load_credentials()
|
|
73
|
+
site_url = f"https://{self.tenant_name}.sharepoint.com"
|
|
74
|
+
|
|
75
|
+
self.base_headers = {
|
|
76
|
+
"Authorization": f"Bearer {self.credentials['access_token']}",
|
|
77
|
+
"Accept": "application/json",
|
|
78
|
+
"Content-Type": "application/json",
|
|
79
|
+
}
|
|
80
|
+
self.base_url = f"{site_url}/sites/{self.site_name}/_api/"
|
|
81
|
+
connector = TCPConnector(ssl=ssl_context)
|
|
82
|
+
self.session = ClientSession(
|
|
83
|
+
headers=self.base_headers, base_url=self.base_url, connector=connector
|
|
84
|
+
)
|
|
85
|
+
return self
|
|
86
|
+
except ClientError as error:
|
|
87
|
+
raise ConnectionError(error)
|
|
88
|
+
|
|
89
|
+
async def __aexit__(
|
|
90
|
+
self, _exc_type: type[BaseException], _exc_val: BaseException, _exc_tb: Any
|
|
91
|
+
) -> None:
|
|
92
|
+
await self.session.close()
|
|
93
|
+
|
|
94
|
+
async def list_files(self, args: SpListFilesArgs) -> list:
|
|
95
|
+
try:
|
|
96
|
+
folder_relative_url = (
|
|
97
|
+
f"GetFolderByServerRelativeUrl('{args.folder_relative_url}')"
|
|
98
|
+
)
|
|
99
|
+
endpoint = f"web/{folder_relative_url}/Files"
|
|
100
|
+
response = await self.session.get(endpoint.lstrip("/"))
|
|
101
|
+
response.raise_for_status()
|
|
102
|
+
response_json = await response.json()
|
|
103
|
+
return response_json
|
|
104
|
+
except ClientError as error:
|
|
105
|
+
raise ConnectionError(error) from error
|
|
106
|
+
|
|
107
|
+
async def list_folders(self, args: SpListFoldersArgs) -> list:
|
|
108
|
+
try:
|
|
109
|
+
folder_relative_url = (
|
|
110
|
+
f"GetFolderByServerRelativeUrl('{args.folder_relative_url}')"
|
|
111
|
+
)
|
|
112
|
+
endpoint = f"web/{folder_relative_url}/Folders"
|
|
113
|
+
response = await self.session.get(endpoint.lstrip("/"))
|
|
114
|
+
response.raise_for_status()
|
|
115
|
+
response_json = await response.json()
|
|
116
|
+
return response_json
|
|
117
|
+
except ClientError as error:
|
|
118
|
+
raise ConnectionError(error) from error
|
|
119
|
+
|
|
120
|
+
async def upload_file(self, args: SpUploadFileArgs) -> dict:
|
|
121
|
+
try:
|
|
122
|
+
# Load form digest value
|
|
123
|
+
form_digest_value = await self._load_form_digest_value()
|
|
124
|
+
headers = {
|
|
125
|
+
**self.base_headers,
|
|
126
|
+
"X-RequestDigest": form_digest_value,
|
|
127
|
+
"Content-Type": "application/octet-stream",
|
|
128
|
+
}
|
|
129
|
+
# Upload the file in the requested folder
|
|
130
|
+
folder_relative_url = (
|
|
131
|
+
f"GetFolderByServerRelativeUrl('{args.folder_relative_url}')"
|
|
132
|
+
)
|
|
133
|
+
data = args.file_content
|
|
134
|
+
|
|
135
|
+
endpoint = f"web/{folder_relative_url}/Files/add(url='{args.file_name}',overwrite=true)"
|
|
136
|
+
response = await self.session.post(endpoint, data=data, headers=headers)
|
|
137
|
+
|
|
138
|
+
response.raise_for_status()
|
|
139
|
+
return await response.json()
|
|
140
|
+
except ClientError as error:
|
|
141
|
+
raise ConnectionError(error) from error
|
|
142
|
+
|
|
143
|
+
async def create_folder(self, args: SpCreateFolderArgs):
|
|
144
|
+
try:
|
|
145
|
+
# Load form digest value
|
|
146
|
+
form_digest_value = await self._load_form_digest_value()
|
|
147
|
+
headers = {
|
|
148
|
+
**self.base_headers,
|
|
149
|
+
"X-RequestDigest": form_digest_value,
|
|
150
|
+
}
|
|
151
|
+
body = {"ServerRelativeUrl": f"{args.folder_relative_url}"}
|
|
152
|
+
endpoint = "web/folders"
|
|
153
|
+
response = await self.session.post(
|
|
154
|
+
endpoint.lstrip("/"), data=json.dumps(body), headers=headers
|
|
155
|
+
)
|
|
156
|
+
response.raise_for_status()
|
|
157
|
+
response_json = await response.json()
|
|
158
|
+
return response_json
|
|
159
|
+
except ClientError as error:
|
|
160
|
+
raise ConnectionError(error) from error
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
from .clients.sharepoint_rest_api import SharepointRestAPI
|
|
2
|
+
from .sharepoint_client_contract import SharepointClientContract
|
|
3
|
+
from .types.sharepoint_client_types import (
|
|
4
|
+
SharepointClientInitArgs,
|
|
5
|
+
SpListFilesArgs,
|
|
6
|
+
SpListFoldersArgs,
|
|
7
|
+
SpUploadFileArgs,
|
|
8
|
+
SpCreateFolderArgs,
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class SharepointClient(SharepointClientContract):
|
|
13
|
+
CLIENTS = {"sharepoint_rest_api"}
|
|
14
|
+
|
|
15
|
+
def __init__(self, args: SharepointClientInitArgs):
|
|
16
|
+
if args.client_name not in SharepointClient.CLIENTS:
|
|
17
|
+
msg = f"Unsupported client {args.client_name}"
|
|
18
|
+
raise KeyError(msg)
|
|
19
|
+
elif args.client_name == "sharepoint_rest_api":
|
|
20
|
+
self.client_obj = SharepointRestAPI(args)
|
|
21
|
+
|
|
22
|
+
@property
|
|
23
|
+
def tenant_id(self):
|
|
24
|
+
return self.client_obj.tenant_id
|
|
25
|
+
|
|
26
|
+
@property
|
|
27
|
+
def tenant_name(self):
|
|
28
|
+
return self.client_obj.tenant_name
|
|
29
|
+
|
|
30
|
+
@property
|
|
31
|
+
def site_name(self):
|
|
32
|
+
return self.client_obj.site_name
|
|
33
|
+
|
|
34
|
+
@property
|
|
35
|
+
def client_id(self):
|
|
36
|
+
return self.client_obj.client_id
|
|
37
|
+
|
|
38
|
+
@property
|
|
39
|
+
def client_secret(self):
|
|
40
|
+
return self.client_obj.client_secret
|
|
41
|
+
|
|
42
|
+
async def __aenter__(self):
|
|
43
|
+
return await self.client_obj.__aenter__()
|
|
44
|
+
|
|
45
|
+
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
|
46
|
+
await self.client_obj.__aexit__(exc_type, exc_val, exc_tb)
|
|
47
|
+
|
|
48
|
+
async def list_files(self, args: SpListFilesArgs) -> list:
|
|
49
|
+
return await self.client_obj.list_files(args)
|
|
50
|
+
|
|
51
|
+
async def list_folders(self, args: SpListFoldersArgs) -> list:
|
|
52
|
+
return await self.client_obj.list_folders(args)
|
|
53
|
+
|
|
54
|
+
async def upload_file(self, args: SpUploadFileArgs) -> dict:
|
|
55
|
+
return await self.client_obj.upload_file(args)
|
|
56
|
+
|
|
57
|
+
async def create_folder(self, args: SpCreateFolderArgs) -> dict:
|
|
58
|
+
return await self.client_obj.create_folder(args)
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
|
|
3
|
+
from .types.sharepoint_client_types import (
|
|
4
|
+
SpListFilesArgs,
|
|
5
|
+
SpListFoldersArgs,
|
|
6
|
+
SpUploadFileArgs,
|
|
7
|
+
SpCreateFolderArgs,
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class SharepointClientContract(ABC):
|
|
12
|
+
@abstractmethod
|
|
13
|
+
async def list_files(self, args: SpListFilesArgs) -> list:
|
|
14
|
+
pass
|
|
15
|
+
|
|
16
|
+
@abstractmethod
|
|
17
|
+
async def list_folders(self, args: SpListFoldersArgs) -> list:
|
|
18
|
+
pass
|
|
19
|
+
|
|
20
|
+
@abstractmethod
|
|
21
|
+
async def upload_file(self, args: SpUploadFileArgs) -> dict:
|
|
22
|
+
pass
|
|
23
|
+
|
|
24
|
+
@abstractmethod
|
|
25
|
+
async def create_folder(self, args: SpCreateFolderArgs) -> dict:
|
|
26
|
+
pass
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
@dataclass
|
|
6
|
+
class SharepointClientInitArgs:
|
|
7
|
+
config: Any
|
|
8
|
+
client_name: str = "sharepoint_rest_api"
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclass
|
|
12
|
+
class SpListFilesArgs:
|
|
13
|
+
folder_relative_url: str
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass
|
|
17
|
+
class SpListFoldersArgs:
|
|
18
|
+
folder_relative_url: str
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@dataclass
|
|
22
|
+
class SpUploadFileArgs:
|
|
23
|
+
folder_relative_url: str
|
|
24
|
+
file_name: str
|
|
25
|
+
file_content: bytes = bytes()
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@dataclass
|
|
29
|
+
class SpCreateFolderArgs:
|
|
30
|
+
folder_relative_url: str
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
from datetime import datetime
|
|
2
|
+
from zoneinfo import ZoneInfo
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def today(timezone: str = "America/Santiago") -> datetime:
|
|
6
|
+
"""
|
|
7
|
+
Return the current date.
|
|
8
|
+
|
|
9
|
+
:param timezone: A string representing the IANA timezone name.
|
|
10
|
+
Defaults to "America/Santiago".
|
|
11
|
+
:return datetime:
|
|
12
|
+
"""
|
|
13
|
+
return datetime.now(tz=ZoneInfo(timezone))
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def datetime_to_str(date: datetime, date_format: str = "%m/%d/%Y, %H:%M:%S") -> str:
|
|
17
|
+
"""
|
|
18
|
+
Convert a datetime object to a string in the specified format.
|
|
19
|
+
|
|
20
|
+
:param date: The datetime object to convert.
|
|
21
|
+
:param date_format: The format to convert the datetime object to.
|
|
22
|
+
Defaults to "%Y-%m-%dT%H:%M:%S".
|
|
23
|
+
:return: A string in the specified format.
|
|
24
|
+
"""
|
|
25
|
+
return date.strftime(date_format)
|
|
File without changes
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
from typing import Any, Dict
|
|
2
|
+
|
|
3
|
+
from .controllers.upload_backup_to_sharepoint import (
|
|
4
|
+
UploadBackupToSharepointControllerInput,
|
|
5
|
+
)
|
|
6
|
+
from .controllers.upload_backup_to_sharepoint import UploadBackupToSharepointController
|
|
7
|
+
from saviialib.general_types.api.saviia_backup_api_types import SaviiaBackupConfig
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class SaviiaBackupAPI:
|
|
11
|
+
"""
|
|
12
|
+
EpiiAPI is a service class that provides methods to interact with Patagonia Center system.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
def __init__(self, config: SaviiaBackupConfig):
|
|
16
|
+
self.config = config
|
|
17
|
+
|
|
18
|
+
async def upload_backup_to_sharepoint(
|
|
19
|
+
self, local_backup_source_path: str, sharepoint_destination_path: str
|
|
20
|
+
) -> Dict[str, Any]:
|
|
21
|
+
"""Migrate a backup folder from Home assistant to Sharepoint directory.
|
|
22
|
+
Args:
|
|
23
|
+
local_backup_source_path (str): Local path to backup.
|
|
24
|
+
Returns:
|
|
25
|
+
response (dict): A dictionary containing the response from the upload operation.
|
|
26
|
+
This dictionary will typically include information about the success or
|
|
27
|
+
failure of the upload, as well as any relevant metadata.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
controller = UploadBackupToSharepointController(
|
|
31
|
+
UploadBackupToSharepointControllerInput(
|
|
32
|
+
self.config, local_backup_source_path, sharepoint_destination_path
|
|
33
|
+
)
|
|
34
|
+
)
|
|
35
|
+
response = await controller.execute()
|
|
36
|
+
return response.__dict__
|
|
File without changes
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from dataclasses import dataclass, field
|
|
2
|
+
from typing import Dict
|
|
3
|
+
|
|
4
|
+
from saviialib.general_types.api.saviia_backup_api_types import SaviiaBackupConfig
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@dataclass
|
|
8
|
+
class UploadBackupToSharepointControllerInput:
|
|
9
|
+
config: SaviiaBackupConfig
|
|
10
|
+
local_backup_source_path: str
|
|
11
|
+
sharepoint_destination_path: str
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@dataclass
|
|
15
|
+
class UploadBackupToSharepointControllerOutput:
|
|
16
|
+
message: str
|
|
17
|
+
status: int
|
|
18
|
+
metadata: Dict[str, str] = field(default_factory=dict)
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
from http import HTTPStatus
|
|
2
|
+
from saviialib.general_types.api.saviia_api_types import SharepointConfig
|
|
3
|
+
|
|
4
|
+
from saviialib.general_types.error_types.api.saviia_api_error_types import (
|
|
5
|
+
BackupUploadError,
|
|
6
|
+
BackupSourcePathError,
|
|
7
|
+
BackupEmptyError,
|
|
8
|
+
)
|
|
9
|
+
from saviialib.general_types.error_types.common.common_types import (
|
|
10
|
+
EmptyDataError,
|
|
11
|
+
SharepointClientError,
|
|
12
|
+
)
|
|
13
|
+
from saviialib.services.backup.controllers.types.upload_backup_to_sharepoint_types import (
|
|
14
|
+
UploadBackupToSharepointControllerInput,
|
|
15
|
+
UploadBackupToSharepointControllerOutput,
|
|
16
|
+
)
|
|
17
|
+
from saviialib.services.backup.use_cases.types.upload_backup_to_sharepoint_types import (
|
|
18
|
+
UploadBackupToSharepointUseCaseInput,
|
|
19
|
+
)
|
|
20
|
+
from saviialib.services.backup.use_cases.upload_backup_to_sharepoint import (
|
|
21
|
+
UploadBackupToSharepointUsecase,
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class UploadBackupToSharepointController:
|
|
26
|
+
def __init__(self, input: UploadBackupToSharepointControllerInput):
|
|
27
|
+
self.use_case = UploadBackupToSharepointUsecase(
|
|
28
|
+
UploadBackupToSharepointUseCaseInput(
|
|
29
|
+
sharepoint_config=SharepointConfig(
|
|
30
|
+
sharepoint_client_id=input.config.sharepoint_client_id,
|
|
31
|
+
sharepoint_client_secret=input.config.sharepoint_client_secret,
|
|
32
|
+
sharepoint_site_name=input.config.sharepoint_site_name,
|
|
33
|
+
sharepoint_tenant_name=input.config.sharepoint_tenant_name,
|
|
34
|
+
sharepoint_tenant_id=input.config.sharepoint_tenant_id,
|
|
35
|
+
),
|
|
36
|
+
local_backup_source_path=input.local_backup_source_path,
|
|
37
|
+
sharepoint_destination_path=input.sharepoint_destination_path,
|
|
38
|
+
logger=input.config.logger,
|
|
39
|
+
)
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
async def execute(self) -> UploadBackupToSharepointControllerOutput:
|
|
43
|
+
try:
|
|
44
|
+
data = await self.use_case.execute()
|
|
45
|
+
return UploadBackupToSharepointControllerOutput(
|
|
46
|
+
message="Local backup was migrated successfully",
|
|
47
|
+
status=HTTPStatus.OK.value,
|
|
48
|
+
metadata={"data": data}, # type: ignore
|
|
49
|
+
)
|
|
50
|
+
except EmptyDataError:
|
|
51
|
+
return UploadBackupToSharepointControllerOutput(
|
|
52
|
+
message="No files to upload", status=HTTPStatus.NO_CONTENT.value
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
except (AttributeError, NameError, ValueError) as error:
|
|
56
|
+
return UploadBackupToSharepointControllerOutput(
|
|
57
|
+
message="An unexpected error occurred during use case initialization.",
|
|
58
|
+
status=HTTPStatus.BAD_REQUEST.value,
|
|
59
|
+
metadata={"error": error.__str__()},
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
except SharepointClientError as error:
|
|
63
|
+
return UploadBackupToSharepointControllerOutput(
|
|
64
|
+
message="Sharepoint Client initialization fails.",
|
|
65
|
+
status=HTTPStatus.INTERNAL_SERVER_ERROR.value,
|
|
66
|
+
metadata={"error": error.__str__()},
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
except BackupUploadError as error:
|
|
70
|
+
return UploadBackupToSharepointControllerOutput(
|
|
71
|
+
message="An error occurred during local backup",
|
|
72
|
+
status=HTTPStatus.MULTI_STATUS.value,
|
|
73
|
+
metadata={"error": error.__str__()},
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
except BackupSourcePathError as error:
|
|
77
|
+
return UploadBackupToSharepointControllerOutput(
|
|
78
|
+
message="Invalid local backup source path provided.",
|
|
79
|
+
status=HTTPStatus.BAD_REQUEST.value,
|
|
80
|
+
metadata={"error": error.__str__()},
|
|
81
|
+
)
|
|
82
|
+
except BackupEmptyError as error:
|
|
83
|
+
return UploadBackupToSharepointControllerOutput(
|
|
84
|
+
message="Each folder in the backup folder is empty. Check out again",
|
|
85
|
+
status=HTTPStatus.EXPECTATION_FAILED.value,
|
|
86
|
+
metadata={"error": error.__str__()},
|
|
87
|
+
)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from saviialib.general_types.api.saviia_api_types import SharepointConfig
|
|
3
|
+
from logging import Logger
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@dataclass
|
|
7
|
+
class UploadBackupToSharepointUseCaseInput:
|
|
8
|
+
sharepoint_config: SharepointConfig
|
|
9
|
+
local_backup_source_path: str
|
|
10
|
+
sharepoint_destination_path: str
|
|
11
|
+
logger: Logger
|