2024-11-02 20:21:55 +09:00
|
|
|
import datetime, rfeed, requests, re
|
|
|
|
|
|
|
|
# error codes
|
|
|
|
USER_NOT_FOUND = 1
|
|
|
|
CANNOT_ACCESS_INSTANCE = 2
|
|
|
|
INVALID_HANDLE = 3
|
|
|
|
|
|
|
|
|
|
|
|
def get_statuses_of_user(user_handle: str) -> list[dict] | str:
|
2024-11-03 17:44:18 +09:00
|
|
|
# parsed_handle = parse_handle(user_handle)
|
|
|
|
# if parsed_handle is None:
|
|
|
|
# return INVALID_HANDLE
|
|
|
|
[username, instance] = user_handle.split("@")[1:]
|
2024-11-02 20:21:55 +09:00
|
|
|
|
|
|
|
try:
|
|
|
|
account_lookup = requests.get(f"https://{instance}/api/v1/accounts/lookup?acct={username}")
|
|
|
|
except requests.exceptions.RequestException as err:
|
|
|
|
print(err)
|
|
|
|
return CANNOT_ACCESS_INSTANCE
|
|
|
|
|
|
|
|
if not account_lookup.ok:
|
|
|
|
return USER_NOT_FOUND
|
|
|
|
|
|
|
|
account_info = account_lookup.json()
|
|
|
|
user_id = account_info["id"]
|
|
|
|
|
|
|
|
try:
|
|
|
|
statuses_get = requests.get(f"https://{instance}/api/v1/accounts/{user_id}/statuses?exclude_reblogs=true&exclude_replies=true")
|
|
|
|
except requests.exceptions.RequestException as err:
|
|
|
|
print(err)
|
|
|
|
return CANNOT_ACCESS_INSTANCE
|
|
|
|
|
|
|
|
if not statuses_get.ok:
|
|
|
|
return USER_NOT_FOUND
|
|
|
|
|
|
|
|
return statuses_get.json()
|
|
|
|
|
|
|
|
|
|
|
|
def generate_feed_of_user(user_handle: str) -> str | int:
|
|
|
|
# get user's statuses
|
|
|
|
statuses = get_statuses_of_user(user_handle)
|
|
|
|
if type(statuses) is int:
|
|
|
|
return statuses
|
|
|
|
|
|
|
|
# generate rss feed
|
|
|
|
status_items = []
|
|
|
|
for status in statuses:
|
|
|
|
content = status["content"]
|
|
|
|
|
|
|
|
# get media of status
|
|
|
|
for media in status["media_attachments"]:
|
2024-11-03 02:08:43 +09:00
|
|
|
media_url = media["url"]
|
|
|
|
media_description = media["description"]
|
2024-11-02 20:21:55 +09:00
|
|
|
if media["type"] == "image":
|
2024-11-03 02:08:43 +09:00
|
|
|
content += f"<img src='{media_url}' alt='{media_description if not media_description is None else ''}' />"
|
2024-11-02 20:21:55 +09:00
|
|
|
elif media["type"] == "video" or media["type"] == "gifv":
|
2024-11-03 02:08:43 +09:00
|
|
|
content += f"<video><source src='{media_url}'>{f'<p>{media_description}</p>' if not media_description is None else ''}</source></video>"
|
2024-11-02 20:21:55 +09:00
|
|
|
elif media["type"] == "audio":
|
2024-11-03 02:08:43 +09:00
|
|
|
content += f"<audio src='{media_url}' controls></audio>{f'<span>{media_description}</span>' if not media_description is None else ''}"
|
2024-11-02 20:21:55 +09:00
|
|
|
else:
|
2024-11-03 02:08:43 +09:00
|
|
|
content += f"<a href='{media_url}'>{media_description if not media_description is None else media_url}</a>"
|
2024-11-02 20:21:55 +09:00
|
|
|
|
|
|
|
status_items.append(rfeed.Item(
|
|
|
|
description=content,
|
|
|
|
link=status["url"],
|
|
|
|
guid=rfeed.Guid(status["url"]),
|
|
|
|
pubDate=datetime.datetime.strptime(status["created_at"], "%Y-%m-%dT%H:%M:%S.%fZ")
|
|
|
|
))
|
|
|
|
|
|
|
|
feed = rfeed.Feed(
|
|
|
|
title=status["account"]["display_name"],
|
|
|
|
link=status["account"]["url"],
|
|
|
|
description=status["account"]["note"],
|
|
|
|
lastBuildDate=datetime.datetime.now(),
|
|
|
|
items=status_items
|
|
|
|
)
|
|
|
|
|
|
|
|
return feed.rss()
|