diff --git a/README.md b/README.md index c1b5b9d..9b93414 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ A python library for interacting with Lemmy ![pythorhead logo](https://raw.githubusercontent.com/db0/pythorhead/main/logo.png) -# Sample Usage +# Sample Post Usage ```python from pythorhead import Lemmy @@ -14,3 +14,19 @@ lemmy.log_in("username", "password") community_id = lemmy.discover_community("botart") lemmy.post.create(community_id, "Hello Lemmy World") ``` + +# Sample Comment Usage + +```python +from pythorhead import Lemmy + +lemmy = Lemmy("https://lemmy.dbzer0.com") +lemmy.log_in("username", "password") + +# getting the first post id +post_id = lemmy.post.list()[0]["post"]["id"] + +# leave a comment +lemmy.comment.create(post_id, "Hello Lemmy World") + +``` diff --git a/pythorhead/comment.py b/pythorhead/comment.py new file mode 100644 index 0000000..407056a --- /dev/null +++ b/pythorhead/comment.py @@ -0,0 +1,228 @@ +from typing import List, Literal, Optional + +from pythorhead.requestor import Request, Requestor +from pythorhead.types import CommentSortType, ListingType + + +class Comment: + def __init__(self): + self._requestor = Requestor() + + def list( # noqa: A003 + self, + community_id: Optional[int] = None, + community_name: Optional[str] = None, + limit: Optional[int] = None, + max_depth: Optional[int] = None, + page: Optional[int] = None, + parent_id: Optional[int] = None, + post_id: Optional[int] = None, + saved_only: Optional[bool] = None, + sort: Optional[CommentSortType] = None, + type_: Optional[ListingType] = None, + ) -> List[dict]: + """ + + Get comments, with various filters. + + Args: + community_id (Optional[int], optional): Defaults to None. + community_name (Optional[str], optional): Defaults to None. + limit (Optional[int], optional): Defaults to None. + max_depth (Optional[int], optional): Defaults to None. + page (Optional[int], optional): Defaults to None. + parent_id (Optional[int], optional): Defaults to None. + post_id (Optional[int], optional): Defaults to None. + saved_only (Optional[bool], optional): Defaults to None. + sort (Optional[CommentSortType], optional): Defaults to None. + type_ (Optional[ListingType], optional): Defaults to None. + + Returns: + List[dict]: list of comments + """ + list_comment = {} + if community_id is not None: + list_comment["community_id"] = community_id + if community_name is not None: + list_comment["community_name"] = community_name + if limit is not None: + list_comment["limit"] = limit + if max_depth is not None: + list_comment["max_depth"] = max_depth + if page is not None: + list_comment["page"] = page + if parent_id is not None: + list_comment["parent_id"] = parent_id + if post_id is not None: + list_comment["post_id"] = post_id + if saved_only is not None: + list_comment["saved_only"] = saved_only + if sort is not None: + list_comment["sort"] = sort + if type_ is not None: + list_comment["type"] = type_ + + if data := self._requestor.request(Request.GET, "/comment/list", params=list_comment): + return data["comments"] + return [] + + def create( + self, + post_id: int, + content: str, + form_id: Optional[str] = None, + parent_id: Optional[int] = None, + language_id: Optional[int] = None, + ) -> Optional[dict]: + """ + Create a comment. + + Args: + post_id (int) + content (str) + form_id (Optional[int], optional): Defaults to None. + parent_id (Optional[int], optional): Defaults to None. + language_id (Optional[int], optional): Defaults to None. + + Returns: + Optional[dict]: created comment data if successful + """ + + create_comment = { + "post_id": post_id, + "content": content, + } + if form_id is not None: + create_comment["form_id"] = form_id + if parent_id is not None: + create_comment["parent_id"] = parent_id + if language_id is not None: + create_comment["language_id"] = language_id + + return self._requestor.request( + Request.POST, + "/comment", + json=create_comment, + ) + + def edit( + self, + comment_id: int, + content: Optional[str] = None, + distinguished: Optional[bool] = None, + form_id: Optional[str] = None, + language_id: Optional[int] = None, + ) -> Optional[dict]: + """ + Edit a comment. + + Args: + comment_id (int) + content (Optional[str], optional): Defaults to None. + distinguished (Optional[bool], optional): Defaults to None. + form_id (Optional[str], optional): Defaults to None. + language_id (Optional[int], optional): Defaults to None. + + Returns: + Optional[dict]: edited comment data if successful + """ + edit_comment: dict = { + "comment_id": comment_id, + } + if content is not None: + edit_comment["content"] = content + if distinguished is not None: + edit_comment["distinguished"] = distinguished + if form_id is not None: + edit_comment["form_id"] = form_id + if language_id is not None: + edit_comment["language_id"] = language_id + + return self._requestor.request( + Request.PUT, + "/comment", + json=edit_comment, + ) + + def like(self, comment_id: int, score: Literal[-1, 0, 1]) -> Optional[dict]: + """ + Like / Dislike a comment. + + Args: + comment_id (int) + score (int) + + Returns: + Optional[dict]: like comment data if successful + """ + return self._requestor.request( + Request.POST, + "/comment/like", + json={ + "comment_id": comment_id, + "score": score, + }, + ) + + def delete(self, comment_id: int, deleted: bool) -> Optional[dict]: + """ + Delete / Restore a comment. + + Args: + comment_id (int): comment_id + deleted (bool): deleted + + Returns: + Optional[dict]: deleted comment data if successful + """ + return self._requestor.request( + Request.POST, + "/comment/delete", + json={ + "comment_id": comment_id, + "deleted": deleted, + }, + ) + + def save(self, comment_id: int, save: bool) -> Optional[dict]: + """ + Add / Remove a comment from saved. + + Args: + comment_id (int) + save (bool) + + Returns: + Optional[dict]: saved comment data if successful + + """ + return self._requestor.request( + Request.PUT, + "/comment/save", + json={ + "comment_id": comment_id, + "save": save, + }, + ) + + def report(self, comment_id: int, reason: str) -> Optional[dict]: + """ + Report a comment. + + Args: + comment_id (int): comment_id + reason (str): reason + + Returns: + Optional[dict]: report comment data if successful + """ + return self._requestor.request( + Request.POST, + "/comment/report", + json={ + "comment_id": comment_id, + "reason": reason, + }, + ) + + __call__ = create diff --git a/pythorhead/lemmy.py b/pythorhead/lemmy.py index bbf7199..0d66e2b 100644 --- a/pythorhead/lemmy.py +++ b/pythorhead/lemmy.py @@ -1,15 +1,16 @@ import logging - from typing import Optional +from pythorhead.comment import Comment from pythorhead.post import Post -from pythorhead.requestor import Requestor, Request +from pythorhead.requestor import Request, Requestor logging.basicConfig(format="%(asctime)s - %(name)s - %(levelname)s - %(message)s") class Lemmy: post: Post + comment: Comment _known_communities = {} _requestor: Requestor @@ -17,6 +18,7 @@ def __init__(self, api_base_url: str) -> None: self._requestor = Requestor() self._requestor.set_api_base_url(f"{api_base_url}/api/v3") self.post = Post() + self.comment = Comment() def log_in(self, username_or_email: str, password: str) -> bool: return self._requestor.log_in(username_or_email, password) diff --git a/pythorhead/post.py b/pythorhead/post.py index 510a84c..584ae2c 100644 --- a/pythorhead/post.py +++ b/pythorhead/post.py @@ -1,7 +1,7 @@ -from typing import Any, Literal, Optional, List +from typing import Any, List, Literal, Optional -from pythorhead.types import FeatureType, ListingType, SortType -from pythorhead.requestor import Requestor, Request +from pythorhead.requestor import Request, Requestor +from pythorhead.types import FeatureType, ListingType, PostSortType class Post: @@ -39,7 +39,7 @@ def list( # noqa: A003 limit: Optional[int] = None, page: Optional[int] = None, saved_only: Optional[bool] = None, - sort: Optional[SortType] = None, + sort: Optional[PostSortType] = None, type_: Optional[ListingType] = None, ) -> List[dict]: """ @@ -202,7 +202,7 @@ def edit( def like(self, post_id: int, score: Literal[-1, 0, 1]) -> Optional[dict]: """ - Like a post + Like / Dislike a post Args: post_id (int) @@ -220,7 +220,7 @@ def like(self, post_id: int, score: Literal[-1, 0, 1]) -> Optional[dict]: def save(self, post_id: int, saved: bool) -> Optional[dict]: """ - Save / Unsave a post + Add / Remove a post to saved posts Args: post_id (int) diff --git a/pythorhead/requestor.py b/pythorhead/requestor.py index c06b788..1955941 100644 --- a/pythorhead/requestor.py +++ b/pythorhead/requestor.py @@ -1,10 +1,10 @@ -import requests import logging - from enum import Enum from typing import Optional -from pythorhead.auth import Authentication +import requests + +from pythorhead.auth import Authentication logger = logging.getLogger(__name__) diff --git a/pythorhead/types/__init__.py b/pythorhead/types/__init__.py index 35f1c31..83ba401 100644 --- a/pythorhead/types/__init__.py +++ b/pythorhead/types/__init__.py @@ -1,3 +1,3 @@ from .feature import FeatureType from .listing import ListingType -from .sort import SortType +from .sort import CommentSortType, PostSortType diff --git a/pythorhead/types/sort.py b/pythorhead/types/sort.py index 5783872..2c66556 100644 --- a/pythorhead/types/sort.py +++ b/pythorhead/types/sort.py @@ -1,7 +1,7 @@ from enum import Enum -class SortType(Enum): +class PostSortType(Enum): Active = "Active" Hot = "Hot" MostComments = "MostComments" @@ -12,3 +12,10 @@ class SortType(Enum): TopMonth = "TopMonth" TopWeek = "TopWeek" TopYear = "TopYear" + + +class CommentSortType(Enum): + Hot = "Hot" + New = "New" + Old = "Old" + Top = "Top"