Discord bot executes but doesn't function when testing in discord server - mongodb

I've adjusted the main file and added a prefix "?" to my commands
import discord
from discord.ext import commands
import os
import asyncio
client = commands.Bot(command_prefix="?", intents = discord.Intents.all())
async def load():
for filename in os.listdir("./cogs"):
if filename.endswith(".py"):
await client.load_extension(f"cogs.{filename[:-3]}")
async def main():
async with client:
await load()
await client.start(TOKEN)
asyncio.run(main())
and added a simple ping command to test if the bot was working in discord. unfortunately all the commands except for ping does not work
import discord
from discord.ext import commands
from pymongo import MongoClient
bot_channel = BOTCHANNELID
talk_channels = [TALKCHANNELID]
level = ["test1", "test2", "test3"]
levelnum = [2,4,6]
cluster = MongoClient("MONGODBCODE")
levelling = cluster["NAME"]["NAME2"]
class levelsys(commands.Cog):
def __init__(self,client):
self.client = client
#commands.Cog.listener()
async def on_ready(self):
print("Ready!")
#commands.Cog.listener()
async def on_message(self, message):
if message.channel.id in talk_channels:
stats = levelling.find_one({"id" : message.author.id})
if not message.author.bot:
if stats is None:
newuser = {"id" : message.author.id, "xp" : 1}
levelling.insert_one(newuser)
else:
xp = stats["xp"] + 5
levelling.update_one({"id":message.author.id}, {"$set":{"xp":xp}})
lvl = 0
while True:
if xp < ((50*(lvl**2))+(50*(lvl-1))):
break
lvl += 1
xp -= ((50*((lvl-1)**2))+(50*(lvl-1)))
if xp == 0:
await message.channel.send(f"gz {message.author.mention} ! you lvled up to **level: {lvl}**")
for i in range(len(level)):
if lvl == levelnum[i]:
await message.author.add_roles(discord.utils.get(message.author.guild.roles, name=level[i]))
embed = discord.Embed(description=f"{message.author.mention} you have gotten role **{level[i]}**")
embed.set_thumbnail(url=message.author.avatar_url)
await message.channel.send(embed=embed)
#commands.command()
async def rank(self, ctx):
if ctx.channel.id == bot_channel:
stats = levelling.find_one({"id" : ctx.author.id})
if stats is None:
embed = discord.Embed(description="you haven't been studying lil bro")
await ctx.channel.send(embed=embed)
else:
xp = stats["xp"]
lvl = 0
rank = 0
while True:
if xp < ((50*(lvl**2))+(50*lvl)):
break
lvl += 1
xp -= ((50*((lvl-1)**2))+(50*(lvl-1)))
boxes = int((xp/(200*((1/2) * lvl)))*20)
rankings = levelling.find().sort("xp",-1)
for x in rankings:
rank += 1
if stats["id"] == x["id"]:
break
embed = discord.Embed(title="{}'s level stats".format(ctx.author.name))
embed.add_field(name="Name", value=ctx.author.mention, inline=True)
embed.add_field(name="XP", value=f"{xp}/{int(200*((1/2)*lvl))}", inline=True)
embed.add_field(name="Rank", value=f"{rank}/{ctx.guild.member_count}", inline=True)
embed.add_field(name="Progress Bar [lvl]", value=boxes * ":blue_square:" + (20-boxes) * ":white_large_squares:", inline = False)
embed.add_field(name='Level', value=f'{lvl}', inline=True)
embed.set_thumbnail(url=ctx.author.avatar_url)
await ctx.channel.send(embed=embed)
#commands.command()
async def dashboard(self, ctx):
if (ctx.channel.id == bot_channel):
rankings = levelling.find().sort("xp",-1)
i = 1
embed = discord.Embed(title="Rankings:")
for x in rankings:
try:
temp = ctx.guild.get_member(x["id"])
tempxp = x["xp"]
embed.add_field(name=f"{i}: {temp.name}", value=f"Total XP: {tempxp}", inline=False)
i += 1
except:
pass
if i == 11:
break
await ctx.channel.send(embed=embed)
#commands.command()
async def ping(self, ctx):
bot_latency = round(self.client.latency * 1000)
await ctx.send(f"Your ping is {bot_latency} ms !.")
async def setup(client):
await client.add_cog(levelsys(client))
I'm not too sure how I would go about fixing all the other commands to get them working. All help is much appreciated !

Related

Why does kivy keep freezing when using python sockets?

I'm working on a basic client-server desktop app project using kivy & sockets & threading.
The client & server work on it's own, however when I try to integrate it with kivy, python & kivy don't want to respond & yet no definitive error pops up.
Could i have some ideas as to how to fix this?
This is the code that freezes when i run it, if i take away the import server_sock it works as a general gui and doesnt freeze.
import kivy
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.gridlayout import GridLayout
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.clock import Clock
import server_sock
import sys
kivy.require("2.1.0") #latest version
class ConnectPage(GridLayout):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.cols = 2
self.add_widget(Label(text="IP:"))
self.ip = TextInput(multiline=False)
self.add_widget(self.ip)
self.add_widget(Label(text="PORT:"))
self.port = TextInput(multiline=False)
self.add_widget(self.port)
self.add_widget(Label(text="USERNAME:"))
self.user = TextInput(multiline=False)
self.add_widget(self.user)
self.join = Button(text="Join")
self.join.bind(on_press=self.join_button)
self.add_widget(Label())
self.add_widget(self.join)
def join_button(self, instance):
port = self.port.text
ip = self.ip.text
user = self.user.text
info = f"Attempting to join {ip}:{port} as {user}"
chat_app.info_page.update_info(info)
chat_app.screen_manager.current = "Info"
Clock.shedule_once(self.connect,1)
def connect(self, _):
port = int(self.port.text)
ip = self.ip.text
user = self.user.text
try:
server_sock.connect(ip, port)
chat_app.create_chat_page()
chat_app.screen_manager.current = "Chat"
except:
show_error(message="not gonna happen")
class InfoPage(GridLayout):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.cols = 1
self.message = Label(halign="center", valign="middle", font_size="30")
self.message.bind(width=self.update_text_width)
self.add_widget(self.message)
def update_info(self,message):
self.message.text = message
def update_text_width(self, *_):
self.message.text_size = (self.message.width*0.9, None)
class ChatPage(GridLayout):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.cols = 1
self.add_widget(Label(text="Hey at least it works till now"))
class ChatApp(App):
def build(self):
self.screen_manager = ScreenManager()
self.connect_page = ConnectPage()
screen = Screen(name="Connect")
screen.add_widget(self.connect_page)
self.screen_manager.add_widget(screen)
self.info_page = InfoPage()
screen= Screen(name="Info")
screen.add_widget(self.info_page)
self.screen_manager.add_widget(screen)
return self.screen_manager
def create_chat_page(self):
self.chat_page = ChatPage()
screen = Screen(name="Chat")
screen.add_widget(self.chat_page)
self.screen_manager.add_widget(screen)
def show_error(message):
chat_app.info_page.update_info(message)
chat_app.screen_manager.current = "Info"
Clock.shedule_once(sys.exit, 10)
if __name__ == "__main__":
chat_app =ChatApp()
chat_app.run()
This is the server_sock file
import socket
import threading
import socket
HOST = '127.0.0.1'
PORT = 55555
server = socket.socket(
socket.AF_INET,
socket.SOCK_STREAM
)
try:
server.bind((HOST, PORT))
except:
print(f'unable to bind to {HOST} and {PORT}')
server.listen()
print(f"Listening for connections on {HOST}: {PORT}")
clients = []
nicknames = []
def broadcast(message):
for client in clients:
client.send(message)
def message_recv(client):
while True:
try:
message = client.recv(2048)
broadcast(message)
except:
index = clients.index(client)
clients.remove(client)
nickname = nicknames[index]
broadcast(f'{nickname} left the chat'.encode('ascii'))
nicknames.remove(nickname)
break
def recieve():
while True:
client, address = server.accept()
print(f"Connected with {str(address)}")
client.send("SOMETHING".encode('ascii'))
nickname = client.recv(2048).decode('ascii')
nicknames.append(nickname)
clients.append(client)
print(f"Nickname of the client is {nickname}")
broadcast(f"{nickname} joined the chat".encode('ascii'))
client.send("Connected to the server".encode('ascii'))
thread = threading.Thread(target=message_recv, args=(client,))
thread.start()
print("Server is listening")
recieve()

Running an asyncoio socket server and client on the same process for tests

I wrote a socket server and client package with asyncio that happens to be a single module with two classes Server and Client. The intention is to have the code check if the specified port is in use on the same device, and if so, it will choose the use the Client class instead of the Server class. I am doing this to enable local testing between client and server for a larger goal.
I wrote my unit test with pytest and I can get it to pass if I run the server in its own process first, then run the client in another process.
However, I want to test both server and client together in the same process using pytest. The test never completes this way, however.
Am I running into an issue with asyncio here? Or is it an issue with pytest? Or is it something I am doing wrong in my code?
WebSockets.websocket
import asyncio
class Server:
def __init__(self, host, port):
self.host = host
self.port = port
self.server = None
self.connections = {}
async def start(self):
self.server = server = await asyncio.start_server(self.handle_client, self.host, self.port)
addr = server.sockets[0].getsockname()
print(f'Serving on {addr}')
async with server:
await server.serve_forever()
async def handle_client(self, reader, writer):
addr = writer.get_extra_info('peername')
print(f'New connection from {addr}')
self.connections[addr] = writer
try:
while not reader.at_eof():
data = await reader.read(100)
message = data.decode()
if message:
print(f'Received {message!r} from {addr}')
await self.send(message, addr)
finally:
del self.connections[addr]
writer.close()
async def send(self, message, addr):
writer = self.connections.get(addr)
if not writer:
return
writer.write(message.encode())
await writer.drain()
async def recv(self, addr):
reader, _ = await asyncio.open_connection(addr[0], addr[1])
data = await reader.read(100)
return data.decode()
async def stop(self):
await self.server.close()
class Client:
def __init__(self, host, port):
self.host = host
self.port = port
self.reader = None
self.writer = None
async def connect(self):
self.reader, self.writer = await asyncio.open_connection(self.host, self.port)
async def send(self, message):
self.writer.write(message.encode())
async def recv(self):
data = await self.reader.read(100)
return data.decode()
async def close(self):
self.writer.close()
Test
import socket
import asyncio
from WebSockets.websocket import Server, Client
import pytest
def check_port(address, port):
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((address, port))
s.close()
return "server"
except OSError:
return "client"
async def serve():
server = Server('localhost', 8910)
await server.start()
async def client_connect():
client = Client('localhost', 8910)
await client.connect()
await client.send("Hello world!")
message = await client.recv()
if message:
print(f"Received {message!r} from server")
assert message == "Hello world!"
await client.close()
#pytest.mark.asyncio
async def test_sockets():
if check_port("localhost", 8910) == "server":
await serve()
# for reference on how to use in non pytest module
# loop = asyncio.new_event_loop()
# loop.run_until_complete(serve())
# loop.close()
else:
await client_connect()
# for reference on how to use in non pytest module
# loop = asyncio.new_event_loop()
# loop.run_until_complete(client_connect())
# loop.close()

OSError: [WinError 10038] An operation was attempted on something that is not a socket what is the problem?

im running a chat app on my computer and i tried to send a message and this ERROR accured. it suppose to send a " will joind the chat" and another message " connected to server" after that i should send my message to the group and it didnt worked.
any ideas?
import kivy
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
import socket
import threading
kivy.require("1.9.0")
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
class MyRoot(BoxLayout):
def __init__(self):
super(MyRoot, self).__init__()
def send_message(self):
client.send(f"{self.nickname_text.text}: {self.message_text.text}".encode('utf-8'))
def connect_to_server(self):
if self.nickname_text != "":
client.connect((self.ip_text.text, 9999))
message = client.recv(1024).decode('utf-8')
if message == "NICK":
client.send(self.nickname_text.text.encode('utf-8'))
self.send_btn.disabled = False
self.message_text.disabled = False
self.connect_btn.disabled = True
self.ip_text.disabled = True
self.make_invisible(self.connection_grid)
self.make_invisible(self.connect_btn)
thread = threading.Thread(target=self.receive)
thread.start()
def make_invisible(self, widget):
widget.visible = False
widget.size_hint_x = None
widget.size_hint_y = None
widget.height = 0
widget.width = 0
widget.text = ""
widget.opacity = 0
def receive(self):
stop = False
while not stop:
try:
message = client.recv(1024).decode('utf-8')
self.chat_text.text += message + "\n"
except:
print("ERROR")
client.close()
stop = True
class TraboChat(App):
def build(self):
return MyRoot()
trabo_chat = TraboChat()
trabo_chat.run()
serve.py:
import socket
import threading
HOST = socket.gethostbyname(socket.gethostname())
PORT = 9999
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((HOST, PORT))
server.listen()
clients = []
nicknames = []
def broadcast(message):
for client in clients:
client.send(message)
def handle_connection(client):
stop = False
while not stop:
try:
message = client.recv(1024)
broadcast(message)
except:
index = clients.index(client)
clients.remove(client)
nickname = nicknames[index]
nicknames.remove(nickname)
broadcast(f"{nickname} left the chat!".encode('utf-8'))
stop = True
def main():
print("server is running..")
while True:
client, addr = server.accept()
print(f"connected to {addr}")
client.send("NICK".encode('utf-8'))
nickname = client.recv(1024).decode('utf-8')
nicknames.append(nickname)
clients.append(client)
print(f"Nickname is {nickname}")
broadcast(f"{nickname} join the chat!")
client.send("You are now connected".encode('utf-8'))
thread = threading.Thread(target=handle_connection, args=(client,))
if name == 'main':
main()

How to make A Weather command? (Discord.py)

So I made this weather command down below, but for some reason, it only says the bot is typing, and there gives a error. This is the code:
import requests
#client.command()
async def weather(ctx, *, city: str):
city_name = city
complete_url = base_url + "appid=" + api_key + "&q=" + city_name
response = requests.get(complete_url)
x = response.json()
channel = ctx.message.channel
if x["cod"] != "404":
async with channel.typing():
y = x["main"]
current_temperature = y["temp"]
current_temperature_celsiuis = str(round(current_temperature - 273.15))
current_pressure = y["pressure"]
current_humidity = y["humidity"]
z = x["weather"]
weather_description = z[0]["description"]
weather_description = z[0]["description"]
embed = discord.Embed(title=f"Weather in {city_name}",
color=ctx.guild.me.top_role.color,
timestamp=ctx.message.created_at,)
embed.add_field(name="Descripition", value=f"**{weather_description}**", inline=False)
embed.add_field(name="Temperature(C)", value=f"**{current_temperature_celsiuis}°C**", inline=False)
embed.add_field(name="Humidity(%)", value=f"**{current_humidity}%**", inline=False)
embed.add_field(name="Atmospheric Pressure(hPa)", value=f"**{current_pressure}hPa**", inline=False)
embed.set_thumbnail(url="https://i.ibb.co/CMrsxdX/weather.png")
embed.set_footer(text=f"Requested by {ctx.author.name}")
await channel.send(embed=embed)
else:
await channel.send("City not found.")
But the error I get from this is saying 'main' is a keyerror

server doesn't send data to clients

I have this piece of code for server to handle clients. it properly receive data but when i want to send received data to clients nothing happens.
server
import socket
from _thread import *
class GameServer:
def __init__(self):
# Game parameters
board = [None] * 9
turn = 1
# TCP parameters specifying
self.tcp_ip = socket.gethostname()
self.tcp_port = 9999
self.buffer_size = 2048
self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
self.s.bind((self.tcp_ip, self.tcp_port))
except:
print("socket error, Please try again! ")
self.s.listen(5)
print('Waiting for a connection...')
def messaging(self, conn):
while True:
data = conn.recv(self.buffer_size)
if not data:
break
print("This data from client:", data)
conn.send(data)
def thread_run(self):
while True:
conn, addr = self.s.accept()
print('connected to: ' + addr[0] + " : " + str(addr[1]))
start_new_thread(self.messaging, (conn,))
def main():
gameserver = GameServer()
gameserver.thread_run()
if __name__ == '__main__':
main()
'
I want to if data received completely send to clients by retrieve the address of sender and send it to other clients by means of conn.send() but seems there is no way to do this with 'send()' method.
The piece of client side code
'
def receive_parser(self):
global turn
rcv_data = self.s.recv(4096)
rcv_data.decode()
if rcv_data[:2] == 'c2':
message = rcv_data[2:]
if message[:3] == 'trn':
temp = message[3]
if temp == 2:
turn = -1
elif temp ==1:
turn = 1
elif message[:3] == 'num':
self.set_text(message[3])
elif message[:3] == 'txt':
self.plainTextEdit_4.appendPlainText('client1: ' + message[3:])
else:
print(rcv_data)
'
the receiver method does not receive any data.
I modified your code a little(as I have python 2.7) and conn.send() seems to work fine. You can also try conn.sendall(). Here is the code I ran:
Server code:
import socket
from thread import *
class GameServer:
def __init__(self):
# Game parameters
board = [None] * 9
turn = 1
# TCP parameters specifying
self.tcp_ip = "127.0.0.1"#socket.gethostname()
self.tcp_port = 9999
self.buffer_size = 2048
self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
self.s.bind((self.tcp_ip, self.tcp_port))
except:
print("socket error, Please try again! ")
self.s.listen(5)
print('Waiting for a connection...')
def messaging(self, conn):
while True:
data = conn.recv(self.buffer_size)
if not data:
break
print("This data from client:", data)
conn.send(data)
def thread_run(self):
while True:
conn, addr = self.s.accept()
print('connected to: ' + addr[0] + " : " + str(addr[1]))
start_new_thread(self.messaging, (conn,))
def main():
gameserver = GameServer()
gameserver.thread_run()
main()
Client code:
import socket
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("127.0.0.1", 9999))
def receive_parser():
#global turn
s.sendall("hello world")
rcv_data = s.recv(4096)
# rcv_data.decode()
# if rcv_data[:2] == 'c2':
# message = rcv_data[2:]
# if message[:3] == 'trn':
# temp = message[3]
# if temp == 2:
# turn = -1
# elif temp ==1:
# turn = 1
# elif message[:3] == 'num':
# self.set_text(message[3])
# elif message[:3] == 'txt':
# self.plainTextEdit_4.appendPlainText('client1: ' + message[3:])
# else:
print(rcv_data)
receive_parser()