uploaded v3 cog

This commit is contained in:
brandons209 2019-06-20 12:48:36 -04:00
parent aebda8d165
commit 8fcba72d10
6 changed files with 198 additions and 654 deletions

6
events/__init__.py Normal file
View 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
View 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
"""
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(40)

View file

@ -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")

View file

@ -1,2 +0,0 @@
tensorflow==1.5
keras

View file

@ -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
}

View file

@ -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))