Skip to content

Commit

Permalink
add attachment support
Browse files Browse the repository at this point in the history
## Todo
- delete temporary file
- clear TMP_attachments folder in some period
  • Loading branch information
Deutscher775 committed Aug 28, 2024
1 parent 508daa2 commit a992209
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 29 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,8 @@ src/Bot/nerimity_servers/1528027692992208896.json
>>>>>>> Stashed changes
src/Bot/config.py
src/tokens.json
src/astroidapi.zip
src/astroidapi/beta_config.py
src/Bot/config.py
src/tokens.json
src/tokens.json
Empty file.
42 changes: 42 additions & 0 deletions src/astroidapi/attachment_processor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import requests
import astroidapi.errors as errors
import pathlib
import random
import pathlib
import string

async def download_attachment(attachment_url):
try:
response = requests.get(attachment_url)
if response.status_code == 200:
if int(response.headers["content-length"]) > 50 * 1024 * 1024: # value in B -> KB -> MB
raise errors.AttachmentProcessError.AttachmentDownloadError.AttachmentTooLarge("Attachment is too large. Maximum size is 50MB.")
print(f"Downloafing attachment from {attachment_url}. Size: {int(response.headers['content-length'])*1024}KB")
attachment = response.content
attachment_name = attachment_url.split('/')[-1]
attachment_type = attachment_name.split('.')[-1]
id_chars = string.ascii_lowercase + string.digits
attachment_id = "".join(random.choices(id_chars, k=16))
attachment_path = f"{pathlib.Path(__file__).parent.resolve()}/TMP_attachments/{attachment_id}.{attachment_type}"
with open(attachment_path, 'wb') as file:
file.write(attachment)
return file
else:
raise errors.AttachmentProcessError.AttachmentDownloadError.AttachmentDownloadError(f"Received invalid Statuscode. Statuscode: {response.status_code}")
except Exception as e:
raise errors.AttachmentProcessError.AttachmentDownloadError.AttachmentDownloadError(f"Error downloading attachment. Error: {e}")


def clear_temporary_attachments():
try:
path = f"{pathlib.Path(__file__).parent.resolve()}/TMP_attachments"
for file in pathlib.Path(path).iterdir():
file.unlink()
except Exception as e:
raise errors.AttachmentProcessError.AttachmentClearError.DeletionError(f"Error deleting temporary attachments. Error: {e}")

def clear_temporary_attachment(attachment_path):
try:
pathlib.Path(attachment_path.replace("\\", "/")).unlink()
except Exception as e:
raise errors.AttachmentProcessError.AttachmentClearError.DeletionError(f"Error deleting temporary attachment. Error: {e}")
2 changes: 1 addition & 1 deletion src/astroidapi/endpoint_update_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ async def update_endpoint(
else:
endpoint_data["meta"]["message"]["attachments"].append(val)
else:
endpoint_data["meta"]["message"]["attachments"] = []
endpoint_data["meta"]["message"]["attachments"] = [message_attachments]

if message_embed:
embed_object = json.loads(message_embed.replace("'", '"'))
Expand Down
26 changes: 26 additions & 0 deletions src/astroidapi/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,3 +184,29 @@ class EndpointMetaDataError(Exception):
def __init__(self, message):
self.message = message
super().__init__(self.message)

class AttachmentProcessError:
class AttachmentDownloadError:
class AttachmentNotFound(Exception):
def __init__(self, message):
self.message = message
super().__init__(self.message)

class AttachmentDownloadError(Exception):
def __init__(self, message):
self.message = message
super().__init__(self.message)

class AttachmentTooLarge(Exception):
def __init__(self, message):
self.message = message
super().__init__(self.message)

class AttachmentClearError:
class DeletionError(Exception):
def __init__(self, message):
self.message = message
super().__init__(self.message)



73 changes: 45 additions & 28 deletions src/astroidapi/sending_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import astroidapi.surrealdb_handler as surrealdb_handler
import astroidapi.read_handler as read_handler
import astroidapi.formatter as formatter
import astroidapi.attachment_processor as attachment_processor
import os


class SendingHandler():
Expand All @@ -18,69 +20,76 @@ async def distribute(cls, endpoint, updated_json):
try:
sender = updated_json["meta"]["sender"]

if len(updated_json["meta"]["message"]["attachments"]) > 0:
attachments = []
for attachment in updated_json["meta"]["message"]["attachments"]:
file = await attachment_processor.download_attachment(attachment)
attachments.append(file)
else:
attachments = None

if sender == "guilded":
await cls.send_from_guilded(updated_json, endpoint)
await cls.send_from_guilded(updated_json, endpoint, attachments)
if sender == "discord":
await cls.send_from_discord(updated_json, endpoint)
await cls.send_from_discord(updated_json, endpoint, attachments)
if sender == "revolt":
await cls.send_from_revolt(updated_json, endpoint)
await cls.send_from_revolt(updated_json, endpoint, attachments)
if sender == "nerimity":
await cls.send_from_nerimity(updated_json, endpoint)
await cls.send_from_nerimity(updated_json, endpoint, attachments)
return True
except Exception as e:
raise errors.SendingError.DistributionError(e)



@classmethod
async def send_from_discord(cls, updated_json, endpoint):
async def send_from_discord(cls, updated_json, endpoint, attachments: list = None):
try:
asyncio.create_task(cls.send_to_revolt(updated_json, endpoint))
asyncio.create_task(cls.send_to_guilded(updated_json, endpoint))
asyncio.create_task(cls.send_to_revolt(updated_json, endpoint, attachments))
asyncio.create_task(cls.send_to_guilded(updated_json, endpoint, attachments))
if updated_json["config"]["isbeta"] is True:
asyncio.create_task(cls.send_to_nerimity(updated_json, endpoint))
asyncio.create_task(cls.send_to_nerimity(updated_json, endpoint, attachments))
except Exception as e:
raise errors.SendingError.SendFromDiscordError(e)


@classmethod
async def send_from_nerimity(cls, updated_json, endpoint):
async def send_from_nerimity(cls, updated_json, endpoint, attachments: list = None):
try:
asyncio.create_task(cls.send_to_discord(updated_json, endpoint))
asyncio.create_task(cls.send_to_discord(updated_json, endpoint, attachments))
if updated_json["config"]["isbeta"] is True:
asyncio.create_task(cls.send_to_guilded(updated_json, endpoint))
asyncio.create_task(cls.send_to_guilded(updated_json, endpoint, attachments))
if updated_json["config"]["isbeta"] is True:
asyncio.create_task(cls.send_to_revolt(updated_json, endpoint))
asyncio.create_task(cls.send_to_revolt(updated_json, endpoint, attachments))
return True
except Exception as e:
raise errors.SendingError.SendFromNerimiryError(e)

@classmethod
async def send_from_revolt(cls, updated_json, endpoint):
async def send_from_revolt(cls, updated_json, endpoint, attachments: list = None):
try:
asyncio.create_task(cls.send_to_discord(updated_json, endpoint))
asyncio.create_task(cls.send_to_discord(updated_json, endpoint, attachments))
if updated_json["config"]["isbeta"] is True:
asyncio.create_task(cls.send_to_guilded(updated_json, endpoint))
asyncio.create_task(cls.send_to_guilded(updated_json, endpoint, attachments))
if updated_json["config"]["isbeta"] is True:
asyncio.create_task(cls.send_to_nerimity(updated_json, endpoint))
asyncio.create_task(cls.send_to_nerimity(updated_json, endpoint, attachments))
return True
except Exception as e:
raise errors.SendingError.SendFromRevoltError(e)

@classmethod
async def send_from_guilded(cls, updated_json, endpoint):
async def send_from_guilded(cls, updated_json, endpoint, attachments: list = None):
try:
asyncio.create_task(cls.send_to_discord(updated_json, endpoint))
asyncio.create_task(cls.send_to_discord(updated_json, endpoint, attachments))
if updated_json["config"]["isbeta"] is True:
asyncio.create_task(cls.send_to_nerimity(updated_json, endpoint))
asyncio.create_task(cls.send_to_nerimity(updated_json, endpoint, attachments))
if updated_json["config"]["isbeta"] is True:
asyncio.create_task(cls.send_to_revolt(updated_json, endpoint))
asyncio.create_task(cls.send_to_revolt(updated_json, endpoint, attachments))
return True
except Exception as e:
raise errors.SendingError.SendFromGuildedError(e)

@classmethod
async def send_to_discord(cls, updated_json, endpoint):
async def send_to_discord(cls, updated_json, endpoint, attachments: list = None):
try:
read_discord = await read_handler.ReadHandler.check_read(endpoint, "discord")
if read_discord is False:
Expand All @@ -92,9 +101,13 @@ async def send_to_discord(cls, updated_json, endpoint):
webhook = updated_json["config"]["webhooks"]["discord"][updated_json["config"]["channels"]["revolt"].index(updated_json["meta"]["sender-channel"])]
else:
raise errors.SendingError.ChannelNotFound(f'The channel {updated_json["meta"]["sender-channel"]} ({updated_json["meta"]["sender"]}) does not seem to be a registered channel on other platforms.')
nextcord_files = []
if attachments is not None:
for attachment in attachments:
nextcord_files.append(nextcord.File(attachment.name, filename=attachment.name.split("/")[-1]))
async with aiohttp.ClientSession() as session:
webhook_obj = nextcord.Webhook.from_url(webhook, session=session)
await webhook_obj.send(content=updated_json["meta"]["message"]["content"], avatar_url=updated_json["meta"]["message"]["author"]["avatar"], username=formatter.Format.format_username(updated_json["meta"]["message"]["author"]["name"]))
await webhook_obj.send(content=updated_json["meta"]["message"]["content"], avatar_url=updated_json["meta"]["message"]["author"]["avatar"], username=formatter.Format.format_username(updated_json["meta"]["message"]["author"]["name"]), files=nextcord_files)
await session.close()
asyncio.create_task(read_handler.ReadHandler.mark_read(endpoint, "discord"))
print("Sent to discord")
Expand All @@ -108,7 +121,7 @@ async def send_to_discord(cls, updated_json, endpoint):


@classmethod
async def send_to_guilded(cls, updated_json, endpoint):
async def send_to_guilded(cls, updated_json, endpoint, attachments: list = None):
try:
read_guilded = await read_handler.ReadHandler.check_read(endpoint, "guilded")
if read_guilded is False:
Expand All @@ -120,11 +133,15 @@ async def send_to_guilded(cls, updated_json, endpoint):
webhook = updated_json["config"]["webhooks"]["guilded"][updated_json["config"]["channels"]["revolt"].index(updated_json["meta"]["sender-channel"])]
else:
raise errors.SendingError.ChannelNotFound(f'The channel {updated_json["meta"]["sender-channel"]} ({updated_json["meta"]["sender"]}) does not seem to be a registered channel on other platforms.')
guilded_files = []
if attachments is not None:
for attachment in attachments:
guilded_files.append(guilded.File(attachment.name, filename=attachment.name.split("/")[-1]))
async with aiohttp.ClientSession() as session:
asyncio.create_task(read_handler.ReadHandler.mark_read(endpoint, "guilded"))
webhook_obj = guilded.Webhook.from_url(webhook, session=session)
await webhook_obj.send(content=updated_json["meta"]["message"]["content"], avatar_url=updated_json["meta"]["message"]["author"]["avatar"], username=formatter.Format.format_username(updated_json["meta"]["message"]["author"]["name"]))
await webhook_obj.send(content=updated_json["meta"]["message"]["content"], avatar_url=updated_json["meta"]["message"]["author"]["avatar"], username=formatter.Format.format_username(updated_json["meta"]["message"]["author"]["name"]), files=guilded_files)
await session.close()
asyncio.create_task(read_handler.ReadHandler.mark_read(endpoint, "guilded"))
print("Sent to guilded")
return True
else:
Expand All @@ -136,7 +153,7 @@ async def send_to_guilded(cls, updated_json, endpoint):


@classmethod
async def send_to_nerimity(cls, updated_json, endpoint):
async def send_to_nerimity(cls, updated_json, endpoint, attachments: list = None):
try:
read_nerimity = await read_handler.ReadHandler.check_read(endpoint, "nerimity")
if read_nerimity is False and updated_json["config"]["isbeta"] is True:
Expand Down Expand Up @@ -173,7 +190,7 @@ async def send_to_nerimity(cls, updated_json, endpoint):


@classmethod
async def send_to_revolt(cls, updated_json, endpoint):
async def send_to_revolt(cls, updated_json, endpoint, attachments: list = None):
return True
#if updated_json["meta"]["read"]["revolt"] is False:
# if updated_json["meta"]["sender-channel"] in updated_json["config"]["channels"]["discord"]:
Expand Down

0 comments on commit a992209

Please sign in to comment.