mirror of
https://github.com/brandons209/Red-bot-Cogs.git
synced 2024-06-03 11:05:18 +12:00
Merge branch 'v3' of https://github.com/brandons209/Red-bot-Cogs into v3
This commit is contained in:
commit
e4801cfddc
53
cogs_to_port.txt
Normal file
53
cogs_to_port.txt
Normal file
|
@ -0,0 +1,53 @@
|
|||
1. antiraid - could combine with the v3 cog Dungeon for new users
|
||||
|
||||
2. activitylog
|
||||
|
||||
3. custom commands from admin
|
||||
|
||||
4. autoeconomy - integrate into something else
|
||||
|
||||
5. buyrole
|
||||
|
||||
6. economytrickle might need the v3 reworked
|
||||
|
||||
7. punish / isolate, maybe integrate into one module
|
||||
|
||||
8. rpoll
|
||||
|
||||
9. referral
|
||||
|
||||
10. changes to russian rolutte and race
|
||||
|
||||
11. genscript
|
||||
|
||||
12. slap (intgrate with roleplay cog)
|
||||
|
||||
13. ugreport (upgrade it?)
|
||||
|
||||
14. xorole if exclusiverole sucks
|
||||
|
||||
15. markov if fix issue
|
||||
|
||||
16. sfx
|
||||
|
||||
cogs to look at:
|
||||
evolution
|
||||
economytrickle upgrade - awards voice activity too (oof)
|
||||
massdm
|
||||
invoice
|
||||
otherbot
|
||||
rolemanagement - maybe replace pingable and other role functions
|
||||
deepfry
|
||||
scanner
|
||||
blurplefy
|
||||
imagemaker
|
||||
audiotrivia
|
||||
exclusive role replaces xorole
|
||||
chatter
|
||||
leaver
|
||||
infochannel
|
||||
love calculator
|
||||
turn
|
||||
cah
|
||||
pupper
|
||||
pingtime
|
6
events/__init__.py
Normal file
6
events/__init__.py
Normal file
|
@ -0,0 +1,6 @@
|
|||
from .events import Events
|
||||
|
||||
def setup(bot):
|
||||
n = Events(bot)
|
||||
bot.add_cog(n)
|
||||
bot.loop.create_task(n.update_events())
|
192
events/events.py
Normal file
192
events/events.py
Normal file
|
@ -0,0 +1,192 @@
|
|||
import discord
|
||||
from redbot.core import checks, commands
|
||||
from redbot.core.utils.chat_formatting import *
|
||||
from redbot.core import Config
|
||||
|
||||
import time
|
||||
import random
|
||||
import asyncio
|
||||
import datetime
|
||||
import pytz
|
||||
from tzlocal import get_localzone
|
||||
|
||||
|
||||
basic_colors = [discord.Colour.blue(), discord.Colour.teal(), discord.Colour.dark_teal(), discord.Colour.green(), discord.Colour.dark_green(), discord.Colour.dark_blue(), discord.Colour.purple(), discord.Colour.dark_purple(), discord.Colour.magenta(), discord.Colour.gold(), discord.Colour.orange(), discord.Colour.red(), discord.Colour.dark_red(), discord.Colour.blurple(), discord.Colour.greyple()]
|
||||
class Events(commands.Cog):
|
||||
"""
|
||||
Set events that track time since set events
|
||||
"""
|
||||
def __init__(self, bot):
|
||||
super().__init__()
|
||||
self.config = Config.get_conf(self, identifier=6748392754)
|
||||
self.timezone = get_localzone()
|
||||
self.bot = bot
|
||||
# set default values
|
||||
self.config.register_guild(events={}, channel=0)
|
||||
|
||||
@commands.group()
|
||||
@commands.guild_only()
|
||||
async def event(self, ctx):
|
||||
"""
|
||||
Track time since event occured.
|
||||
"""
|
||||
pass
|
||||
|
||||
@event.command(name="add")
|
||||
async def addevent(self, ctx, start_time: str, *, event_name: str = ""):
|
||||
"""
|
||||
Add event to track. If start time is not given, the current data and time is used.
|
||||
Start time should be a UNIX timestamp in UTC.
|
||||
"""
|
||||
guild = ctx.guild
|
||||
channel_id = await self.config.guild(guild).channel()
|
||||
if channel_id == 0:
|
||||
await ctx.send("Channel not setup, use ``{}eventset channel` to set channel for events.".format(ctx.prefix))
|
||||
return
|
||||
channel = self.bot.get_channel(channel_id)
|
||||
if not channel:
|
||||
await ctx.send("Channel set not found, please setup channel.")
|
||||
return
|
||||
try:
|
||||
start_time = datetime.datetime.utcfromtimestamp(int(start_time))
|
||||
except:
|
||||
event_name = start_time + " " + event_name
|
||||
start_time = datetime.datetime.utcnow()
|
||||
|
||||
elapsed_time = datetime.datetime.utcnow() - start_time
|
||||
embed = discord.Embed(title=event_name, colour=random.choice(basic_colors))
|
||||
embed.add_field(name="Event time", value=start_time.replace(tzinfo=pytz.utc).astimezone(self.timezone).strftime("%b %d, %Y, %H:%M"))
|
||||
day_msg = "{} day{},".format(elapsed_time.days, "s" if elapsed_time.days > 1 else "")
|
||||
hour_msg = " {} hour{}".format(int(elapsed_time.seconds / 60 / 60), "s" if int(elapsed_time.seconds / 60 / 60) > 1 else "")
|
||||
if elapsed_time.days > 0 or int(elapsed_time.seconds / 60 / 60) > 0:
|
||||
minute_msg = ", and {} minute{}".format(int(elapsed_time.seconds / 60 - int(elapsed_time.seconds / 60 / 60) * 60), "s" if int(elapsed_time.seconds / 60 - int(elapsed_time.seconds / 60 / 60) * 60) > 1 else "")
|
||||
else:
|
||||
minute_msg = "{} minute{}".format(int(elapsed_time.seconds / 60 - int(elapsed_time.seconds / 60 / 60) * 60), "s" if int(elapsed_time.seconds / 60 - int(elapsed_time.seconds / 60 / 60) * 60) > 1 else "")
|
||||
msg = "{}{}{}".format(day_msg if elapsed_time.days > 0 else "", hour_msg if int(elapsed_time.seconds / 60 / 60) > 0 else "", minute_msg)
|
||||
embed.add_field(name="Elapsed time", value=msg)
|
||||
message = await channel.send(embed=embed)
|
||||
async with self.config.guild(guild).events() as events:
|
||||
new_event = {"start_time" : int(start_time.replace(tzinfo=pytz.utc).timestamp()), "name" : event_name}
|
||||
events[message.id] = new_event
|
||||
await ctx.send("Event added!")
|
||||
|
||||
@event.command(name="del")
|
||||
async def delevent(self, ctx):
|
||||
"""
|
||||
Delete an event. Interactive deletion, so just run the command.
|
||||
"""
|
||||
guild = ctx.guild
|
||||
channel_id = await self.config.guild(guild).channel()
|
||||
if channel_id == 0:
|
||||
await ctx.send("Channel not setup, use `{}eventset channel` to set channel for events.".format(ctx.prefix))
|
||||
return
|
||||
channel = self.bot.get_channel(channel_id)
|
||||
if not channel:
|
||||
await ctx.send("Channel set not found, please setup channel.")
|
||||
return
|
||||
|
||||
counter = 0
|
||||
msg = "```"
|
||||
async with self.config.guild(guild).events() as events:
|
||||
for num, event in events.items():
|
||||
msg += "{}\t{}\n".format(counter, event["name"])
|
||||
if len(msg + "```") + 100 > 2000:
|
||||
msg += "```"
|
||||
await ctx.send(msg)
|
||||
msg = "```"
|
||||
counter += 1
|
||||
msg += "```"
|
||||
await ctx.send(msg)
|
||||
await ctx.send("Please choose which event you want to delete. (type number in chat)")
|
||||
def m_check(m):
|
||||
try:
|
||||
return m.author.id == ctx.author.id and m.channel.id == ctx.channel.id and int(m.content) <= counter and int(m.content) >= 0
|
||||
except:
|
||||
return False
|
||||
try:
|
||||
response = await self.bot.wait_for('message', timeout=30, check=m_check)
|
||||
except:
|
||||
await ctx.send("Timed out, event deletion cancelled.")
|
||||
return
|
||||
for i, num in enumerate(events.keys()):
|
||||
if i == int(response.content):
|
||||
event_num = num
|
||||
try:
|
||||
message = await channel.fetch_message(event_num)
|
||||
await message.delete()
|
||||
except:
|
||||
await ctx.send("Event message in {} was not found.".format(channel.mention))
|
||||
|
||||
await ctx.send("{} has been deleted!".format(events[event_num]["name"]))
|
||||
del events[event_num]
|
||||
|
||||
@event.command(name="list")
|
||||
async def listevent(self, ctx):
|
||||
"""
|
||||
List all events for server.
|
||||
"""
|
||||
guild = ctx.guild
|
||||
msg = "```\n"
|
||||
async with self.config.guild(guild).events() as events:
|
||||
if len(events) == 0:
|
||||
msg += "None"
|
||||
for num, event in events.items():
|
||||
msg += "{}\n".format(event["name"])
|
||||
if len(msg + "```") + 3 > 2000:
|
||||
msg += "```"
|
||||
await ctx.send(msg)
|
||||
msg = "```"
|
||||
|
||||
msg += "```"
|
||||
await ctx.send(msg)
|
||||
|
||||
@commands.group()
|
||||
@commands.guild_only()
|
||||
@checks.admin_or_permissions(administrator=True)
|
||||
async def eventset(self, ctx: commands.Context):
|
||||
"""Manages event settings"""
|
||||
pass
|
||||
|
||||
@eventset.command(name="channel")
|
||||
async def _channel_set(self, ctx, channel: discord.TextChannel):
|
||||
"""
|
||||
Set channel to send event messages too
|
||||
"""
|
||||
guild = ctx.guild
|
||||
await self.config.guild(guild).channel.set(channel.id)
|
||||
await ctx.send("Channel now set to {}".format(channel.mention))
|
||||
|
||||
async def update_events(self):
|
||||
while True:
|
||||
if self is not self.bot.get_cog("Events"):
|
||||
print("events cog has been lost")
|
||||
return
|
||||
guilds = self.bot.guilds
|
||||
for guild in guilds:
|
||||
async with self.config.guild(guild).events() as events:
|
||||
channel_id = await self.config.guild(guild).channel()
|
||||
if channel_id == 0:
|
||||
continue
|
||||
channel = self.bot.get_channel(channel_id)
|
||||
if channel is None:
|
||||
continue
|
||||
for message_id, event in events.items():
|
||||
try:
|
||||
message = await channel.fetch_message(message_id)
|
||||
except:
|
||||
continue
|
||||
start_time = datetime.datetime.utcfromtimestamp(event["start_time"])
|
||||
elapsed_time = datetime.datetime.utcnow() - start_time
|
||||
embed = message.embeds[0]
|
||||
embed.clear_fields()
|
||||
embed.add_field(name="Event time", value=start_time.replace(tzinfo=pytz.utc).astimezone(self.timezone).strftime("%b %d, %Y, %H:%M"))
|
||||
day_msg = "{} day{},".format(elapsed_time.days, "s" if elapsed_time.days > 1 else "")
|
||||
hour_msg = " {} hour{}".format(int(elapsed_time.seconds / 60 / 60), "s" if int(elapsed_time.seconds / 60 / 60) > 1 else "")
|
||||
if elapsed_time.days > 0 or int(elapsed_time.seconds / 60 / 60) > 0:
|
||||
minute_msg = ", and {} minute{}".format(int(elapsed_time.seconds / 60 - int(elapsed_time.seconds / 60 / 60) * 60), "s" if int(elapsed_time.seconds / 60 - int(elapsed_time.seconds / 60 / 60) * 60) > 1 else "")
|
||||
else:
|
||||
minute_msg = "{} minute{}".format(int(elapsed_time.seconds / 60 - int(elapsed_time.seconds / 60 / 60) * 60), "s" if int(elapsed_time.seconds / 60 - int(elapsed_time.seconds / 60 / 60) * 60) > 1 else "")
|
||||
msg = "{}{}{}".format(day_msg if elapsed_time.days > 0 else "", hour_msg if int(elapsed_time.seconds / 60 / 60) > 0 else "", minute_msg)
|
||||
embed.add_field(name="Elapsed time", value=msg)
|
||||
await message.edit(embed=embed)
|
||||
await asyncio.sleep(30)
|
7
info.json
Normal file
7
info.json
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"AUTHOR": "Brandons209",
|
||||
"INSTALL_MSG": "Thank you for using my cogs! Have fun!",
|
||||
"NAME": "Brandon-V3",
|
||||
"SHORT": "Cogs by Brandons209",
|
||||
"DESCRIPTION": "Cogs for Red-Discord Bot by Brandons209"
|
||||
}
|
6
pony/__init__.py
Normal file
6
pony/__init__.py
Normal file
|
@ -0,0 +1,6 @@
|
|||
import os
|
||||
from .pony import Pony
|
||||
from redbot.core import Config
|
||||
|
||||
def setup(bot):
|
||||
bot.add_cog(Pony())
|
24
pony/info.json
Normal file
24
pony/info.json
Normal file
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"author": [
|
||||
"Brandons209",
|
||||
"somethingux",
|
||||
"Alzarath"
|
||||
],
|
||||
"bot_version": [
|
||||
3,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"description": "Search derpibooru for images of ponies! Fully customizable filter list!",
|
||||
"hidden": false,
|
||||
"install_msg": "Thank you for using this cog! Please make sure to setup the filters to your liking using '[p]ponyfilter'.",
|
||||
"requirements": ["urllib3", "aiohttp"],
|
||||
"short": "Search derpibooru for images of ponies!",
|
||||
"tags": [
|
||||
"brandons209",
|
||||
"fun",
|
||||
"pony",
|
||||
"mlp",
|
||||
"image"
|
||||
]
|
||||
}
|
350
pony/pony.py
Normal file
350
pony/pony.py
Normal file
|
@ -0,0 +1,350 @@
|
|||
import discord
|
||||
from redbot.core.utils.chat_formatting import *
|
||||
from redbot.core import Config, checks, commands
|
||||
from urllib import parse
|
||||
import aiohttp
|
||||
import os
|
||||
import traceback
|
||||
import json
|
||||
|
||||
class Pony(commands.Cog):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
self.config = Config.get_conf(self, identifier=7384662719)
|
||||
default_global = {
|
||||
"maxfilters":50
|
||||
}
|
||||
self.default_guild = {
|
||||
"filters": ["-meme", "safe", "-spoiler:*", "-vulgar"],
|
||||
"verbose": False
|
||||
}
|
||||
self.config.register_guild(**self.default_guild)
|
||||
self.config.register_global(**default_global)
|
||||
|
||||
@commands.command()
|
||||
@commands.guild_only()
|
||||
async def pony(self, ctx, *text):
|
||||
"""Retrieves the latest result from Derpibooru"""
|
||||
await self.fetch_image(ctx, randomize=False, tags=text)
|
||||
|
||||
@commands.command()
|
||||
@commands.guild_only()
|
||||
async def ponyr(self, ctx, *text):
|
||||
"""Retrieves a random result from Derpibooru"""
|
||||
await self.fetch_image(ctx, randomize=True, tags=text)
|
||||
|
||||
# needed because derpi was having trouble getting a random image from our derpi page with the filters we have
|
||||
@commands.command(pass_context=True, no_pm=True)
|
||||
async def mascot(self, ctx):
|
||||
"""
|
||||
Gives a random picture of our mascot!
|
||||
"""
|
||||
await fetch_image(self, ctx, randomize=True, mascot=True, tags=['safe,', 'uploader:champions of equestria'])
|
||||
|
||||
@commands.group()
|
||||
@commands.guild_only()
|
||||
@checks.admin()
|
||||
async def ponyfilter(self, ctx: commands.Context):
|
||||
"""Manages pony filters
|
||||
Warning: Can be used to allow NSFW images
|
||||
|
||||
Filters automatically apply tags to each search"""
|
||||
pass
|
||||
|
||||
@ponyfilter.command(name="add")
|
||||
async def _add_ponyfilter(self, ctx, filter_tag : str):
|
||||
"""Adds a tag to the server's pony filter list
|
||||
|
||||
Example: !ponyfilter add safe"""
|
||||
guild = ctx.guild
|
||||
filters = await self.config.guild(guild).filters()
|
||||
max_filters = await self.config.maxfilters()
|
||||
# if reached limit of max filters, don't add
|
||||
if len(filters) < max_filters:
|
||||
if filter_tag not in filters:
|
||||
async with self.config.guild(guild).filters() as old_filter:
|
||||
old_filter.append(filter_tag)
|
||||
await ctx.send("Filter '{}' added to the server's pony filter list.".format(filter_tag))
|
||||
else:
|
||||
await ctx.send("Filter '{}' is already in the server's pony filter list.".format(filter_tag))
|
||||
else:
|
||||
await ctx.send("This server has exceeded the maximum filters ({}/{}).".format(len(filters), max_filters))
|
||||
|
||||
@ponyfilter.command(name="del")
|
||||
async def _del_ponyfilter(self, ctx, filter_tag : str=""):
|
||||
"""Deletes a tag from the server's pony filter list
|
||||
|
||||
Without arguments, reverts to the default pony filter list
|
||||
|
||||
Example: !ponyfilter del safe"""
|
||||
guild = ctx.guild
|
||||
filters = await self.config.guild(guild).filters()
|
||||
if len(filter_tag) > 0:
|
||||
if filter_tag in filters:
|
||||
async with self.config.guild(guild).filters() as old_filter:
|
||||
old_filter.remove(filter_tag)
|
||||
await ctx.send("Filter '{}' deleted from the server's pony filter list.".format(filter_tag))
|
||||
else:
|
||||
await ctx.send("Filter '{}' does not exist in the server's pony filter list.".format(filter_tag))
|
||||
else:
|
||||
if self.default_guild["filters"] != filters:
|
||||
await self.config.guild(guild).filters.set(self.default_guild["filters"])
|
||||
await ctx.send("Reverted the server to the default pony filter list.")
|
||||
else:
|
||||
await ctx.send("Server is already using the default pony filter list.")
|
||||
|
||||
@ponyfilter.command(name="list")
|
||||
async def _list_ponyfilter(self, ctx):
|
||||
"""Lists all of the filters currently applied to the current server"""
|
||||
guild = ctx.guild
|
||||
filters = await self.config.guild(guild).filters()
|
||||
if filters:
|
||||
filter_list = '\n'.join(sorted(filters))
|
||||
target_guild = "{}'s".format(guild.name)
|
||||
else:
|
||||
filter_list = '\n'.join(sorted(filters["default"]))
|
||||
target_guild = "Default"
|
||||
await ctx.send("{} pony filter list contains:```\n{}```".format(target_guild, filter_list))
|
||||
|
||||
@commands.group()
|
||||
@checks.admin()
|
||||
async def ponyset(self, ctx):
|
||||
"""Manages pony options"""
|
||||
pass
|
||||
|
||||
@ponyset.command(name="verbose")
|
||||
async def _verbose_ponyset(self, ctx, toggle : str="toggle"):
|
||||
"""Toggles verbose mode"""
|
||||
guild = ctx.guild
|
||||
verbose = await self.config.guild(guild).verbose()
|
||||
if toggle.lower() == "on" or toggle.lower() == "true" or toggle.lower() == "enable":
|
||||
if not verbose:
|
||||
await self.config.guild(guild).verbose.set(True)
|
||||
await ctx.send("Verbose mode is now enabled.")
|
||||
else:
|
||||
await ctx.send("Verbose mode is already enabled.")
|
||||
elif toggle.lower() == "off" or toggle.lower() == "false" or toggle.lower() == "disable":
|
||||
if verbose:
|
||||
await self.config.guild(guild).verbose.set(False)
|
||||
await ctx.send("Verbose mode is now disabled.")
|
||||
else:
|
||||
await ctx.send("Verbose mode is already disabled.")
|
||||
else:
|
||||
if verbose:
|
||||
await self.config.guild(guild).verbose.set(False)
|
||||
await ctx.send("Verbose mode is now disabled.")
|
||||
else:
|
||||
await self.config.guild(guild).verbose.set(True)
|
||||
await ctx.send("Verbose mode is now enabled.")
|
||||
|
||||
@ponyset.command(name="maxfilters")
|
||||
@checks.is_owner()
|
||||
async def _maxfilters_ponyset(self, ctx, new_max_filters : int):
|
||||
"""Sets the global tag limit for the filter list.
|
||||
|
||||
Leave blank to get current max filters.
|
||||
|
||||
Gives an error when a user tries to add a filter while the server's filter list contains a certain amount of tags"""
|
||||
if new_max_filters is None:
|
||||
max_filters = self.config.maxfilters()
|
||||
await ctx.send("Current filter limit: {} filters.".format(max_filters))
|
||||
return
|
||||
|
||||
guild = ctx.guild
|
||||
await self.config.maxfilters.set(new_max_filters)
|
||||
await ctx.send("Maximum filters allowed per server for pony set to '{}'.".format(new_max_filters))
|
||||
|
||||
@ponyset.command(name="import")
|
||||
@checks.is_owner()
|
||||
async def _import_ponyset(self, ctx, path_to_import):
|
||||
"""Imports filters and settings from jsons.
|
||||
|
||||
Specifiy the **path** to the jsons to import filters and settings from.
|
||||
|
||||
*i.e.: /path/containing/jsons/*"""
|
||||
bot = ctx.bot
|
||||
path_to_settings = os.path.join(path_to_import, "settings.json")
|
||||
path_to_filters = os.path.join(path_to_import, "filters.json")
|
||||
|
||||
try:
|
||||
with open(path_to_settings) as raw_settings:
|
||||
msg = "Settings import sucessful for these guilds:\n"
|
||||
import_settings = json.load(raw_settings)
|
||||
for json_guild_id, json_guild_verbose in import_settings.items():
|
||||
if json_guild_id != "maxfilters":
|
||||
|
||||
guild = bot.get_guild(int(json_guild_id))
|
||||
if guild is None:
|
||||
continue
|
||||
|
||||
await self.config.guild(guild).verbose.set(json_guild_verbose['verbose'])
|
||||
msg += "**{}**\n".format(guild)
|
||||
if len(msg) + 100 > 2000:
|
||||
await ctx.send(msg)
|
||||
msg = ""
|
||||
|
||||
await self.config.maxfilters.set(int(import_settings["maxfilters"]))
|
||||
if msg != "":
|
||||
await ctx.send(msg)
|
||||
|
||||
with open(path_to_filters) as raw_filters:
|
||||
import_filters = json.load(raw_filters)
|
||||
msg = "Filters import successful for these guilds:\n"
|
||||
for json_guild_id, json_guild_filters in import_filters.items():
|
||||
if json_guild_id != "default":
|
||||
|
||||
guild = bot.get_guild(int(json_guild_id)) # returns None if guild is not found
|
||||
if guild is None:
|
||||
continue
|
||||
|
||||
await self.config.guild(guild).filters.set(json_guild_filters)
|
||||
msg += "**{}**\n".format(guild)
|
||||
if len(msg) + 100 > 2000:
|
||||
await ctx.send(msg)
|
||||
msg = ""
|
||||
else:
|
||||
continue
|
||||
if msg != "":
|
||||
await ctx.send(msg)
|
||||
|
||||
except FileNotFoundError:
|
||||
await ctx.send("Invalid path to json files.")
|
||||
except json.decoder.JSONDecodeError:
|
||||
await ctx.send("Invalid or malformed json files.")
|
||||
|
||||
async def fetch_image(self, ctx, randomize : bool=False, tags : list=[], mascot=False):
|
||||
guild = ctx.guild
|
||||
filters = await self.config.guild(guild).filters()
|
||||
verbose = await self.config.guild(guild).verbose()
|
||||
|
||||
#Initialize variables
|
||||
artist = "unknown artist"
|
||||
artists = ""
|
||||
artistList = []
|
||||
embedLink = ""
|
||||
embedTitle = ""
|
||||
imageId = ""
|
||||
message = ""
|
||||
output = None
|
||||
rating = ""
|
||||
ratingColor = "FFFFFF"
|
||||
ratingWord = "unknown"
|
||||
search = "https://derpibooru.org/search.json?q="
|
||||
tagSearch = ""
|
||||
|
||||
# Assign tags to URL
|
||||
if tags:
|
||||
tagSearch += "{} ".format(" ".join(tags)).strip()
|
||||
if filters and not mascot:
|
||||
if filters != [] and tags:
|
||||
tagSearch += ", "
|
||||
tagSearch += ", ".join(filters)
|
||||
elif not mascot:
|
||||
if tags:
|
||||
tagSearch += ", "
|
||||
tagSearch += ", ".join(filters)
|
||||
|
||||
search += parse.quote_plus(tagSearch)
|
||||
|
||||
# Randomize results and apply Derpibooru's "Everything" filter
|
||||
if randomize:
|
||||
if not tags and filters:
|
||||
if filters == []:
|
||||
search = "https://derpibooru.org/images/random.json?filter_id=56027"
|
||||
else:
|
||||
search += "&random_image=y&filter_id=56027"
|
||||
else:
|
||||
search += "&random_image=y&filter_id=56027"
|
||||
|
||||
# Inform users about image retrieving
|
||||
message = await ctx.send("Fetching pony image...")
|
||||
|
||||
# Fetch the image or display an error
|
||||
try:
|
||||
async with aiohttp.ClientSession(loop=ctx.bot.loop) as session:
|
||||
async with session.get(search, headers={'User-Agent': "Booru-Cogs (https://git.io/booru)"}) as r:
|
||||
website = await r.json()
|
||||
if randomize:
|
||||
if "id" in website:
|
||||
imageId = str(website["id"])
|
||||
async with aiohttp.ClientSession(loop=ctx.bot.loop) as session:
|
||||
async with session.get("https://derpibooru.org/images/" + imageId + ".json") as r:
|
||||
website = await r.json()
|
||||
imageURL = "https:{}".format(website["image"])
|
||||
else:
|
||||
return await message.edit(content="Your search terms gave no results.")
|
||||
else:
|
||||
if website["search"] != []:
|
||||
website = website["search"][0]
|
||||
imageURL = "https:{}".format(website["image"])
|
||||
else:
|
||||
return await message.edit(content="Your search terms gave no results.")
|
||||
except:
|
||||
return await message.edit(content="Error. {}".format(traceback.format_exc()))
|
||||
|
||||
# If verbose mode is enabled, create an embed and fill it with information
|
||||
if verbose:
|
||||
# Sets the embed title
|
||||
embedTitle = "Derpibooru Image #{}".format(imageId)
|
||||
|
||||
# Sets the URL to be linked
|
||||
embedLink = "https://derpibooru.org/{}".format(imageId)
|
||||
|
||||
# Populates the tag list
|
||||
tagList = website["tags"].split(", ")
|
||||
|
||||
# Checks for the rating and sets an appropriate color
|
||||
for i in range(0, len(tagList)):
|
||||
if tagList[i] == "safe":
|
||||
ratingColor = "00FF00"
|
||||
ratingWord = tagList.pop(i)
|
||||
break
|
||||
elif tagList[i] == "suggestive":
|
||||
ratingColor = "FFFF00"
|
||||
ratingWord = tagList.pop(i)
|
||||
break
|
||||
elif tagList[i] == "questionable":
|
||||
ratingColor = "FF9900"
|
||||
ratingWord = tagList.pop(i)
|
||||
break
|
||||
elif tagList[i] == "explicit":
|
||||
ratingColor = "FF0000"
|
||||
ratingWord = tagList.pop(i)
|
||||
break
|
||||
|
||||
# Grabs the artist(s)
|
||||
for i in range(0, len(tagList)):
|
||||
if "artist:" in tagList[i]:
|
||||
while "artist:" in tagList[i]:
|
||||
artistList.append(tagList.pop(i)[7:])
|
||||
break
|
||||
|
||||
# Determine if there are multiple artists
|
||||
if len(artistList) == 1:
|
||||
artist = artistList[0]
|
||||
elif len(artistList) > 1:
|
||||
artists = ", ".join(artistList)
|
||||
artist = ""
|
||||
|
||||
# Initialize verbose embed
|
||||
output = discord.Embed(title=embedTitle, url=embedLink, colour=discord.Colour(value=int(ratingColor, 16)))
|
||||
|
||||
# Sets the thumbnail and adds the rating and tag fields to the embed
|
||||
output.add_field(name="Rating", value=ratingWord)
|
||||
if artist:
|
||||
output.add_field(name="Artist", value=artist)
|
||||
elif artists:
|
||||
output.add_field(name="Artists", value=artists)
|
||||
output.add_field(name="Tags", value=", ".join(tagList), inline=False)
|
||||
output.add_field(name="Search url", value=search)
|
||||
output.set_thumbnail(url=imageURL)
|
||||
else:
|
||||
# Sets the link to the image URL if verbose mode is not enabled
|
||||
output = imageURL
|
||||
|
||||
# Edits the pending message with the results
|
||||
if verbose:
|
||||
return await message.edit(content="Image found.", embed=output)
|
||||
else:
|
||||
return await message.edit(content=output)
|
|
@ -1,269 +0,0 @@
|
|||
import discord
|
||||
from discord.ext import commands
|
||||
from cogs.utils import checks
|
||||
from cogs.utils.dataIO import dataIO
|
||||
import asyncio
|
||||
import os
|
||||
import random
|
||||
|
||||
class Referral:
|
||||
"""
|
||||
Creates a referral system with raffle like selection for prizes for discord users.
|
||||
"""
|
||||
def __init__(self, bot):
|
||||
self.settings_path = 'data/referral/settings.json'
|
||||
self.bot = bot
|
||||
self.settings = dataIO.load_json(self.settings_path)
|
||||
|
||||
def add_non_refer(self, member):
|
||||
if member.server.id not in self.settings.keys():
|
||||
self.settings[member.server.id] = {}
|
||||
self.settings[member.server.id]["NON-REFERRALS"] = []
|
||||
elif "NON-REFERRALS" not in self.settings[member.server.id].keys():
|
||||
self.settings[member.server.id]["NON-REFERRALS"] = []
|
||||
|
||||
self.settings[member.server.id]["NON-REFERRALS"].append(member.id)
|
||||
dataIO.save_json(self.settings_path, self.settings)
|
||||
|
||||
def clear_refers(self, server):
|
||||
"""
|
||||
Clears entire referral and non referral list, then adds all current users in server to non referral list.
|
||||
"""
|
||||
self.settings[server.id]["NON-REFERRALS"] = []
|
||||
self.settings[server.id]["REFERRALS"] = {}
|
||||
for member in server.members:
|
||||
self.settings[server.id]["NON-REFERRALS"].append(member.id)
|
||||
|
||||
dataIO.save_json(self.settings_path, self.settings)
|
||||
|
||||
async def member_join_listener(self, member):
|
||||
"""
|
||||
Checks user against main invite link to determine if they went through the main invite link or an alternate one
|
||||
"""
|
||||
server = member.server
|
||||
default_inv = self.settings.get(server.id, {}).get("DEFAULT_INVITE", {})
|
||||
invite = None
|
||||
|
||||
if not default_inv:
|
||||
# TODO logging
|
||||
return
|
||||
else:
|
||||
try:
|
||||
invite = await self.bot.get_invite(default_inv["ID"])
|
||||
except:
|
||||
invite = None
|
||||
|
||||
if not invite:
|
||||
# TODO: put logging here
|
||||
return
|
||||
|
||||
if invite.uses > int(default_inv["USES"]):
|
||||
self.add_non_refer(member)
|
||||
self.settings[server.id]["DEFAULT_INVITE"]["USES"] = invite.uses
|
||||
dataIO.save_json(self.settings_path, self.settings)
|
||||
|
||||
@commands.group(pass_context=True, invoke_without_command=True, no_pm=True)
|
||||
@checks.admin_or_permissions(administrator=True)
|
||||
async def referralset(self, ctx):
|
||||
if ctx.invoked_subcommand is None:
|
||||
await self.bot.send_cmd_help(ctx)
|
||||
|
||||
@referralset.command(pass_context=True, no_pm=True, name="default-invite")
|
||||
async def default_invite(self, ctx, invite_id : str):
|
||||
"""
|
||||
!!! Not functional !!!
|
||||
Set default invite for server. Give a valid invite ID.
|
||||
"""
|
||||
server = ctx.message.server
|
||||
try:
|
||||
invite = await self.bot.get_invite(invite_id)
|
||||
except:
|
||||
await self.bot.say("Could not retrieve invite, make sure to use a valid invite ID.")
|
||||
return
|
||||
|
||||
if server.id not in self.settings.keys():
|
||||
self.settings[server.id] = {}
|
||||
self.settings[server.id]["DEFAULT_INVITE"] = {}
|
||||
elif "DEFAULT_INVITE" not in self.settings[server.id].keys():
|
||||
self.settings[server.id]["DEFAULT_INVITE"] = {}
|
||||
|
||||
self.settings[server.id]["DEFAULT_INVITE"]["ID"] = invite_id
|
||||
self.settings[server.id]["DEFAULT_INVITE"]["USES"] = invite.uses
|
||||
dataIO.save_json(self.settings_path, self.settings)
|
||||
await self.bot.say("Counts: {}".format(invite.uses))
|
||||
await self.bot.say("Default invite changed.")
|
||||
|
||||
@referralset.command(pass_context=True, no_pm=True, name="min-account-age")
|
||||
async def min_account_age(self, ctx, days : int):
|
||||
"""
|
||||
Set the min age (in days) a new user must have been on discord before they can set a referer.
|
||||
"""
|
||||
server = ctx.message.server
|
||||
|
||||
if server.id not in self.settings.keys():
|
||||
self.settings[server.id] = {}
|
||||
self.settings[server.id]["MIN_ACCOUNT_AGE"] = 0
|
||||
elif "MIN_ACCOUNT_AGE" not in self.settings[server.id].keys():
|
||||
self.settings[server.id]["MIN_ACCOUNT_AGE"] = 0
|
||||
|
||||
self.settings[server.id]["MIN_ACCOUNT_AGE"] = days
|
||||
dataIO.save_json(self.settings_path, self.settings)
|
||||
await self.bot.say("Minimum account age set to {}.".format(days))
|
||||
|
||||
@referralset.command(pass_context=True, no_pm=True, name="clear")
|
||||
async def clear_refer_data(self, ctx):
|
||||
"""
|
||||
Clears ALL current referrals and refer blacklist.
|
||||
It then puts all current server's members onto the blacklist.
|
||||
"""
|
||||
await self.bot.say("All current referral data (not settings) will be cleared, continue? (y/n)")
|
||||
message = await self.bot.wait_for_message(author=ctx.message.author, channel=ctx.message.channel)
|
||||
server = ctx.message.server
|
||||
|
||||
if message.content.lower() == "y":
|
||||
self.clear_refers(ctx.message.server)
|
||||
await self.bot.say("Referral data cleared.")
|
||||
else:
|
||||
await self.bot.say("Cancelled.")
|
||||
|
||||
@referralset.command(pass_context=True, no_pm=True, name="setup")
|
||||
async def setup(self, ctx):
|
||||
"""
|
||||
Setup referral cog for server.
|
||||
When first loading the referral module, make sure to run setup to add all current users to the blacklist for referrals.
|
||||
!!! WILL CLEAR ALL DATA FOR SERVER! !!!
|
||||
"""
|
||||
await self.bot.say("All current data will be cleared, continue? (y/n)")
|
||||
message = await self.bot.wait_for_message(author=ctx.message.author, channel=ctx.message.channel)
|
||||
server = ctx.message.server
|
||||
|
||||
if message.content.lower() == "y":
|
||||
self.settings[server.id] = {}
|
||||
self.settings[server.id]["MIN_ACCOUNT_AGE"] = 0
|
||||
self.settings[server.id]["DEFAULT_INVITE"] = {}
|
||||
#self.settings[server.id]["NON-REFERRALS"] = []
|
||||
#self.settings[server.id]["REFERRALS"] = {}
|
||||
self.clear_refers(server)
|
||||
await self.bot.say("Referral cog setup for this server!")
|
||||
dataIO.save_json(self.settings_path, self.settings)
|
||||
else:
|
||||
await self.bot.say("Canceled. No changes made")
|
||||
|
||||
@commands.group(pass_context=True, invoke_without_command=True, no_pm=True)
|
||||
async def refer(self, ctx, user: discord.Member):
|
||||
server = ctx.message.server
|
||||
if user:
|
||||
author = ctx.message.author
|
||||
thresh = self.settings.get(server.id, {}).get("MIN_ACCOUNT_AGE", 0)
|
||||
author_days_old = (ctx.message.timestamp - author.created_at).days
|
||||
user_days_old = (ctx.message.timestamp - user.created_at).days
|
||||
if author_days_old > thresh and user_days_old > thresh:
|
||||
if author.id in self.settings[server.id]["NON-REFERRALS"]:
|
||||
await self.bot.say("Sorry, you already set someone as your referrer or were already on the server.")
|
||||
return
|
||||
elif author.id == user.id:
|
||||
await self.bot.say("Sorry, you cannot refer yourself.")
|
||||
return
|
||||
elif user.id == self.bot.user.id:
|
||||
await self.bot.say("Thanks for trying, but you cannot set me as your referrer.")
|
||||
return
|
||||
if user.id not in self.settings[server.id]["REFERRALS"].keys():
|
||||
self.settings[server.id]["REFERRALS"][user.id] = [author.id]
|
||||
else:
|
||||
self.settings[server.id]["REFERRALS"][user.id].append(author.id)
|
||||
await self.bot.say("Referrer set to {}, thank you!".format(user.name))
|
||||
self.add_non_refer(author)
|
||||
dataIO.save_json(self.settings_path, self.settings)
|
||||
elif author_days_old < thresh:
|
||||
await self.bot.say("Sorry, your account is too new! Your account needs to be at least {} days old but it is {} days old.".format(thresh, author_days_old))
|
||||
else:
|
||||
await self.bot.say("Sorry, your referrer's account is too new! Their account needs to be at least {} days old but it is {} days old.".format(thresh, user_days_old))
|
||||
elif ctx.invoked_subcommand is None:
|
||||
await self.bot.send_cmd_help(ctx)
|
||||
|
||||
@refer.command(pass_context=True, no_pm=True, name="list")
|
||||
async def check_referrals(self, ctx):
|
||||
"""
|
||||
Checks how many people you have referred, and who referred you.
|
||||
"""
|
||||
author = ctx.message.author
|
||||
server = ctx.message.server
|
||||
settings = self.settings.get(server.id, {})
|
||||
msg = "Your Referrals:\n"
|
||||
referrals = settings.get("REFERRALS", {})
|
||||
author_referrals = settings.get("REFERRALS", {}).get(author.id, None)
|
||||
|
||||
if not author_referrals:
|
||||
msg += "**None**\n"
|
||||
else:
|
||||
for refer in author_referrals:
|
||||
member = await self.bot.get_user_info(refer)
|
||||
msg += "`{}`\n".format(member.name)
|
||||
|
||||
msg += "\nYour referer:\n"
|
||||
flag = 0
|
||||
for user_id in referrals.keys():
|
||||
for refer in referrals[user_id]:
|
||||
if refer == author.id:
|
||||
user = await self.bot.get_user_info(user_id)
|
||||
msg += "`{}`\n".format(user.name)
|
||||
flag = 1
|
||||
break
|
||||
if flag:
|
||||
break
|
||||
|
||||
if not flag:
|
||||
msg += "**None**\n"
|
||||
|
||||
await self.bot.say(msg)
|
||||
|
||||
@refer.command(pass_context=True, no_pm=True, name="raffle")
|
||||
@checks.admin_or_permissions(administrator=True)
|
||||
async def raffle(self, ctx, winners : int):
|
||||
"""
|
||||
Chooses specified amount of winners from users who have referrals. Each referral is a "raffle ticket" for the user.
|
||||
Once a winner is chooses, they cannot be choosen again.
|
||||
"""
|
||||
server = ctx.message.server
|
||||
settings = self.settings.get(server.id, {})
|
||||
|
||||
referrers = list(settings.get("REFERRALS", {}).keys())
|
||||
raffle_list = []
|
||||
|
||||
if not referrers:
|
||||
await self.bot.say("No one has referred anyone yet.")
|
||||
return
|
||||
|
||||
for refer in referrers:
|
||||
for _ in range(len(settings.get("REFERRALS", {}).get(refer, []))):
|
||||
raffle_list.append(refer)
|
||||
|
||||
random.shuffle(raffle_list)
|
||||
selection = []
|
||||
for i in range(winners):
|
||||
winner = random.choice(raffle_list)
|
||||
selection.append(winner)
|
||||
raffle_list = [x for x in raffle_list if x != winner]
|
||||
if not raffle_list:
|
||||
break
|
||||
|
||||
|
||||
msg = "**Here are the winners!**\n"
|
||||
for i, winner in enumerate(selection):
|
||||
user = await self.bot.get_user_info(winner)
|
||||
msg += "{}. `{}`\n".format(i + 1, user.display_name)
|
||||
|
||||
await self.bot.say(msg)
|
||||
|
||||
|
||||
def check_files():
|
||||
if not os.path.exists('data/referral/settings.json'):
|
||||
os.makedirs('data/referral', exist_ok=True)
|
||||
dataIO.save_json('data/referral/settings.json', {})
|
||||
|
||||
|
||||
def setup(bot):
|
||||
check_files()
|
||||
n = Referral(bot)
|
||||
bot.add_cog(n)
|
||||
#bot.add_listener(n.member_join_listener, "on_member_join")
|
|
@ -1,2 +0,0 @@
|
|||
tensorflow==1.5
|
||||
keras
|
|
@ -1,10 +0,0 @@
|
|||
{
|
||||
"AUTHOR" : "Brandon Silva",
|
||||
"INSTALL_MSG" : "Thanks for installing my cog!",
|
||||
"NAME" : "ScriptCog",
|
||||
"SHORT" : "Generates text from keras model.",
|
||||
"DESCRIPTION" : "Uses a keras model to generate text.",
|
||||
"TAGS" : ["mlp"],
|
||||
"REQUIREMENTS" : ["tensorflow", "keras"],
|
||||
"HIDDEN" : false
|
||||
}
|
|
@ -1,373 +0,0 @@
|
|||
import discord
|
||||
from discord.ext import commands
|
||||
from cogs.utils import checks
|
||||
from cogs.utils.converters import GlobalUser
|
||||
|
||||
from keras.models import load_model
|
||||
from keras.preprocessing.sequence import pad_sequences
|
||||
|
||||
import numpy as np
|
||||
import os
|
||||
import pickle
|
||||
import time
|
||||
import asyncio
|
||||
|
||||
from .utils.dataIO import dataIO
|
||||
from .utils.chat_formatting import warning
|
||||
|
||||
#loads dictionary from file
|
||||
def _load_dict(path):
|
||||
with open(path, 'rb') as file:
|
||||
dict = pickle.load(file)
|
||||
return dict
|
||||
|
||||
#dictionaries for tokenizing puncuation and converting it back
|
||||
punctuation_to_tokens = {'!':' ||exclaimation_mark|| ', ',':' ||comma|| ', '"':' ||quotation_mark|| ',
|
||||
';':' ||semicolon|| ', '.':' ||period|| ', '?':' ||question_mark|| ', '(':' ||left_parentheses|| ',
|
||||
')':' ||right_parentheses|| ', '--':' ||dash|| ', '\n':' ||return|| ', ':':' ||colon|| '}
|
||||
|
||||
tokens_to_punctuation = {token.strip(): punc for punc, token in punctuation_to_tokens.items()}
|
||||
|
||||
#for all of the puncuation in replace_list, convert it to tokens
|
||||
def _tokenize_punctuation(text):
|
||||
replace_list = ['.', ',', '!', '"', ';', '?', '(', ')', '--', '\n', ':']
|
||||
for char in replace_list:
|
||||
text = text.replace(char, punctuation_to_tokens[char])
|
||||
return text
|
||||
|
||||
#convert tokens back to puncuation
|
||||
def _untokenize_punctuation(text):
|
||||
replace_list = ['||period||', '||comma||', '||exclaimation_mark||', '||quotation_mark||',
|
||||
'||semicolon||', '||question_mark||', '||left_parentheses||', '||right_parentheses||',
|
||||
'||dash||', '||return||', '||colon||']
|
||||
for char in replace_list:
|
||||
if char == '||left_parentheses||':#added this since left parentheses had an extra space
|
||||
text = text.replace(' ' + char + ' ', tokens_to_punctuation[char])
|
||||
text = text.replace(' ' + char, tokens_to_punctuation[char])
|
||||
return text
|
||||
|
||||
"""
|
||||
helper function that instead of just doing argmax for prediction, actually taking a sample of top possible words
|
||||
takes a tempature which defines how many predictions to consider. lower means the word picked will be closer to the highest predicted word.
|
||||
"""
|
||||
def _sample(prediction, temp=0):
|
||||
if temp <= 0:
|
||||
return np.argmax(prediction)
|
||||
prediction = prediction[0]
|
||||
prediction = np.asarray(prediction).astype('float64')
|
||||
prediction = np.log(prediction) / temp
|
||||
expo_prediction = np.exp(prediction)
|
||||
prediction = expo_prediction / np.sum(expo_prediction)
|
||||
probabilities = np.random.multinomial(1, prediction, 1)
|
||||
return np.argmax(probabilities)
|
||||
|
||||
def _resolve_role_list(server: discord.Server, roles: list) -> list:
|
||||
gen = (_role_from_string(server, name) for name in roles)
|
||||
return list(filter(None, gen))
|
||||
|
||||
def _role_from_string(server, rolename, roles=None):
|
||||
if roles is None:
|
||||
roles = server.roles
|
||||
|
||||
roles = [r for r in roles if r is not None]
|
||||
role = discord.utils.find(lambda r: r.name.lower() == rolename.lower(), roles)
|
||||
# if couldnt find by role name, try to find by role id
|
||||
if role is None:
|
||||
role = discord.utils.find(lambda r: r.id == rolename, roles)
|
||||
|
||||
return role
|
||||
|
||||
def format_list(*items, join='and', delim=', '):
|
||||
if len(items) > 1:
|
||||
return (' %s ' % join).join((delim.join(items[:-1]), items[-1]))
|
||||
elif items:
|
||||
return items[0]
|
||||
else:
|
||||
return ''
|
||||
|
||||
"""This cog generates scripts based on imported model, I used a keras model. """
|
||||
class ScriptCog:
|
||||
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
self.model_path = "data/scriptcog/model.h5"
|
||||
self.dict_path = "data/scriptcog/dicts/"
|
||||
|
||||
self.cooldown = time.time()
|
||||
|
||||
try:
|
||||
self.model = load_model(self.model_path)
|
||||
except:
|
||||
self.model = None
|
||||
|
||||
self.settings_path = "data/scriptcog/settings.json"
|
||||
self.settings = dataIO.load_json(self.settings_path)
|
||||
|
||||
self.default_word_limit = 300
|
||||
self.default_cooldown_limit = 30
|
||||
self.default_tv_show = "My Little Pony"
|
||||
self.default_price = 0
|
||||
|
||||
try:
|
||||
self.word_to_int = _load_dict(self.dict_path + 'word_to_int.pkl')
|
||||
self.int_to_word = _load_dict(self.dict_path + 'int_to_word.pkl')
|
||||
self.sequence_length = _load_dict(self.dict_path + 'sequence_length.pkl')
|
||||
except:
|
||||
self.word_to_int = None
|
||||
self.int_to_word = None
|
||||
self.sequence_length = None
|
||||
|
||||
@commands.group(pass_context=True, invoke_without_command=True, no_pm=True)
|
||||
@checks.admin_or_permissions(administrator=True)
|
||||
async def genscriptset(self, ctx):
|
||||
if ctx.invoked_subcommand is None:
|
||||
await self.bot.send_cmd_help(ctx)
|
||||
|
||||
@genscriptset.command(pass_context=True, no_pm=True, name="word-limit")
|
||||
@checks.is_owner()
|
||||
async def genscriptset_set_word_limit(self, ctx, num_words : int):
|
||||
"""
|
||||
Set the word limit for generating scripts.
|
||||
"""
|
||||
try:
|
||||
self.settings[ctx.message.server.id]["WORD_LIMIT"] = num_words
|
||||
except:
|
||||
self.settings[ctx.message.server.id] = {}
|
||||
self.settings[ctx.message.server.id]["WORD_LIMIT"] = num_words
|
||||
|
||||
dataIO.save_json(self.settings_path, self.settings)
|
||||
await self.bot.say("Maximum number of words is now {}".format(num_words))
|
||||
|
||||
@genscriptset.command(pass_context=True, no_pm=True, name="tv-show")
|
||||
@checks.is_owner()
|
||||
async def genscriptset_set_tv_show(self, ctx, *, show):
|
||||
"""
|
||||
Sets the TV show the scripts are generated from.
|
||||
"""
|
||||
try:
|
||||
self.settings[ctx.message.server.id]["TV_SHOW"] = show
|
||||
except:
|
||||
self.settings[ctx.message.server.id] = {}
|
||||
self.settings[ctx.message.server.id]["TV_SHOW"] = show
|
||||
|
||||
dataIO.save_json(self.settings_path, self.settings)
|
||||
await self.bot.say("TV show is now {}.".format(show))
|
||||
|
||||
@genscriptset.command(pass_context=True, no_pm=True, name="cooldown")
|
||||
@checks.is_owner()
|
||||
async def genscriptset_set_cooldown(self, ctx, cooldown : int):
|
||||
"""
|
||||
Sets the cooldown period between generating scripts in seconds.
|
||||
"""
|
||||
try:
|
||||
self.settings[ctx.message.server.id]["COOLDOWN"] = cooldown
|
||||
except:
|
||||
self.settings[ctx.message.server.id] = {}
|
||||
self.settings[ctx.message.server.id]["COOLDOWN"] = cooldown
|
||||
|
||||
dataIO.save_json(self.settings_path, self.settings)
|
||||
await self.bot.say("Script cooldown is now {}.".format(cooldown))
|
||||
|
||||
@genscriptset.command(pass_context=True, no_pm=True, name="price")
|
||||
async def genscriptset_set_price(self, ctx, price : int):
|
||||
"""
|
||||
Sets the price for generating scripts.
|
||||
"""
|
||||
try:
|
||||
self.settings[ctx.message.server.id]["PRICE"] = price
|
||||
except:
|
||||
self.settings[ctx.message.server.id] = {}
|
||||
self.settings[ctx.message.server.id]["PRICE"] = price
|
||||
|
||||
dataIO.save_json(self.settings_path, self.settings)
|
||||
await self.bot.say("Price is now {}.".format(price))
|
||||
|
||||
@genscriptset.command(pass_context=True, no_pm=True, name="free-roles")
|
||||
async def genscriptset_free_roles(self, ctx, *, rolelist=None):
|
||||
"""Set roles that do not have to pay to generate scripts.
|
||||
|
||||
COMMA SEPARATED LIST (e.g. Admin,Staff,Mod), Can also use role IDs as well.
|
||||
|
||||
To get current list, run command with no roles.
|
||||
|
||||
Add role_list_clear as the role to clear the server\'s free role list.
|
||||
"""
|
||||
server = ctx.message.server
|
||||
current_roles = _resolve_role_list(server, self.settings[server.id].get("FREE_ROLE_LIST", []))
|
||||
|
||||
if rolelist is None:
|
||||
if current_roles:
|
||||
names_list = format_list(*(r.name for r in current_roles))
|
||||
await self.bot.say("Current list of roles that do not have to pay: {}".format(names_list))
|
||||
else:
|
||||
await self.bot.say("No roles defined.")
|
||||
return
|
||||
elif "role_list_clear" in rolelist.lower():
|
||||
await self.bot.say("Free role list cleared.")
|
||||
self.settings[server.id]["FREE_ROLE_LIST"] = []
|
||||
dataIO.save_json(self.settings_path, self.settings)
|
||||
return
|
||||
|
||||
found_roles = set()
|
||||
notfound_names = set()
|
||||
|
||||
for lookup in rolelist.split(","):
|
||||
lookup = lookup.strip()
|
||||
role = _role_from_string(server, lookup)
|
||||
|
||||
if role:
|
||||
found_roles.add(role)
|
||||
else:
|
||||
notfound_names.add(lookup)
|
||||
|
||||
if notfound_names:
|
||||
fmt_list = format_list(*("`{}`".format(x) for x in notfound_names))
|
||||
await self.bot.say(warning("These roles were not found: {}\n\nPlease try again.".format(fmt_list)))
|
||||
elif server.default_role in found_roles:
|
||||
await self.bot.say(warning("The everyone role cannot be added.\n\nPlease try again."))
|
||||
elif found_roles == set(current_roles):
|
||||
await self.bot.say("No changes to make.")
|
||||
else:
|
||||
if server.id not in self.settings:
|
||||
self.settings[server.id] = {}
|
||||
else:
|
||||
extra = ""
|
||||
|
||||
self.settings[server.id]["FREE_ROLE_LIST"] = [r.id for r in found_roles]
|
||||
dataIO.save_json(self.settings_path, self.settings)
|
||||
|
||||
fmt_list = format_list(*(r.name for r in found_roles))
|
||||
await self.bot.say("These roles will not have to pay for scripts: {}.{}".format(fmt_list, extra))
|
||||
|
||||
@commands.command(pass_context=True, no_pm=True)
|
||||
async def genscriptinfo(self, ctx):
|
||||
server_id = ctx.message.server.id
|
||||
word_limit = self.settings.get(server_id, {}).get("WORD_LIMIT", self.default_word_limit)
|
||||
cooldown = self.settings.get(server_id, {}).get("COOLDOWN", self.default_cooldown_limit)
|
||||
tv_show = self.settings.get(server_id, {}).get("TV_SHOW", self.default_tv_show)
|
||||
price = self.settings.get(server_id, {}).get("PRICE", self.default_price)
|
||||
await self.bot.say("```Word Limit: {0}\nCooldown Time: {1} seconds\nShow: {2}\nPrice for {0} words: {3}, which is {4} bits per word```".format(word_limit, cooldown, tv_show, price, price / word_limit))
|
||||
|
||||
@commands.command(pass_context=True, no_pm=True)
|
||||
async def genscripthelp(self, ctx):
|
||||
await self.bot.say("--------------------\nGenerate original TV scripts for {0} using Neural Networks!\nUsage: `{1}genscript <number of words to generate> <word variance> <starting text>`\nUse starting texts such as:\n`pinkie pie::`\n`fluttershy::`\n`twilight sparkle::`\nor other names of characters in the show. Otherwise, you can use any words said in the show.\n\nWord variance helps gives the script better results. A variance of 0 will mean that with the same starting text, it will always have the same output. Variance up to 1.0 will give more variety to words, however going closer to 1 can introduce more grammar and spelling mistakes.\n\nGenerating scripts cost bits, depending on how many words you want to generate. Use `{1}genscriptinfo` to get information on the cost.\n-------------------".format(self.settings.get(ctx.message.server.id, {}).get("TV_SHOW", self.default_tv_show), ctx.prefix))
|
||||
|
||||
@commands.command(pass_context=True, no_pm=True)
|
||||
async def genscript(self, ctx, num_words_to_generate : int, variance : float, *, seed):
|
||||
"""
|
||||
Generate a script using the power of Neural Networks!
|
||||
Please use the genscripthelp command to get a complete explaination of how to use the command.
|
||||
"""
|
||||
server_id = ctx.message.server.id
|
||||
word_limit = self.settings.get(server_id, {}).get("WORD_LIMIT", self.default_word_limit)
|
||||
cooldown = self.settings.get(server_id, {}).get("COOLDOWN", self.default_cooldown_limit)
|
||||
price = self.settings.get(server_id, {}).get("PRICE", self.default_price)
|
||||
user = ctx.message.author
|
||||
|
||||
if num_words_to_generate > word_limit:
|
||||
await self.bot.say("Please keep script sizes to {} words or less.".format(word_limit))
|
||||
return
|
||||
elif time.time() - self.cooldown < cooldown:
|
||||
await self.bot.say("Sorry, I am cooling down, please wait {:.0f} seconds.".format(cooldown - (time.time() - self.cooldown)))
|
||||
return
|
||||
|
||||
if not self.check_free_role(user):
|
||||
price = int((price / word_limit) * num_words_to_generate)
|
||||
return_val = self.charge_user(user, price)
|
||||
if return_val == 1: #if this worked, dont need to check when getting econ cog
|
||||
balance = self.bot.get_cog('Economy').bank.get_balance(user)
|
||||
await self.bot.say("Charged: {}, Balance: {}".format(price, balance))
|
||||
else:
|
||||
await self.charge_user_check(return_val, price, user)
|
||||
return
|
||||
|
||||
self.cooldown = time.time()
|
||||
|
||||
if variance > 1.0:
|
||||
variance = 1.0
|
||||
elif variance < 0:
|
||||
variance = 0
|
||||
|
||||
await self.bot.say("Generating script, please wait...")
|
||||
await self.get_model_output(num_words_to_generate, variance, seed)
|
||||
|
||||
async def get_model_output(self, num_words, temp, seed):
|
||||
input_text = seed
|
||||
for _ in range(num_words):
|
||||
#tokenize text to ints
|
||||
int_text = _tokenize_punctuation(input_text)
|
||||
int_text = int_text.lower()
|
||||
int_text = int_text.split()
|
||||
try:
|
||||
int_text = np.array([self.word_to_int[word] for word in int_text], dtype=np.int32)
|
||||
except KeyError:
|
||||
await self.bot.say("Sorry, that seed word is not in my vocabulary.\nPlease try an English word from the show.\n")
|
||||
return
|
||||
#pad text if it is too short, pads with zeros at beginning of text, so shouldnt have too much noise added
|
||||
int_text = pad_sequences([int_text], maxlen=self.sequence_length)
|
||||
#predict next word:
|
||||
prediction = self.model.predict(int_text, verbose=0)
|
||||
output_word = self.int_to_word[_sample(prediction, temp=temp)]
|
||||
#append to the result
|
||||
input_text += ' ' + output_word
|
||||
#convert tokenized punctuation and other characters back
|
||||
result = _untokenize_punctuation(input_text)
|
||||
await self.bot.say("------------------------")
|
||||
await self.bot.say(result)
|
||||
await self.bot.say("------------------------")
|
||||
|
||||
def charge_user(self, user, amount):
|
||||
"""
|
||||
Takes a user and a amount and charges the user. Returns 1 on success, 0 if economy cog cannot be loaded, -1 if the user does not have a bank account, and -2 if the user doesn't have enough credits.
|
||||
"""
|
||||
econ_cog = self.bot.get_cog('Economy')
|
||||
if not econ_cog:
|
||||
return 0
|
||||
if not econ_cog.bank.account_exists(user):
|
||||
return -1
|
||||
if not econ_cog.bank.can_spend(user, amount):
|
||||
return -2
|
||||
econ_cog.bank.withdraw_credits(user, amount)
|
||||
return 1
|
||||
|
||||
async def charge_user_check(self, return_val, amount, user):
|
||||
"""
|
||||
takes in return vals from charge_user and gives apporiate response
|
||||
"""
|
||||
econ_cog = self.bot.get_cog('Economy')
|
||||
if not econ_cog:
|
||||
await self.bot.say("Error loading economy cog!")
|
||||
return
|
||||
if return_val == 0:
|
||||
await self.bot.say("Economy cog not found! Please check to make sure the economy cog is loaded.")
|
||||
elif return_val == -1:
|
||||
await self.bot.say("You appear to not have a bank account. Use [p]bank register to open an account.")
|
||||
elif return_val == -2:
|
||||
await self.bot.say("You do not have enough credits. The sound command costs {} and you have {} credits in your bank account.".format(amount, econ_cog.bank.get_balance(user)))
|
||||
|
||||
def check_free_role(self, user):
|
||||
"""
|
||||
Checks if the user has a role that grants them free sounds. Returns 1 if the user does have one of these roles, zero otherwise.
|
||||
"""
|
||||
server = user.server
|
||||
free_roles = self.settings.get(server.id, {}).get("FREE_ROLE_LIST", [])
|
||||
if not free_roles:
|
||||
return 0
|
||||
user_roles = [r.id for r in user.roles]
|
||||
|
||||
for role in free_roles:
|
||||
if role in user_roles:
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
def check_folders():
|
||||
os.makedirs("data/scriptcog", exist_ok=True)
|
||||
os.makedirs("data/scriptcog/dicts", exist_ok=True)
|
||||
f = "data/scriptcog/settings.json"
|
||||
if not dataIO.is_valid_json(f):
|
||||
dataIO.save_json(f, {})
|
||||
|
||||
def setup(bot):
|
||||
check_folders()
|
||||
bot.add_cog(ScriptCog(bot))
|
Loading…
Reference in a new issue