Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Support for more endpoints #90

Merged
merged 1 commit into from
Mar 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions pythorhead/community.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ def create(
title: str,
description: Optional[str] = None,
icon: Optional[str] = None,
banner: Optional[str] = None,
nsfw: Optional[bool] = None,
posting_restricted_to_mods: Optional[bool] = None,
discussion_languages: Optional[List[Union[int, LanguageType]]] = None,
Expand Down Expand Up @@ -53,6 +54,39 @@ def create(

return self._requestor.api(Request.POST, "/community", json=new_community)

def edit(
self,
community_id: int,
title: Optional[str] = None,
description: Optional[str] = None,
icon: Optional[str] = None,
banner: Optional[str] = None,
nsfw: Optional[bool] = None,
posting_restricted_to_mods: Optional[bool] = None,
discussion_languages: Optional[List[Union[int, LanguageType]]] = None,
) -> Optional[dict]:
"""
Edit a community

Args:
name (str)
title (str)
description (str, optional): Defaults to None
icon (str, optional): Defaults to None
nsfw (bool, optional): Defaults to None
posting_restricted_to_mods (bool, optional): Defaults to None
discussion_languages: (List[Union[int, LanguageType]], optional): Defaults to None

Returns:
Optional[dict]: post data if successful
"""
params: dict[str, Any] = {key: value for key, value in locals().items() if value is not None and key != "self"}
if discussion_languages is not None:
params["discussion_languages"] = [
language.value for language in discussion_languages if isinstance(language, LanguageType)
]
return self._requestor.api(Request.PUT, "/community", json=params)

def get(self, id: Optional[int] = None, name: Optional[str] = None) -> Optional[dict]:
"""
Get a community by id or name
Expand Down
89 changes: 59 additions & 30 deletions pythorhead/image.py
Original file line number Diff line number Diff line change
@@ -1,46 +1,75 @@
from os.path import basename
from typing import Optional

from PIL import Image as PillowImage
from pythorhead.requestor import Request, Requestor
from io import BytesIO


class Image:
def __init__(self, _requestor: Requestor) -> None:
self._requestor = _requestor

def upload(self, image_path: str) -> Optional[dict]:
def upload(self, image):
"""

Upload an image

Args:
image_path (str)
image (str, PIL.Image): Image ins str or PIL format

Returns:
Optional[dict]: pictrs upload data, if successful
"""
data = None
if isinstance(image, str):
with open(image, "rb") as image_bytes:
data = self._requestor.image(
Request.POST,
files={"images[]": image_bytes},
)
else:
img: PillowImage = image
img_byte_array = BytesIO()
image_bytes = img.save(img_byte_array, format='webp', quality=95)
img_byte_array.seek(0)

data = self._requestor.image(
Request.POST,
files={"images[]": img_byte_array},
)
if data and "files" in data:
for file in data["files"]:
file["image_url"] = "/".join(
(
self._requestor._auth.image_url,
file["file"],
),
)
file["delete_url"] = "/".join(
(
self._requestor._auth.image_url,
"delete",
file["delete_token"],
file["file"],
),
)
del file["file"]
del file["delete_token"]

return data["files"]

def delete(self, image_delete_url: str):
"""

Delete an lemmy image via pictrs

Args:
image_delete_url (str): The pictrs delete URL

Returns:
Optional[dict]: image data if successful
bool: True is succesfully deleted
"""
with open(image_path, "rb") as image:
data = self._requestor.image(
Request.POST,
files={"images[]": image},
)
if data and "files" in data:
for file in data["files"]:
file["image_url"] = "/".join(
(
self._requestor._auth.image_url,
file["file"],
),
)
file["delete_url"] = "/".join(
(
self._requestor._auth.image_url,
"delete",
file["delete_token"],
file["file"],
),
)
del file["file"]
del file["delete_token"]

return data["files"]
req = self._requestor.image_del(
Request.GET,
image_delete_url,
)
return req.ok
4 changes: 4 additions & 0 deletions pythorhead/lemmy.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ def __init__(self, api_base_url: str, raise_exceptions = False, request_timeout=
def nodeinfo(self):
return self._requestor.nodeinfo

@property
def username(self):
return self._requestor.logged_in_username

def log_in(self, username_or_email: str, password: str, totp: Optional[str] = None) -> bool:
return self._requestor.log_in(username_or_email, password, totp)

Expand Down
17 changes: 17 additions & 0 deletions pythorhead/requestor.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class Requestor:
domain: Optional[str] = None
raise_exceptions: Optional[bool] = False
request_timeout: Optional[int] = 3
logged_in_username: Optional[str] = None

def __init__(self, raise_exceptions = False, request_timeout = 3):
self._auth = Authentication()
Expand Down Expand Up @@ -109,6 +110,17 @@ def image(self, method: Request, **kwargs) -> Optional[dict]:
return
return r.json()

def image_del(self, method: Request, image_delete_url:str, **kwargs) -> Optional[dict]:
logger.info(f"Deleting image {method}")
cookies = {}
if self._auth.token:
cookies["jwt"] = self._auth.token
r = REQUEST_MAP[method](image_delete_url, cookies=cookies, timeout=self.request_timeout, **kwargs)
if not r.ok:
logger.error(f"Error encountered while {method}: {r.text}")
return
return r

def log_in(self, username_or_email: str, password: str, totp: Optional[str] = None) -> bool:
payload = {
"username_or_email": username_or_email,
Expand All @@ -117,7 +129,12 @@ def log_in(self, username_or_email: str, password: str, totp: Optional[str] = No
}
if data := self.api(Request.POST, "/user/login", json=payload):
self._auth.set_token(data["jwt"])
self.logged_in_username = username_or_email
return self._auth.token is not None

def log_out(self) -> None:
self._auth.token = None
self.logged_in_username = None

def is_logged_in(self) -> bool:
return self.logged_in_username is not None
1 change: 1 addition & 0 deletions pythorhead/types/sort.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class SortType(str, Enum):
TopTwelveHour = "TopTwelveHour"
NewComments = "NewComments"
MostComments = "MostComments"
Scaled = "Scaled"


class CommentSortType(str, Enum):
Expand Down
45 changes: 43 additions & 2 deletions pythorhead/user.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from typing import Any, List, Literal, Optional, Union
from datetime import datetime
from pythorhead.requestor import Request, Requestor
from pythorhead.types import SortType
from pythorhead.types import SortType, ListingType, LanguageType


class User:
Expand Down Expand Up @@ -89,4 +89,45 @@ def ban(
if remove_data is not None:
user_ban["remove_data"] = remove_data

return self._requestor.api(Request.POST, "/user/ban", json=user_ban)
return self._requestor.api(Request.POST, "/user/ban", json=user_ban)

def save_user_settings(
self,
show_nsfw: Optional[bool] = None,
blur_nsfw: Optional[bool] = None,
auto_expand: Optional[bool] = None,
show_scores: Optional[bool] = None,
theme: Optional[str] = None,
default_sort_type: Optional[SortType] = None,
default_listing_type: Optional[ListingType] = None,
interface_language: Optional[str] = None,
avatar: Optional[str] = None,
banner: Optional[str] = None,
display_name: Optional[str] = None,
email: Optional[str] = None,
bio: Optional[str] = None,
matrix_user_id: Optional[str] = None,
show_avatars: Optional[bool] = None,
send_notifications_to_email: Optional[bool] = None,
bot_account: Optional[bool] = None,
show_bot_accounts: Optional[bool] = None,
show_read_posts: Optional[bool] = None,
discussion_languages: Union[int, LanguageType, None] = None,
open_links_in_new_tab: Optional[bool] = None,
infinite_scroll_enabled: Optional[bool] = None,
post_listing_mode: Optional[str] = None,
enable_keyboard_navigation: Optional[bool] = None,
enable_animated_images: Optional[bool] = None,
collapse_bot_comments: Optional[bool] = None,

) -> Optional[dict]:
"""
Get user details with various filters.

Args:
TBD
Returns:
dict: user view
"""
params: dict[str, Any] = {key: value for key, value in locals().items() if value is not None and key != "self"}
return self._requestor.api(Request.PUT, "/user/save_user_settings", json=params)