Praw blocking subreddits - python

Hi I'm trying to block a few subreddits in praw like FiftyFifty but I cant find the command for something like that this is also for a discord bot my code is here
#client.command()
async def r(ctx,subred = ""):
subreddit = reddit.subreddit(subred)
all_subs = []
top = subreddit.top(limit = 50)
for submission in top:
all_subs.append(submission)
random_sub = random.choice(all_subs)
name = random_sub.title
url = random_sub.url
if not submission.over_18:
em = discord.Embed(title = name)
em.set_image(url = url)
await ctx.send(embed = em)
else:
await ctx.send("NO")

This might be a possible solution
bannedSubreddits = ["FiftyFifty", "various", "other", "subreddits"] #Add as many subreddits as you'd like here or just add one
#client.command()
async def r(ctx,subred = ""):
subreddit = reddit.subreddit(subred)
for bannedSub in bannedSubreddits:
if subreddit == reddit.subreddit(bannedSub): #If a banned subreddit is detected, it sends what you wanted to send when you find an over 18 post
await ctx.send("NO")
return
all_subs = []
top = subreddit.top(limit = 50)
for submission in top:
all_subs.append(submission)
random_sub = random.choice(all_subs)
name = random_sub.title
url = random_sub.url
if not submission.over_18:
em = discord.Embed(title = name)
em.set_image(url = url)
await ctx.send(embed = em)
else:
await ctx.send("NO")

Related

Getting duplicate Network Response Playwright Python

I have a working script but when I changed the page.on in playwright it actually runs the network response a certain number of times as per the loop count. I have been trying to figure out why that happens.
For example at i=0 it gives one response.url print but at i=10 it prints response.url 10 times and then send 10 duplicate data to mongodb. I have no idea why this is happening. The link being sent based on the print are all the same.
Would be a great help if anyone can let me know what it is that I am doing wrong that is causing this issue.
Pls see sample code here.
#imports here
today = datetime.today().strftime("%m%d%Y")
filenamearr = []
mongousername = 'XXX'
mongopassword = 'XXXX'
client = MongoClient("mongodb+srv://%s:%s#XXXXX.XXXX.mongodb.net/?retryWrites=true&w=majority"%(mongousername,mongopassword))
db = client.DB1
logg = []
async def runbrowser(playwright,url):
async def handle_response(response,buttonnumber):
l = str(response.url)
para = 'param'
if para in l:
print(response.url)
textdata = await response.text()
subtask = asyncio.create_task(jsonparse(textdata))
done, pending = await asyncio.wait({subtask})
if subtask in done:
print("Success in Json parser")
result = await subtask
status = [buttonnumber,result]
logg.append(status)
print(status)
logdf = pd.DataFrame(logg)
logdf.columns = ['BUTTON','RESULT']
fname = 'XXXX' + today +".csv"
logdf.to_csv(fname,index=False)
async def jsonparse(textdata):
try:
#parsing happens here to output to MongoDB
return "Success"
except Exception as e:
print("Failled parsing")
return e
browser = await playwright.firefox.launch(
headless=True,
)
context = await browser.new_context(
locale='en-US',
ignore_https_errors = True,
)
page = await context.new_page()
await page.goto(url,timeout=0)
button = page.locator("xpath=//button[#event-list-item='']")
bcount = button.locator(":scope",has_text="Locator")
count = await bcount.count()
print(count)
for i in range(count):
print("\n\n\n\n\nSleeping 10 seconds before clicking button")
buttonnumber = i
await asyncio.sleep(10)
print("Clickking Button: ", i)
cbtn = bcount.nth(i)
await cbtn.hover()
await asyncio.sleep(4)
await cbtn.click()
if i==0:
print("i=0")
await page.reload(timeout=0)
retry = page.on("response",lambda response: handle_response(response,buttonnumber))
title = await page.title()
print(title)
print("Heading back to the main page.")
await page.go_back(timeout=0)
await page.reload()
await page.wait_for_timeout(5000)
await page.close()
print("Closing Tab")
await browser.close()
async def main():
tasks = []
async with async_playwright() as playwright:
url = 'https://samplelink.com'
tasks.append(asyncio.create_task(runbrowser(playwright,url)))
for t in asyncio.as_completed(tasks):
print(await t)
await asyncio.gather(*tasks)
asyncio.run(main())

My meme command is slow. How do I make it respond faster?

I have two meme commands. They have two subreddits and that take random memes from that.
Here is my code
sreddits_list = ['dankruto', 'narutomemes']
#bot.command(aliases=['narutomeme', 'narmeme', 'nmeme'])
async def Nmeme(ctx):
subreddit = await reddit.subreddit(random.choice(sreddits_list))
all_subs = []
top = subreddit.top(limit = 50)
async for submission in top:
all_subs.append(submission)
random_subs = random.choice(all_subs)
name = random_subs.title
url = random_subs.url
em = discord.Embed(title = name, colour = discord.Colour.random(), timestamp = ctx.message.created_at, url = url)
em.set_image(url = url)
await ctx.send(embed = em)
#meme cmd
sreddits2_list = ['memes', 'dankmemes']
#bot.command(aliases=['Meme'])
async def meme(ctx):
subreddit = await reddit.subreddit(random.choice(sreddits2_list))
all_subs = []
top = subreddit.top(limit = 50)
async for submission in top:
all_subs.append(submission)
random_subs = random.choice(all_subs)
name = random_subs.title
url = random_subs.url
em = discord.Embed(title = name, colour = discord.Colour.random(), timestamp = ctx.message.created_at, url = url)
em.set_image(url = url)
await ctx.send(embed = em)
I used praw before this. But then someone told me to use asyncpraw. I tried and it was faster. But it's not enough.
Please tell me how do I make it faster?.
The problem is that the bot takes some time to respond and send the embed.
If you want to test the commands, then join the Discord Server and try the commands. (It's just a test server)
-meme
-nmeme
If the above link does not work then please use this one
https://discord.gg/RDtmjTz87H
The reason is praw and asyncpraw. As they are not made for getting posts, you shouldn't be using them. You can use RedditEasy which is 2x faster than praw in getting posts.
This is mostly regarding your bots latency(ping) and the place you are requesting it from. I also recommend you use the reddit api(json).

Programming a Discord bot in Python- I have a meme command, how do I make it so there is less of a chance to show the same meme twice?

So I have a meme command for my bot. I've been trying to figure out how to make it less likely to show the same meme twice (it keeps repeating them). Here is my code:
#client.event
async def on_message(message):
if message.content.startswith(".meme"):
subreddit = reddit.subreddit("cleanmemes")
all_subs = []
top = subreddit.top(limit = 75)
for submission in top:
all_subs.append(submission)
random_sub = random.choice(all_subs)
name = random_sub.title
url = random_sub.url
em = discord.Embed(title = name, color = 0xffff00)
em.set_image(url = url)
await message.channel.send(embed = em)
Im new to programming, any tips?
You can save the memes' urls in a json or txt file. Then, you can check the new url with the sent ones.
#client.event
async def on_message(message):
if message.content.startswith(".meme"):
subreddit = reddit.subreddit("cleanmemes")
all_subs = []
top = subreddit.top(limit = 75)
for submission in top:
all_subs.append(submission)
random_sub = random.choice(all_subs)
name = random_sub.title
url = random_sub.url
with open('urls.txt', 'r+') as file:
if url in file.read():
return
else:
file.write(f'{url}\n')
em = discord.Embed(title = name, color = 0xffff00)
em.set_image(url = url)
await message.channel.send(embed = em)
In this code, you must create a urls.txt file at first. Then, it will check the url's of the memes that you've sent before. If it has sent before, it'll return and won't send anything. If it doesn't, it will save it to that txt file and will send the meme.
Could you try storing a list of the memes that you've already sent (i.e. a list of URLs) and check whether the URL is in your list before sending the message?
Pseudo-code example, below.
# at the beginning of your code initialize an empty list of memes
sent_memes = []
# check if meme has been sent - skip if so
if url in sent_memes:
pass
else:
# send meme
sent_memes.append(url) # add url to list of sent_memes
This approach would ensure that you never send two of the same memes (unless they have different URLs).

Is there anyway to make PRAW faster for discord.py

This works and I have no issue with it. my bot is about 1100 lines of code so not that much. I have a standard meme command using PRAW. Is there any way to make its response time faster and not embedding it is not an option. My ms is average.
code:
#client.command(pass_context=True)
async def meme(ctx):
subreddit = reddit.subreddit("meme")
all_subs = []
top = subreddit.top(limit=50)
for submission in top:
all_subs.append(submission)
random_sub = random.choice(all_subs)
name = random_sub.title
url = random_sub.url
embed = discord.Embed(title = name)
embed.set_image(url=url)
await ctx.send(embed=embed)
You can store a meme and then send it later. By sending and then getting a meme, you do not have to wait to get a meme before sending one. Then you prepare for the next one.
#client.command(pass_context=True)
async def meme(ctx):
if not hasattr(client, 'nextMeme'):
client.nextMeme = getMeme()
name, url = client.nextMeme
embed = discord.Embed(title = name)
embed.set_image(url=url)
await ctx.send(embed=embed)
client.nextMeme = getMeme()
def getMeme():
subreddit = reddit.subreddit("meme")
top = subreddit.top(limit=50)
for submission in top:
all_subs.append(submission)
random_sub = random.choice(all_subs)
name = random_sub.title
url = random_sub.url
return name, url
I changed bot to client, if client does not work for you then replace it with bot.

Showing leader board stats from JSON with Discord.py via Embed

I'm trying to create a leaderboard to show the different stats the users collect when messaging the discord chatroom. I'm storing the data via JSON file and was wondering if I am on the right track or if there was a better way to display the stats with an Embed?
Edit: Edited the code to display what changes were made. New question is, how could I display 11-20 with a page forward? Tried the code below but when it goes to display 11-20, it sends #11 as an embed, then #11-12 as an embed, etc, etc and doesn't stop at 20, just keeps sending more embeds.
client = discord.Client()
try:
with open("cash.json") as fp:
cash = json.load(fp)
except Exception:
cash = {}
def save_cash():
with open("cash.json", "w+") as fp:
json.dump(cash, fp, sort_keys=True, indent=4)
def add_dollars(user: discord.User, dollars: int):
id = user.id
if id not in cash:
cash[id] = {}
cash[id]["dollars"] = cash[id].get("dollars", 0) + dollars
print("{} now has {} dollars".format(user.name, cash[id]["dollars"]))
save_cash()
def get_dollars(user: discord.User):
id = user.id
if id in cash:
return cash[id].get("dollars", 0)
return 0
client.event
async def on_message(message):
if message.content.startswith('!lb cash'):
cash_leaderboard = sorted(cash, key=lambda x : cash[x].get('dollars', 0), reverse=True)
msg = ''
for number, user in enumerate(cash_leaderboard):
msg += '{0}. <#!{1}> {2} Dollars\n\n'.format(number +1, user, cash[user].get('dollars', 0))
if number == 10:
break
else:
number += 1
embed = discord.Embed(
title="TOP BALLER LEADERBOARD\nBallers:",
color=0x24d7cf,
description=msg
)
embed.set_author(name="BOT", icon_url="")
embed.set_thumbnail(url="")
embed.set_footer(text="BOT", icon_url="")
lb_msg = await client.send_message(message.channel, embed=embed)
await client.add_reaction(lb_msg, "⏩")
lb_wait = await client.wait_for_reaction(emoji="⏩", user=message.author, message=lb_msg, timeout=1800)
if lb_wait:
await client.delete_message(lb_msg)
cash_leaderboard2 = sorted(cash, key=lambda x : cash[x].get('dollars', 0), reverse=True)
msg = ''
for number, user in enumerate(cash_leaderboard2):
msg += '{0}. <#!{1}> {2} Dollars\n\n'.format(number +11, user, cash[user].get('dollars', 0))
if number == 20:
break
else:
number += 1
embed = discord.Embed(
title="TOP BALLER LEADERBOARD 11-20\nBallers:",
color=0x24d7cf,
description=msg
)
embed.set_author(name="BOT", icon_url="")
embed.set_thumbnail(url="")
embed.set_footer(text="BOT", icon_url="")
await client.send_message(message.channel, embed=embed)

Categories

Resources