Updated Tool#get_subreddit_feed to be the more generic Tool#get_reddit_feed, which can take in both user and subreddit Reddit .json links.
This commit is contained in:
parent
8e6c1549df
commit
c656a67961
@ -170,84 +170,34 @@ class Tools:
|
|||||||
description="The user agent to use when making requests to Reddit."
|
description="The user agent to use when making requests to Reddit."
|
||||||
)
|
)
|
||||||
|
|
||||||
async def get_subreddit_feed(
|
async def get_reddit_feed(
|
||||||
self,
|
self,
|
||||||
subreddit: str,
|
id: str,
|
||||||
|
page_type: RedditPageType,
|
||||||
__event_emitter__: Callable[[dict], Awaitable[None]],
|
__event_emitter__: Callable[[dict], Awaitable[None]],
|
||||||
__user__: dict = {},
|
__user__: dict = {},
|
||||||
) -> str:
|
) -> str:
|
||||||
"""
|
"""
|
||||||
Get the latest posts from a subreddit, as an array of JSON objects with the following properties: 'id', 'title', 'description', 'link', 'author_username', 'author_id', 'subreddit_name', 'subreddit_id', 'subreddit_subscribers', 'score', 'upvotes', 'downvotes', 'upvote_ratio', 'total_comments', 'total_crossposts', 'total_awards', 'domain', 'flair_text', 'media_embed', 'is_pinned', 'is_self', 'is_video', 'is_media_only', 'is_over_18', 'is_edited', 'is_hidden', 'is_archived', 'is_locked', 'is_quarantined', 'is_spoiler', 'is_stickied', 'is_send_replies', 'published_at'.
|
Retrieves the popular posts from a specific feed, either a /u/username or /r/subreddit feed, or the comments on either.
|
||||||
:param subreddit: The subreddit to get the latest posts from.
|
:param id: The ID of the feed to retrieve, such as a username or a subreddit name. Additionally, a post ID can be appended to either to retrieve comments from a specific post.
|
||||||
:return: A list of posts with the previously mentioned properties, or an error message.
|
:param page_type: The type of page to retrieve, must be 'USER', 'SUBREDDIT', 'USER_COMMENTS' or 'SUBREDDIT_COMMENTS'.
|
||||||
|
:return: An object containing a list of posts, comments, and the next ID to use under the 'after' key, or an error message.
|
||||||
|
Note: The 'USER' page_type will retrieve both posts and comments, while the 'SUBREDDIT' page_type will only retrieve posts (unless a post id is provided as well, and the page_type is 'SUBREDDIT_COMMENTS').
|
||||||
"""
|
"""
|
||||||
headers = { "User-Agent": __user__["valves"].USER_AGENT }
|
id = id.replace("/r/", "").replace("/u/", "").replace("u/", "").replace("r/", "") # Strip any /r/ or /u/ from the ID
|
||||||
await __event_emitter__({ "data": { "description": f"Starting retrieval for r/{subreddit}'s Reddit Feed...", "status": "in_progress", "done": False }, "type": "status" })
|
|
||||||
|
|
||||||
if subreddit == "":
|
# This accounts for the type being dropped by OpenWebUI
|
||||||
await __event_emitter__({ "data": { "description": f"Error: No subreddit provided.", "status": "complete", "done": True }, "type": "status" })
|
if not isinstance(page_type, RedditPageType):
|
||||||
return "Error: No subreddit provided"
|
try:
|
||||||
subreddit = subreddit.replace("/r/", "").replace("r/", "")
|
page_type = RedditPageType[page_type]
|
||||||
|
except ValueError:
|
||||||
if not re.match(r"^[A-Za-z0-9_]{2,21}$", subreddit):
|
await __event_emitter__({ "data": { "description": f"Error: Invalid page type '{page_type}', try 'USER', 'SUBREDDIT', 'USER_COMMENTS' or 'SUBREDDIT_COMMENTS'.", "status": "complete", "done": True }, "type": "status" })
|
||||||
await __event_emitter__({ "data": { "description": f"Error: Invalid subreddit name '{subreddit}' (either too long or two short).", "status": "complete", "done": True }, "type": "status" })
|
return f"Error: Invalid page type '{page_type}', try either 'USER', 'SUBREDDIT', 'USER_COMMENTS' or 'SUBREDDIT_COMMENTS'."
|
||||||
return "Error: Invalid subreddit name"
|
|
||||||
|
|
||||||
try:
|
|
||||||
response = requests.get(f"https://reddit.com/r/{subreddit}.json", headers=headers)
|
|
||||||
|
|
||||||
if not response.ok:
|
|
||||||
await __event_emitter__({ "data": { "description": f"Error: Failed to retrieve r/{subreddit}'s Reddit Feed: {response.status_code}.", "status": "complete", "done": True }, "type": "status" })
|
|
||||||
return f"Error: {response.status_code}"
|
|
||||||
else:
|
|
||||||
output = parse_posts(parse_reddit_page(response))
|
|
||||||
await __event_emitter__({ "data": { "description": f"Retrieved {len(output)} posts from r/{subreddit}'s Reddit Feed.", "status": "complete", "done": True }, "type": "status" })
|
|
||||||
return json.dumps(output)
|
|
||||||
except Exception as e:
|
|
||||||
await __event_emitter__({ "data": { "description": f"Failed to retrieve any posts from r/{subreddit}'s Reddit Feed: {e}.", "status": "complete", "done": True }, "type": "status" })
|
|
||||||
return f"Error: {e}"
|
|
||||||
|
|
||||||
|
|
||||||
async def get_user_feed(
|
|
||||||
self,
|
|
||||||
username: str,
|
|
||||||
__event_emitter__: Callable[[dict], Awaitable[None]],
|
|
||||||
__user__: dict = {},
|
|
||||||
) -> str:
|
|
||||||
"""
|
|
||||||
Get the latest posts from a given user, as a JSON object with an array of 'post' objects with the following properties: 'id', 'title', 'description', 'link', 'author_username', 'author_id', 'subreddit_name', 'subreddit_id', 'subreddit_subscribers', 'score', 'upvotes', 'downvotes', 'upvote_ratio', 'total_comments', 'total_crossposts', 'total_awards', 'domain', 'flair_text', 'media_embed', 'is_pinned', 'is_self', 'is_video', 'is_media_only', 'is_over_18', 'is_edited', 'is_hidden', 'is_archived', 'is_locked', 'is_quarantined', 'is_spoiler', 'is_stickied', 'is_send_replies', 'published_at'.
|
|
||||||
Additionally, the resultant object will also contain an array of 'comment' objects with the following properties: 'id', 'body', 'link', 'post_id', 'post_title', 'post_link', 'author_id', 'post_author_username', 'subreddit_name', 'subreddit_id', 'subreddit_subscribers', 'score', 'upvotes', 'downvotes', 'total_comments', 'total_awards', 'is_edited', 'is_archived', 'is_locked', 'is_quarantined', 'is_stickied', 'is_send_replies', 'published_at'.
|
|
||||||
:param username: The username to get the latest posts from.
|
|
||||||
:return: A object with list of posts and a list of comments (both with the previously mentioned properties), or an error message.
|
|
||||||
"""
|
|
||||||
headers = { "User-Agent": __user__["valves"].USER_AGENT }
|
|
||||||
await __event_emitter__({ "data": { "description": f"Starting retrieval for u/{username}'s Reddit Feed...", "status": "in_progress", "done": False }, "type": "status" })
|
|
||||||
|
|
||||||
if username == "":
|
|
||||||
await __event_emitter__({ "data": { "description": f"Error: No username provided.", "status": "complete", "done": True }, "type": "status" })
|
|
||||||
return "Error: No username provided."
|
|
||||||
username = username.replace("/u/", "").replace("u/", "")
|
|
||||||
|
|
||||||
if not re.match(r"^[A-Za-z0-9_]{3,20}$", username):
|
|
||||||
await __event_emitter__({ "data": { "description": f"Error: Invalid username '{username}' (either too long or two short).", "status": "complete", "done": True }, "type": "status" })
|
|
||||||
return "Error: Invalid username."
|
|
||||||
|
|
||||||
try:
|
|
||||||
response = requests.get(f"https://reddit.com/u/{username}.json", headers=headers)
|
|
||||||
|
|
||||||
if not response.ok:
|
|
||||||
await __event_emitter__({ "data": { "description": f"Error: Failed to retrieve u/{username}'s Reddit Feed: {response.status_code}.", "status": "complete", "done": True }, "type": "status" })
|
|
||||||
return f"Error: {response.status_code}"
|
|
||||||
else:
|
|
||||||
page = parse_reddit_page(response) # user pages can have both posts and comments.
|
|
||||||
posts = parse_posts(page)
|
|
||||||
comments = parse_comments(page)
|
|
||||||
await __event_emitter__({ "data": { "description": f"Retrieved {len(posts)} posts and {len(comments)} comments from u/{username}'s Reddit Feed.", "status": "complete", "done": True }, "type": "status" })
|
|
||||||
return json.dumps({ "posts": posts, "comments": comments })
|
|
||||||
except Exception as e:
|
|
||||||
await __event_emitter__({ "data": { "description": f"Failed to retrieve any posts from u/{username}'s Reddit Feed: {e}.", "status": "complete", "done": True }, "type": "status" })
|
|
||||||
return f"Error: {e}"
|
|
||||||
|
|
||||||
|
await __event_emitter__({ "data": { "description": f"Starting retrieval for {page_type.value}/{id}...", "status": "in_progress", "done": False }, "type": "status" })
|
||||||
|
page = RedditPage(id, page_type).get_page()
|
||||||
|
await __event_emitter__({ "data": { "description": f"Retrieved {len(page.posts)} posts and {len(page.comments)} comments from {page_type.value}/{id}.", "status": "complete", "done": True }, "type": "status" })
|
||||||
|
return str(page)
|
||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
|
Loading…
Reference in New Issue
Block a user