I have an discord bot. whose one function is to find duplicate images from server. After going through less than 500 messages there seems to be a DNS error. is there a way a fix it. I am hosting the bot on solarhosting.cc. On local system bot reachs around 1500 message but on cloud it’s less than 500
def calculate_image_hash(image_data):
return hashlib.md5(image_data).hexdigest()
# Function to process channels
async def process_channels(ctx, image_data, attachment_filename, target_channel_ids=None):
total_channels = len(ctx.guild.text_channels)
processed_channels = 0
processed_messages = 0
processed_attachments = 0
if target_channel_ids:
channels = [ctx.guild.get_channel(channel_id) for channel_id in target_channel_ids]
channels = [channel for channel in channels if channel] # Remove None values
if not channels:
await ctx.send("Invalid channel IDs provided.")
return False
else:
channels = ctx.guild.text_channels
# Blacklist of channel IDs to exclude from search
blacklist_channels = [] # Add channel IDs here
target_channel_set = set(target_channel_ids) if target_channel_ids else set()
blacklist_channels = list(set(blacklist_channels) - target_channel_set)
await ctx.send("Channel Loops Has Started.")
for channel in channels:
# Check if the channel is in the blacklist
if channel.id in blacklist_channels:
continue
processed_channels += 1
print(f"Processing channel: {channel.name} ({processed_channels}/{total_channels})")
try:
async for message in channel.history(limit=None):
for message_attachment in message.attachments:
processed_messages += 1
processed_attachments += 1
# Calculate hash for the attachment at runtime
attachment_hash = calculate_image_hash(await message_attachment.read())
# Compare the hashes directly
if attachment_hash == image_data:
embed = discord.Embed(
title="Match Found",
description=f"#{channel.name}: [{message_attachment.filename}]({message.jump_url})",
color=discord.Color.green()
)
await ctx.send(embed=embed)
print(f"Match Found")
return True
# Apply the check after every 100 messages
if processed_messages % 50 == 0:
print(f"Processed {processed_messages} messages and {processed_attachments} attachments so far...")
await asyncio.sleep(10)
if processed_channels/total_channels == 0.5:
await ctx.send("Half of the server searched.")
if processed_channels/total_channels == 0.8:
await ctx.send("80% of the server searched.")
# Introduce a small delay between requests
await asyncio.sleep(5) # Adjust the delay as needed
except (discord.errors.HTTPException, discord.errors.Forbidden) as e:
print(f"An error occurred while processing channel {channel.name}: {e}")
# Retry processing the current channel
await process_channels(ctx, image_data, attachment_filename, target_channel_ids)
return False
# Command to find matching image
@bot.command()
async def find(ctx, *target_channel_ids: int):
# Check if a message contains an attachment
if not ctx.message.attachments:
await ctx.send("No image attached.")
return
# Get the content and filename of the attached image
attachment = ctx.message.attachments[0]
image_data = await attachment.read()
image_hash = calculate_image_hash(image_data)
try:
found = await process_channels(ctx, image_hash, attachment.filename, target_channel_ids)
except (discord.errors.HTTPException, discord.errors.Forbidden) as e:
print(f"An error occurred while processing channel {channel.name}: {e}")
await asyncio.sleep(60)
found = await process_channels(ctx, image_hash, attachment.filename, target_channel_ids)
if not found:
await ctx.send("No matching image found")
error:
Traceback (most recent call last):
File "/home/container/.local/lib/python3.12/site-packages/aiohttp/connector.py", line 1203, in _create_direct_connection
hosts = await self._resolve_host(host, port, traces=traces)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/container/.local/lib/python3.12/site-packages/aiohttp/connector.py", line 880, in _resolve_host
return await asyncio.shield(resolved_host_task)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/container/.local/lib/python3.12/site-packages/aiohttp/connector.py", line 917, in _resolve_host_with_throttle
addrs = await self._resolver.resolve(host, port, family=self._family)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/container/.local/lib/python3.12/site-packages/aiohttp/resolver.py", line 33, in resolve
infos = await self._loop.getaddrinfo(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/asyncio/base_events.py", line 901, in getaddrinfo
return await self.run_in_executor(
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/concurrent/futures/thread.py", line 58, in run
result = self.fn(*self.args, **self.kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/socket.py", line 963, in getaddrinfo
for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
socket.gaierror: [Errno -3] Temporary failure in name resolution
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/container/.local/lib/python3.12/site-packages/discord/ext/commands/core.py", line 180, in wrapped
ret = await coro(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/container/app.py", line 1077, in find
try:
File "/home/container/app.py", line 1028, in process_channels
async for message in channel.history(limit=None):
File "/home/container/.local/lib/python3.12/site-packages/discord/iterators.py", line 123, in __anext__
return await self.next()
^^^^^^^^^^^^^^^^^
File "/home/container/.local/lib/python3.12/site-packages/discord/iterators.py", line 331, in next
await self.fill_messages()
File "/home/container/.local/lib/python3.12/site-packages/discord/iterators.py", line 354, in fill_messages
data = await self._retrieve_messages(self.retrieve)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/container/.local/lib/python3.12/site-packages/discord/iterators.py", line 378, in _retrieve_messages_before_strategy
data: list[MessagePayload] = await self.logs_from(
^^^^^^^^^^^^^^^^^^^^^
File "/home/container/.local/lib/python3.12/site-packages/discord/http.py", line 285, in request
async with self.__session.request(
File "/home/container/.local/lib/python3.12/site-packages/aiohttp/client.py", line 1197, in __aenter__
self._resp = await self._coro
^^^^^^^^^^^^^^^^
File "/home/container/.local/lib/python3.12/site-packages/aiohttp/client.py", line 581, in _request
conn = await self._connector.connect(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/container/.local/lib/python3.12/site-packages/aiohttp/connector.py", line 544, in connect
proto = await self._create_connection(req, traces, timeout)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/container/.local/lib/python3.12/site-packages/aiohttp/connector.py", line 944, in _create_connection
_, proto = await self._create_direct_connection(req, traces, timeout)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/container/.local/lib/python3.12/site-packages/aiohttp/connector.py", line 1209, in _create_direct_connection
raise ClientConnectorError(req.connection_key, exc) from exc
aiohttp.client_exceptions.ClientConnectorError: Cannot connect to host discord.com:443 ssl:default [Temporary failure in name resolution]
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/container/.local/lib/python3.12/site-packages/discord/ext/commands/bot.py", line 349, in invoke
await ctx.command.invoke(ctx)
File "/home/container/.local/lib/python3.12/site-packages/discord/ext/commands/core.py", line 959, in invoke
await injected(*ctx.args, **ctx.kwargs)
File "/home/container/.local/lib/python3.12/site-packages/discord/ext/commands/core.py", line 189, in wrapped
raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: ClientConnectorError: Cannot connect to host discord.com:443 ssl:default [Temporary failure in name resolution]