How to store JSON.(discord.py) - discord.py

So I tried storing a variable to a json file,but it gives me this error:
Object of type Command is not JSON serializable
The code something like this:
import discord
from discord.ext import commands
import json
num = 0
def store():
with open("num.json", 'w') as file:
json.dump(num, file)
bot = commands.Bot(command_prefix='!')
#bot.command()
async def increase():
num += 1
await ctx.send("I increased your number,now it is: " + num)
store()

Object of type Command is not JSON serializable says, that variable (or entity) you provided can't be transformed (serialized) into the JSON format.
In your case that is because you haven't follow key:value json rule. JSON is similar to the Python's dict (except keys can only be strings). So to be able to store your variable, you have to pass it to the json.dump function as following: {"my_var": num}.
So simply change your code to something like that:
def store():
with open("num.json", 'w') as file:
json.dump({"num": num}, file) #HERE'S THE DEAL! ENTITY SHOULD BE DICT!
bot = commands.Bot(command_prefix='!')
#bot.command()
async def increase():
num += 1
await ctx.send("I increased your number,now it is: " + num)
store()

You didnt open the json file, so you cant write to it.
try this:
num = 0
#bot.command()
async def increase():
num += 1
#opening the json
with open("num.json", "r") as file:
x = json.load(file)
#setting the number
x["num"] = num
#now store it
with open("num.json", "w") as file:
json.dump(file, x, indent=4)
await ctx.send("I increased your number,now it is: " + num)
the num.json should like this (before running the command):
{
"num": 0
}

Related

python coroutine asyncio/ await / aiohttp

new in asyncio world.
going straight to the point...
I want to do/make a request(aiohttp) to a site.
if the wait for an answer pass than N seconds I want to stop the process of waiting.
Do the process again by setting a limit of attempts if needed.
async def search_skiping_add(name_search):
start_time = time()
async with aiohttp.ClientSession() as session:
url = f'https://somesitehere.com'
r = await session.get(url)
final_time = time()
result_time =round(final_time-start_time)
print(result_time)
Maybe, I know, have some way to do it synchronously, but it's an excuse to start using asyncio somehow too.
This should give you an idea of how to use async with aiohttp:
from aiohttp import ClientSession
from asyncio import gather, create_task, sleep, run
from traceback import format_exc
def returnPartionedList(inputlist: list, x: int = 100) -> list: # returns inputlist split into x parts, default is 100
return([inputlist[i:i + x] for i in range(0, len(inputlist), x)])
# You could change validate to an integer and thereby increasing the retry count as needed.
async def GetRessource(url: str, session: ClientSession, validate: bool = False) -> dict:
try:
async with session.get(url) as response:
if response.status == 200:
r: dict = await response.json() # Set equal to .text() to get results as a string
return(r)
else:
r: str = await response.text()
if not validate:
await sleep(3) # Sleep for x amount of seconds before retry
return(await GetRessource(url, session, True))
print(f"Error, got response code: {response.status} message: {r}")
except Exception:
print(f"General Exception:\n{format_exc()}")
return({})
async def GetUrls(urls: list) -> list:
resultsList: list = []
UrlPartitions: list = returnPartionedList(urls, 20) # Rate limit to 20 requests per loop
async with ClientSession(timeout=15) as session: # Timeout is equal to the time to wait in seconds before terminating, default is 300 seconds or 5 minutes.
for partition in UrlPartitions:
partitionTasks: list = [create_task(GetRessource(url, session)) for url in partition]
resultsList.append(await gather(*partitionTasks, return_exceptions=False))
return(resultsList) # Or you can do more processing here before returning
async def main():
urls: list = ["...", "...", "..."] # list of urls to get from
results: list = await GetUrls(urls)
print(results)
if __name__ == "__main__":
run(main())

I'm having a problem with my modmail bot code that was written my discord.py

So, I'm making a modmail bot for my discord server. But when I run, the bot can connect but when I send a test messange in the bot DM, I receive this error: AttributeError: 'NoneType' object has no attribute 'send'.
I'm using python 3.9.1 on Arch Linux. Here is my code:
import discord
from discord.ext.commands import Bot
from discord.ext import commands
import asyncio
client = commands.Bot(command_prefix="!")
#client.event
async def on_ready():
await client.change_presence(activity=discord.Activity(type=discord.ActivityType.watching, name='for moderation mail'))
print("Thunderbird is ready")
#client.event
async def on_message(message):
empty_array = []
modmail_channel = discord.utils.get(client.get_all_channels(), name="modmail-box")
if message.author == client.user:
return
if str(message.channel.type) == "private":
if message.attachments != empty_array:
files = message.attachments
await modmail_channel.send("<#" + message.author.id + ">: ")
for file in files:
await modmail_channel.send(file.url)
else:
await modmail_channel.send("<#" + str(message.author.id) + ">: " + message.content)
elif str(message.channel) == "modmail" and message.content.startswith("<"):
member_object = message.mentions[0]
if message.attachments != empty_array:
files = message.attachments
await member_object.send("**[MOD]** " + "**" + message.author.display_name + "**: ")
for file in files:
await member_object.send(file.url)
else:
index = message.content.index(" ")
string = message.content
mod_message = string[index:]
await member_object.send("**[MOD]** " + "**" + message.author.display_name + "**: " + mod_message)
client.run('No leaking here')
I am assuming that the error is on this line:
await member_object.send("**[MOD]** " + "**" + message.author.display_name + "**: ")
and member_object is coming from this block:
elif str(message.channel) == "modmail" and message.content.startswith("<"):
member_object = message.mentions[0]
if message.attachments != empty_array:
files = message.attachments
await member_object.send("**[MOD]** " + "**" + message.author.display_name + "**: ")
for file in files:
await member_object.send(file.url)
You are defining member_object as the first element in the message.mentions array, however your error of NoneType has no attribute suggests that there are no elements in that array and so member_object is actually equal to None not an instance of a class which has a send method.
You need to check your input to that function and ensure that when your code reaches that block it actually has the attributes that you are expecting

discord.py not finding commands within a class

If I use .join in discord with the code below, I get the following error:
Ignoring exception in command None:
discord.ext.commands.errors.CommandNotFound: Command "join" is not found
I'm not sure how to fix this (this is turning into being part of a music bot). Here is the relevant code:
import discord
import discord.voice_client
from discord import utils
from discord.ext import commands
from discord.utils import *
import discord.utils
import lavalink
bot = commands.Bot(command_prefix= ".", intents=intents)
class MusicCog(commands.Cog):
def __init__(self, bot):
self.bot = bot
self.bot.music = lavalink.Client(self.bot.user.id)
self.bot.music.add_node('localhost', 7000, 'testing', 'na' , 'music-node')
self.bot.add_listener(self.bot.music.voice_update_handler, 'on-socket-response')
self.bot.music.add_event_hook(self.track_hook)
#commands.command(name= 'Join')
async def join(self, ctx):
print("join command worked")
member = utils.find(lambda m: m.id == ctx.author.id, ctx.guild.members)
if member is not None and member.voice is not None:
vc = member.voice.channel
player = self.bot.music.player_manager.create(ctx.guild.id, endpoint= str(ctx.guild.region))
if not player.is_connected:
player.store('channel', ctx.channel.id)
await self.connect_to(ctx.guild.id, str(vc.id))
#commands.command(name= "Play")
async def play(self, ctx, *, query):
try:
player = self.bot.music.player_manager.get(ctx.guild.id)
query = f'ytsearch: {query}'
results = await player.node.get_tracks(query)
tracks = results['tracks'][0:10]
i = 0
query_result = ''
for track in tracks:
i = i + 1
query_result = query_result + f'{i}) {track["info"]["title"]} - {track["info"]["url"]}\n'
show_songs = discord.Embed(
title= None,
description= None,
colour= discord.Colour.blue()
)
show_songs.description = query_result
await ctx.channel.send(embed= show_songs)
def check(m):
return m.author.id == ctx.author.id
response = await self.bot.wait_for('message', check=check)
track = tracks[int(response.conetent)-1]
player.add(requester = ctx.author.id, track = track)
if not player.is_playing:
await player.play()
except Exception as error:
print(error)
async def track_hook(self, event):
if isinstance(event, lavalink.events.QueueEndEvent):
guild_id = int(event.player.guild.id)
await self.connect_to(guild_id, None)
async def connect_to(self, guild_id: int, channel_id: str):
ws = self.bot._connection._get_websocket(guild_id)
await ws.voice_state(str(guild_id), channel_id)
def setup(bot):
bot.add_cog(MusicCog(bot))
I've tried changing #commands.command to #bot.command, which didn't end up working, and I'm almost certain the indentation is correct throughout the code, so at this point, I'm not sure how to fix it. Any help would be appreciated!
By default, commands are case sensitive so you'd have to type .Join or .Play in order to invoke your them.
If you want your commands to be case insensitive, simply type :
bot = commands.Bot(command_prefix='.', intents=intents, case_insensitive=True)
PS : the name argument in the commands.command() decorator refers to what needs to be typed after your prefix to invoke the function.

autobahn mosquitto server chat

I´m trying to connect to a mosquitto broker using autobahn python.
If I use sub.py that has this code inside:
import mosquitto
def on_connect(mosq, obj, rc):
print("rc: "+str(rc))
def on_message(mosq, obj, msg):
print(msg.topic+" "+str(msg.qos)+" "+str(msg.payload))
def on_publish(mosq, obj, mid):
print("mid: "+str(mid))
def on_subscribe(mosq, obj, mid, granted_qos):
print("Subscribed: "+str(mid)+" "+str(granted_qos))
def on_log(mosq, obj, level, string):
print(string)
mqttc = mosquitto.Mosquitto()
mqttc.on_message = on_message
mqttc.on_connect = on_connect
mqttc.on_publish = on_publish
mqttc.on_subscribe = on_subscribe
# Uncomment to enable debug messages
mqttc.on_log = on_log
mqttc.connect("localhost", 1883, 60)
mqttc.subscribe("control", 0)
rc = 0
while rc == 0:
rc = mqttc.loop()
print("rc: "+str(rc))
it is connecting to the broker and retrieving all messages that a client publish to control channel.
I´d like to push somehow those messages using websockets to a webpage for that I am trying to use websocket autobahn py and modify the example from here http://autobahn.ws/python/getstarted#yourfirstserver
My code is like this
import sys
import mosquitto
from twisted.internet import reactor
from twisted.python import log
from autobahn.websocket import WebSocketServerFactory, \
WebSocketServerProtocol, \
listenWS
class EchoServerProtocol(WebSocketServerProtocol):
def on_connect(mosq, obj, rc):
print("rc: "+str(rc))
def on_message(mosq, obj, msg):
print(msg.topic+" "+str(msg.qos)+" "+str(msg.payload))
def onMessage(self, msg, binary):
print "sending echo:", msg
self.sendMessage(msg, binary)
def on_publish(mosq, obj, mid):
print("mid: "+str(mid))
def on_subscribe(mosq, obj, mid, granted_qos):
print("Subscribed: "+str(mid)+" "+str(granted_qos))
mqttc = mosquitto.Mosquitto()
mqttc.on_message = on_message
mqttc.on_connect = on_connect
mqttc.on_publish = on_publish
mqttc.on_subscribe = on_subscribe
# Uncomment to enable debug messages
mqttc.on_log = on_log
mqttc.connect("192.168.2.109", 1883, 60)
mqttc.subscribe("control", 0)
rc = 0
while rc == 0:
rc = mqttc.loop()
print("rc: "+str(rc))
if __name__ == '__main__':
log.startLogging(sys.stdout)
factory = WebSocketServerFactory("ws://192.168.2.109:8899", debug = TRUE)
factory.protocol = EchoServerProtocol
listenWS(factory)
reactor.run()
but I receive this error when I try to run it:
root#Ubuntu:~/authobahn# python myserver.py Traceback (most recent
call last): File "myserver.py", line 30, in
mqttc.on_message = on_message NameError: name 'on_message' is not defined
The problem is that you have defined your on_message() function inside the EchoServerProtocol class. This means it is not visible to the global mqttc variable. You probably want to put all of the mqttc code inside your class as well, although it depends on what you actually want to achieve.
You could do something like the code below:
import mosquitto
class MyMQTTClass:
def __init__(self, clientid=None):
self._mqttc = mosquitto.Mosquitto()
self._mqttc.on_message = self.mqtt_on_message
self._mqttc.on_connect = self.mqtt_on_connect
self._mqttc.on_publish = self.mqtt_on_publish
self._mqttc.on_subscribe = self.mqtt_on_subscribe
def mqtt_on_connect(self, mosq, obj, rc):
print("rc: "+str(rc))
def mqtt_on_message(self, mosq, obj, msg):
print(msg.topic+" "+str(msg.qos)+" "+str(msg.payload))
def mqtt_on_publish(self, mosq, obj, mid):
print("mid: "+str(mid))
def mqtt_on_subscribe(self, mosq, obj, mid, granted_qos):
print("Subscribed: "+str(mid)+" "+str(granted_qos))
def mqtt_on_log(self, mosq, obj, level, string):
print(string)
def run(self):
self._mqttc.connect("test.mosquitto.org", 1883, 60)
self._mqttc.subscribe("$SYS/#", 0)
rc = 0
while rc == 0:
rc = self._mqttc.loop()
return rc
# If you want to use a specific client id, use
# mqttc = MyMQTTClass("client-id")
# but note that the client id must be unique on the broker. Leaving the client
# id parameter empty will generate a random id for you.
mqttc = MyMQTTClass()
rc = mqttc.run()
print("rc: "+str(rc))

Android - Load image on the native side

I am trying to load images so I can use them as textures. I have libpng, but how do find a path to an image? Is it a bad idea to put it into .apk? Is there a better way?
Have a look at this:
http://www.anddev.org/ndk_opengl_-_loading_resources_and_assets_from_native_code-t11978.html
It appears there are two ways of doing it. I can either do what Simon N. has suggested or I can convert the images into a C Array and compile them into the source. I choose to do the latter as I can do it easily on the native side. I have even created a python (v3.2) for converting a png file to a c array header and source file. It requires PyPNG
#!/usr/bin/env python
import png
import re
import itertools
def grouper(n, iterable, fillvalue=None):
args = [iter(iterable)] * n
return itertools.zip_longest(fillvalue=fillvalue, *args)
def expand(array):
new_array = [];
for row in array:
for v in row:
new_array.append(v)
return new_array
def c_array_name(filename):
'''converts the filename to the c array name'''
return re.sub(r'\W', '_', filename)
def c_array_header_filename(filename):
'''converts the filename to the c array header filename'''
return "{0}.h".format(filename)
def c_array_source_filename(filename):
'''converts the filename to the c array source filename'''
return "{0}.cpp".format(filename)
def c_array_header(filename):
'''returns a string that is the c array header,
where
filename is the png file'''
name = c_array_name(filename)
return """
#ifndef __{0}__
#define __{0}__
#include <stdint.h>
extern uint_least32_t const {1}[];
#endif /* __{0}__ */
""".format(name.upper(), name)
def c_array_source(filename, header_filename, array_string):
'''returns a string that is the c array source,
where
name is the value from c_array_name
array_string'''
name = c_array_name(filename)
return """
#include "{0}"
uint_least32_t const {1}[] = {{
{2}
}};
""".format(header_filename, name, array_string)
def convert_data_array_string(data):
'''returns a string of hexes of bytes,
where
data is a map of bytes'''
return ", ".join(["0x{:02x}{:02x}{:02x}{:02x}".format(a, b, g, r)
for r, g, b, a in grouper(4, expand(data), 0)])
def png_data_from_file(path):
'''returns a map of bytes of the png file'''
with open(path, 'rb') as file:
reader = png.Reader(file = file)
data = reader.read();
return list(data[2]);
if __name__ == '__main__':
import sys
import os
if len(sys.argv) != 2:
sys.stdout.write("{0} image_path".format(sys.argv[0]))
exit()
path = sys.argv[1]
filename = os.path.split(path)[1]
header_filename = c_array_header_filename(filename)
sys.stdout.write("Creating header file '{}'... ".format(header_filename))
with open(header_filename, 'w') as header_file:
header_file.write(c_array_header(filename))
sys.stdout.write("done\n")
source_filename = c_array_source_filename(filename)
sys.stdout.write("Creating source file '{}'... ".format(source_filename))
data = png_data_from_file(path)
with open(source_filename, 'w') as source_file:
source_file.write(c_array_source(filename, header_filename, convert_data_array_string(data)))
del data
sys.stdout.write("done\n")

Resources