-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcloud_folder.py
More file actions
124 lines (106 loc) · 4.64 KB
/
Copy pathcloud_folder.py
File metadata and controls
124 lines (106 loc) · 4.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import requests
import time
from typing import Dict, Optional, Union
from requests import Response
from settings import logger
class CloudFolder:
"""Описывает папку на облачном сервисе"""
main_url = 'https://cloud-api.yandex.net/v1/disk/'
def __init__(self, path: str, token: str) -> None:
"""
Инициализация объекта CloudFolder.
:param path: Путь к папке в облаке.
:param token: OAuth токен для авторизации.
"""
self.path = path
self.headers = {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': f'OAuth {token}'
}
self.local: Union[bool, 'Folder'] = False
def is_connected(self) -> None:
"""
Проверяет, есть ли локальный аналог у облачной папки.
:raises Exception: Если локального аналога нет.
"""
if not self.local:
raise Exception('У облачной папки нет локального аналога!')
def create_remote_path(self, filename: str) -> str:
"""
Создает удаленный путь для файла.
:param filename: Имя файла.
:return: Полный путь к файлу в облаке.
"""
return f'{self.path}/{filename}'
def connect(self, url: str, headers: Optional[Dict[str, str]] = None,
params: Optional[Dict[str, str]] = None,
data: Optional[Union[bytes, str]] = None, method: str = 'GET') -> Optional[Response]:
"""
Устанавливает соединение с облачным сервисом.
:param url: URL для запроса.
:param headers: Заголовки для запроса.
:param params: Параметры для запроса.
:param data: Данные для запроса.
:param method: Метод запроса (GET, POST, PUT, DELETE).
:return: Ответ сервера.
"""
while True:
try:
response = requests.request(method, url, headers=headers, params=params, data=data, timeout=10)
if response.status_code // 100 == 2:
return response
else:
logger.error((response.status_code, response.text))
except Exception as e:
logger.error(e)
time.sleep(2)
def get_files_list(self) -> Dict[str, Dict[str, str]]:
"""
Получает список файлов на облаке в виде словаря.
:return: Словарь с информацией о файлах.
"""
url = self.main_url + 'resources/'
params = {
'path': self.path,
'fields': 'name, _embedded.items.path, _embedded.items.name, _embedded.items.modified'
}
response = self.connect(url, params=params, headers=self.headers)
files = {}
if response:
for file in response.json()["_embedded"]["items"]:
files[file["name"]] = {
'name': file["name"],
"path": file["path"],
"modified": file["modified"]
}
return files
def upload_file(self, filename: str) -> None:
"""
Загружает файл на облако.
:param filename: Имя файла для загрузки.
"""
self.is_connected()
url = self.main_url + 'resources/upload/'
params = {
'path': self.create_remote_path(filename),
'overwrite': 'true',
}
upload_url = self.connect(url, headers=self.headers, params=params)
if upload_url:
url = upload_url.json()["href"]
with open(self.local.create_local_path(filename), 'rb') as file:
self.connect(url, data=file, method="PUT")
logger.success(f'Файл {filename} успешно выгружен в облако!')
def delete_file(self, filename: str) -> None:
"""
Удаляет файл с облака.
:param filename: Имя файла для удаления.
"""
url = self.main_url + 'resources/'
params = {
'path': self.create_remote_path(filename),
'permanently': 'true',
}
self.connect(url, headers=self.headers, params=params, method='DELETE')
logger.info(f'Файл {filename} успешно удален!')