From 9a4c47bd8e208f69776729a7f295041bef695af6 Mon Sep 17 00:00:00 2001 From: firedotguy Date: Sun, 8 Feb 2026 23:11:59 +0300 Subject: [PATCH] feat: add get and delete files --- itd/client.py | 41 +++++++++++++++++++++++++++++++++++++++-- itd/exceptions.py | 7 +++++++ itd/models/file.py | 2 ++ itd/routes/files.py | 7 +++++++ itd/routes/hashtags.py | 8 -------- 5 files changed, 55 insertions(+), 10 deletions(-) diff --git a/itd/client.py b/itd/client.py index 20d704e..c63b8b1 100644 --- a/itd/client.py +++ b/itd/client.py @@ -14,7 +14,7 @@ from itd.routes.notifications import get_notifications, mark_as_read, mark_all_a from itd.routes.posts import create_post, get_posts, get_post, edit_post, delete_post, pin_post, repost, view_post, get_liked_posts, restore_post, like_post, unlike_post, get_user_posts from itd.routes.reports import report from itd.routes.search import search -from itd.routes.files import upload_file +from itd.routes.files import upload_file, get_file, delete_file from itd.routes.auth import refresh_token, change_password, logout from itd.routes.verification import verify, get_verification_status from itd.routes.pins import get_pins, remove_pin, set_pin @@ -37,7 +37,7 @@ from itd.exceptions import ( NoCookie, NoAuthData, SamePassword, InvalidOldPassword, NotFound, ValidationError, UserBanned, PendingRequestExists, Forbidden, UsernameTaken, CantFollowYourself, Unauthorized, CantRepostYourPost, AlreadyReposted, AlreadyReported, TooLarge, PinNotOwned, NoContent, - AlreadyFollowing + AlreadyFollowing, NotFoundOrForbidden ) @@ -952,6 +952,43 @@ class Client: return File.model_validate(res.json()) + @refresh_on_error + def get_file(self, id: UUID) -> File: + """Получить файл + + Args: + id (UUID): UUID файла + + Raises: + NotFoundOrForbidden: Файл не найден или нет доступа + + Returns: + File: Файл + """ + res = get_file(self.token, id) + if res.json().get('error', {}).get('code') == 'NOT_FOUND': + raise NotFoundOrForbidden('File') + res.raise_for_status() + + return File.model_validate(res.json()) + + @refresh_on_error + def delete_file(self, id: UUID) -> File: + """Удалить файл + + Args: + id (UUID): UUID файла + + Raises: + NotFound: Файл не найден + """ + res = delete_file(self.token, id) + if res.json().get('error', {}).get('code') == 'NOT_FOUND': + raise NotFound('File') + res.raise_for_status() + + return File.model_validate(res.json()) + def update_banner(self, name: str) -> UserProfileUpdate: """Обновить банер (шорткат из upload_file + update_profile) diff --git a/itd/exceptions.py b/itd/exceptions.py index 3484f11..e8a8b51 100644 --- a/itd/exceptions.py +++ b/itd/exceptions.py @@ -37,6 +37,13 @@ class NotFound(Exception): def __str__(self): return f'{self.obj} not found' +class NotFoundOrForbidden(Exception): + def __init__(self, obj: str): + self.obj = obj + def __str__(self): + return f'{self.obj} not found or access denied' + + class UserBanned(Exception): def __str__(self): return 'User banned' diff --git a/itd/models/file.py b/itd/models/file.py index 635df8c..dd38135 100644 --- a/itd/models/file.py +++ b/itd/models/file.py @@ -1,4 +1,5 @@ from uuid import UUID +from datetime import datetime from pydantic import BaseModel, Field @@ -10,6 +11,7 @@ class File(BaseModel): filename: str mime_type: str = Field(alias='mimeType') size: int + created_at: datetime | None = Field(None, alias='createdAt') class PostAttach(BaseModel): diff --git a/itd/routes/files.py b/itd/routes/files.py index 9303b82..c8c3bb0 100644 --- a/itd/routes/files.py +++ b/itd/routes/files.py @@ -1,7 +1,14 @@ from _io import BufferedReader +from uuid import UUID from itd.request import fetch def upload_file(token: str, name: str, data: BufferedReader): return fetch(token, 'post', 'files/upload', files={'file': (name, data)}) + +def get_file(token: str, id: UUID): + return fetch(token, 'get', f'files/{id}') + +def delete_file(token: str, id: UUID): + return fetch(token, 'delete', f'files/{id}') \ No newline at end of file diff --git a/itd/routes/hashtags.py b/itd/routes/hashtags.py index cd4a836..83f3a93 100644 --- a/itd/routes/hashtags.py +++ b/itd/routes/hashtags.py @@ -2,16 +2,8 @@ from warnings import deprecated from uuid import UUID from itd.request import fetch -@deprecated("get_hastags устарела используйте get_hashtags") -def get_hastags(token: str, limit: int = 10): - return fetch(token, 'get', 'hashtags/trending', {'limit': limit}) - def get_hashtags(token: str, limit: int = 10): return fetch(token, 'get', 'hashtags/trending', {'limit': limit}) -@deprecated("get_posts_by_hastag устерла используй get_posts_by_hashtag") -def get_posts_by_hastag(token: str, hashtag: str, limit: int = 20, cursor: UUID | None = None): - return fetch(token, 'get', f'hashtags/{hashtag}/posts', {'limit': limit, 'cursor': cursor}) - def get_posts_by_hashtag(token: str, hashtag: str, limit: int = 20, cursor: UUID | None = None): return fetch(token, 'get', f'hashtags/{hashtag}/posts', {'limit': limit, 'cursor': cursor})