Skip to content

Commit

Permalink
managed to cog most admin commands after making a class of the server…
Browse files Browse the repository at this point in the history
…Data and userData
  • Loading branch information
ClementJ18 committed Aug 5, 2017
1 parent ce28b16 commit a1a0a94
Show file tree
Hide file tree
Showing 27 changed files with 1,095 additions and 1,368 deletions.
5 changes: 1 addition & 4 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@

data/token.txt

soup
*.pyc
adventure
selfbot
__pycache__/var.cpython-36.pyc
token.txt
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ __User Pofile__ <br>
__Planned Features__
* [x] **Modularity Overhaul** - allow server owners to set their own auto moderation channels, welcome message and others server-specific settings.
* [x] **Overhaul to expand user profile** - server-specific permission, more compact, improved code
* [ ] **Server Roles for Bot Roles** - Give server owners the ability to assign server roles to the bot roles and thereby the ability to grant a bot role by simply granting the equivalent server roles
* [X] **Server Roles for Bot Roles** - Give server owners the ability to assign server roles to the bot roles
* [ ] **EXP System** - longer exp cooldown, level up system, random amount of exp
* [ ] **Money System** - actual use of money, transfers between users
* [x] **Help system** - rewamp into something more compact, allows user to add an argument to look up a detailed description of a command.
Expand Down
Empty file added __init__.py
Empty file.
Binary file removed __pycache__/admin.cpython-36.pyc
Binary file not shown.
Binary file removed __pycache__/var.cpython-36.pyc
Binary file not shown.
590 changes: 110 additions & 480 deletions bot.py

Large diffs are not rendered by default.

597 changes: 0 additions & 597 deletions data/logfile.txt

This file was deleted.

3 changes: 0 additions & 3 deletions data/setting.csv

This file was deleted.

7 changes: 7 additions & 0 deletions logfile.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

Sat Aug 5 22:08:57 2017: Necro#6714 used n!off
Sat Aug 5 22:22:20 2017: Necro#6714 used n!off
Sat Aug 5 22:23:16 2017: Necro#6714 used n!nick <@!172002275412279296> TatsuBot
Sat Aug 5 22:23:33 2017: Necro#6714 used n!reload admin
Sat Aug 5 22:23:39 2017: Necro#6714 used n!nick <@!172002275412279296> TatsuBot
Sat Aug 5 22:24:07 2017: Necro#6714 used n!off
92 changes: 92 additions & 0 deletions miscadmin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#!/usr/bin/python3.6
import discord
from discord.ext import commands
from discord.ext.commands.cooldowns import BucketType

from rings.botdata.data import Data

userData = Data.userData
serverData = Data.serverData

class MiscAdmin():
def __init__(self, bot):
self.bot = bot

def has_perms(perms_level):
def predicate(cont):
return userData[cont.message.author.id]["perms"][cont.message.server.id] >= perms_level
return commands.check(predicate)

def is_necro():
def predicate(cont):
return cont.message.author.id == "241942232867799040"
return commands.check(predicate)

@commands.command(pass_context = True, hidden=True)
@has_perms(6)
async def add(cont, user : discord.Member, *, equation : str):
"""Does the given pythonic equations on the given user's NecroBot balance. (Permission level required: 6+ (NecroBot Admin))"""
s = str(userData[user.id]["money"]) + equation
try:
operation = simple_eval(s)
userData[user]["money"] = abs(int(operation))
await bot.say(":atm: | **"+ user.name + "'s** balance is now **"+str(userData[user.id]["money"])+ "** :euro:")
except (NameError,SyntaxError):
await bot.say(":negative_squared_cross_mark: | Operation no recognized.")

@bot.command(pass_context = True)
async def speak(cont, channel, *, message):
"""Send the given message to the channel mentioned either by id or by mention. Requires the correct permission level on both servers. (Permission level required: 4+ (Server Admin))"""
channel = allmentions(cont, channel)[0]
if userData[cont.message.author.id]["perms"][cont.message.server.id] >= 4 and userData[cont.message.author.id]["perms"][bot.get_channel(ID).server.id] >= 4:
await bot.send_message(bot.get_channel(ID), ":loudspeaker: | " + message)
elif userData[cont.message.author.id]["perms"][bot.get_channel(ID).server.id] < 4:
await bot.say(":negative_squared_cross_mark: | You do not have the required NecroBot permissions on the server you're trying to send the message to.")
else:
await bot.say(":negative_squared_cross_mark: | You do not have the required NecroBot permissions to use this command.")

@bot.command(pass_context = True, hidden=True)
@has_perms(6)
async def pm(cont, ID, *, message):
"""Sends the given message to the user of the given id. It will then wait 5 minutes for an answer and print it to the channel it was called it. (Permission level required: 6+ (NecroBot Admin))"""
for x in bot.get_all_members():
if x.id == ID:
user = x

send = await bot.send_message(user, message + "\n*You have 5 minutes to reply to the message*")
await bot.say("Message sent")
msg = await bot.wait_for_message(author=user, channel=send.channel, timeout=300)
await bot.send_message(cont.message.channel, ":speech_left: | **User: {0.author}** said :**{0.content}**".format(msg))

@bot.command(pass_context = True)
@commands.cooldown(1, 10, BucketType.channel)
@has_perms(4)
async def purge(cont, number : int):
"""Removes number of messages from the channel it is called in. That's all it does at the moment but later checks will also be added to allow for more flexible/specific purging (Permission level required: 4+ (Server Admin))"""
await bot.purge_from(cont.message.channel, limit=number+1)
message = await bot.say(":wastebasket: | **" + str(number) + "** messages purged.")
await asyncio.sleep(5)
await bot.delete_message(message)

@bot.command(pass_context = True)
@has_perms(5)
async def setroles(cont):
"""Sets the NecroBot roles for this server and assigns them to user based on their NecroBot permission level. Permission level required: 5+ (Server Owner))"""
for x in roleList:
if discord.utils.get(cont.message.server.roles, name=x[0]) is None:
new_role = await bot.create_role(cont.message.server, name=x[0], colour=x[1], mentionable=True)
await bot.say("Role " + x[0] + " created")
else:
await bot.say("A role with the name " + x[0] + " already exists.")
await asyncio.sleep(5)
await bot.purge_from(bot.get_channel(cont.message.channel.id), limit=8)
await bot.say("**Roles created**")

for x in cont.message.server.members:
role = userData[x.id]["perms"][cont.message.server.id]-1
await bot.add_roles(x, discord.utils.get(cont.message.server.roles, name=roleList[role][0]))
await bot.say("**Roles assigned**")


def setup(bot):
bot.add_cog(MiscAdmin(bot))
6 changes: 4 additions & 2 deletions rings/animals.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#!/usr/bin/python3.6
import discord
from discord.ext import commands
from discord.ext.commands.cooldowns import BucketType
Expand All @@ -6,22 +7,23 @@


class Animals():
"""Show pictures of cute animals us the power of the internet."""
def __init__(self, bot):
self.bot = bot

#random neko picture
@commands.command()
@commands.cooldown(3, 3, BucketType.user)
async def cat(self):
"""Posts a random cat picture from random.cat """
async with aiohttp.ClientSession() as cs:
async with cs.get('http://random.cat/meow') as r:
res = await r.json()
await self.bot.say(res['file'])

#random doggo picture
@commands.command()
@commands.cooldown(3, 3, BucketType.user)
async def dog(self):
"""Posts a random dog picture from random.dog """
async with aiohttp.ClientSession(connector=aiohttp.TCPConnector(verify_ssl=False)) as cs:
async with cs.get('https://random.dog/woof.json') as r:
res = await r.json()
Expand Down
Empty file added rings/botdata/__init__.py
Empty file.
29 changes: 29 additions & 0 deletions rings/botdata/data.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/usr/bin/python3.6
import ast
import csv
import asyncio
import os

class Data():
def __init__(self, serverData, userData, superDuperIgnoreList):
self.serverData = serverData
self.userData = userData
self.superDuperIgnoreList = superDuperIgnoreList

serverData = dict()
userData = dict()

with open("C:\\Users\\Clement\\Desktop\\necrobot\\rings\\botdata\\userdata.csv","r") as f:
reader = csv.reader(f)
for row in reader:
permsDict = ast.literal_eval(row[5])
userData[row[0]] = {"money":int(row[1]),"daily":row[2],"title":row[3],"exp":int(row[4]),"perms":permsDict,"warnings":row[6].split(","),"lastMessage":"","lastMessageTime":0, "locked":""}

with open("C:\\Users\\Clement\\Desktop\\necrobot\\rings\\botdata\\setting.csv","r") as f:
reader = csv.reader(f)
superDuperIgnoreList = list(next(reader))
line = next(reader)
for row in reader:
tagsDict = ast.literal_eval(row[10])
serverData[row[1]] = {"mute":row[2],"automod":row[3],"welcome-channel":row[4], "selfRoles":row[5].split(","),"ignoreCommand":row[6].split(","),"ignoreAutomod":row[7].split(","),"welcome":row[8],"goodbye":row[9],"tags":tagsDict}

3 changes: 3 additions & 0 deletions rings/botdata/setting.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
318465643420712962
Server Name,Server,Mute Role,Automod Channel,Welcome Channel,Self Roles,Automod Ignore,Commands Ignore,Welcome Message,Goodbye Message,Tags
The Land of Shadow,311630847969198082,TimeOut,318828760331845634,318738044515647498,",Evil,Chaotic,Neutral,Lawful,Good",",311789251190587392,312647665395433492,312184736166576129,172002275412279296",",317619283377258497,321305756999745547,312902474753245184,312243558671450113,339330190742126595,172002275412279296,241942232867799040","Hello, {member} and welcome to {server}, don't forget to check out <#311630847969198082>","Bye, we'll miss you {member} :kissing_heart:","{'gao': {'content': 'https://secure.static.tumblr.com/6e33aba611550380136a248fd4f77f1b/afrpxsg/Ryjnnjr7p/tumblr_static_tumblr_static_a80laqb3wj4s084w80c8goc4o_640.gif', 'owner': '241942232867799040'}, 'test': {'content': '*claps feet*', 'owner': '241942232867799040'}, 'test2': {'content': ""This is a really nice server, what do you say it's called? {server.name}? Noice! And you're a very nice user, {member.display_name}. Although this {channel.name} channel really sucks (edited)"", 'owner': '241942232867799040'}}"
6 changes: 3 additions & 3 deletions data/userdata.csv → rings/botdata/userdata.csv
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
241942232867799040,65897,22,The Bot Smith,2311,"{'311630847969198082': 7, '236997924427530241': 7, '288255618341666827': 7}","test warning1, testwarning2,muted #1"
241942232867799040,65897,22,The Bot Smith,2939,"{'311630847969198082': 7, '236997924427530241': 7, '288255618341666827': 7}","test warning1, testwarning2,muted #1"
317619283377258497,698562,32, ,4667,"{'311630847969198082': 2, '236997924427530241': 0, '288255618341666827': 0}",test warning 1 by Necro#6714 on server The Land of Shadow
227589245731209217,2000,32, ,0,"{'311630847969198082': 0, '236997924427530241': 0, '288255618341666827': 0}",
220502526393450497,2000,32, ,4,"{'311630847969198082': 0, '236997924427530241': 0, '288255618341666827': 0}",
Expand All @@ -23,14 +23,14 @@
295594533868142592,2000,32, ,0,"{'311630847969198082': 0, '236997924427530241': 0, '288255618341666827': 0}",
88057082737082368,2000,32, ,0,"{'311630847969198082': 0, '236997924427530241': 0, '288255618341666827': 0}",
228975286123888650,2000,32, ,0,"{'311630847969198082': 0, '236997924427530241': 0, '288255618341666827': 0}",
253741720464916485,2000,32, ,2,"{'311630847969198082': 0, '236997924427530241': 0, '288255618341666827': 0}",
253741720464916485,2000,32, ,15,"{'311630847969198082': 0, '236997924427530241': 0, '288255618341666827': 0}",
302209918499553280,2000,32, ,5,"{'311630847969198082': 0, '236997924427530241': 0, '288255618341666827': 0}",
267357476012163073,2000,32, ,445,"{'311630847969198082': 0, '236997924427530241': 0, '288255618341666827': 0}",
141250907399651328,2000,32, ,0,"{'311630847969198082': 0, '236997924427530241': 0, '288255618341666827': 0}",
275989054082777088,2000,32, ,95,"{'311630847969198082': 0, '236997924427530241': 0, '288255618341666827': 0}",
288715359048040449,2000,32, ,20,"{'311630847969198082': 0, '236997924427530241': 0, '288255618341666827': 0}",
222820128734183435,2000,32, ,0,"{'311630847969198082': 0, '236997924427530241': 0, '288255618341666827': 0}",
271259290415792129,2200,6, ,1828,"{'311630847969198082': 6, '236997924427530241': 6, '288255618341666827': 6}","too sexy (warning #2) by Necro#6714 on server The Land of Shadow,too sexy <:Kappa:312680876054151169> by Necro#6714 on server The Land of Shadow,too sexy <:Kappa:312680876054151169> by Necro#6714 on server The Land of Shadow"
271259290415792129,2200,6, ,1886,"{'311630847969198082': 6, '236997924427530241': 6, '288255618341666827': 6}","too sexy (warning #2) by Necro#6714 on server The Land of Shadow,too sexy <:Kappa:312680876054151169> by Necro#6714 on server The Land of Shadow,too sexy <:Kappa:312680876054151169> by Necro#6714 on server The Land of Shadow"
235142713123667978,2000,32, ,0,"{'311630847969198082': 0, '236997924427530241': 0, '288255618341666827': 0}",
203015871378096128,2000,32, ,151,"{'311630847969198082': 0, '236997924427530241': 0, '288255618341666827': 0}",
218447974554927105,2000,32, ,0,"{'311630847969198082': 0, '236997924427530241': 0, '288255618341666827': 0}",
Expand Down
134 changes: 134 additions & 0 deletions rings/help.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
#!/usr/bin/python3.6
import discord
from discord.ext.commands import *
import itertools, inspect, re

class NecroBotHelpFormatter(HelpFormatter):
def __init__(self, show_hidden=False, show_check_failure=True, width=80):
self.width = width
self.show_hidden = show_hidden
self.show_check_failure = show_check_failure

def get_ending_note(self):
command_name = self.context.invoked_with
return "Type {0}{1} [command] for more info on a command.\n" \
"Example: `n!help edain` - display help on the edain command \n" \
"You can also type {0}{1} [category] for more info on a category. \n"\
"Example: `n!help Animals` - display help on the Animals category".format(self.clean_prefix, command_name)

def get_ending_note_command(self):
command_name = self.context.invoked_with
return "Type {0}{1} [command] [subcommand] for more info on a command's subcommand.\n" \
"Example: `n!help settings welcome-channel` - display help on the welcome-channel subcommand of the settings command \n".format(self.clean_prefix, command_name)

def get_command_signature(self):
"""Retrieves the signature portion of the help page."""
result = []
prefix = self.clean_prefix
cmd = self.command
parent = cmd.full_parent_name
if len(cmd.aliases) > 0:
aliases = ' | '.join(cmd.aliases)
fmt = '{0}[{1.name} | {2}]'
if parent:
fmt = '{0}{3} [{1.name} | {2}]'
result.append(fmt.format(prefix, cmd, aliases, parent))
else:
name = prefix + cmd.name if not parent else prefix + parent + ' ' + cmd.name
result.append(name)

params = cmd.clean_params
if len(params) > 0:
for name, param in params.items():
if param.kind == param.VAR_POSITIONAL:
result.append('[{}...]'.format(name))
else:
result.append('<{}>'.format(name))

return ' '.join(result)

def _add_commands_to_page(self, max_width, commands):
commandList = list()
for name, command in commands:
if name in command.aliases:
# skip aliases
continue

commandList.append("`{}`".format(name))

return " | ".join(commandList)

def _add_subcommands_to_page(self, max_width, commands):
for name, command in commands:
if name in command.aliases:
# skip aliases
continue

entry = ' `{0:<{width}}` - {1}'.format(name, command.short_doc, width=max_width)
shortened = self.shorten(entry)
self._paginator.add_line(shortened)

def format(self):
self._paginator = Paginator(prefix="", suffix="")
if isinstance(self.command, Command):
title = ":information_source: **The `{0}` command** :information_source:".format(self.command)
else:
title = ":information_source: **NecroBot Help Menu** :information_source:"


self._paginator.add_line(title)

# we need a padding of ~80 or so

description = self.command.description if not self.is_cog() else inspect.getdoc(self.command)

if description:
# <description> portion
self._paginator.add_line(description, empty=True)

if isinstance(self.command, Command):

# <long doc> section
if self.command.help:
self._paginator.add_line(self.command.help, empty=True)

# <signature portion>
signature = "__Usage__\n" + self.get_command_signature()
self._paginator.add_line(signature, empty=True)

# end it here if it's just a regular command
if not self.has_subcommands():
self._paginator.close_page()
return self._paginator.pages

max_width = self.max_name_size

def category(tup):
cog = tup[1].cog_name
# we insert the zero width space there to give it approximate
# last place sorting position.
return "**" + cog + '** - ' if cog is not None else '\u200b**No Category** - '

if self.is_bot():
data = sorted(self.filter_command_list(), key=category)
counter = 0
for category, commands in itertools.groupby(data, key=category):
# there simply is no prettier way of doing this.
counter += 1
commands = list(commands)
if len(commands) > 0:
self._paginator.add_line(str(counter) + ". " + category + self._add_commands_to_page(max_width, commands))

# add the ending note for general help
ending_note = self.get_ending_note()

else:
self._paginator.add_line('Sub-commands:')
self._add_subcommands_to_page(max_width, self.filter_command_list())

# add the ending note for command pages
ending_note = self.get_ending_note_command()

self._paginator.add_line()
self._paginator.add_line(ending_note)
return self._paginator.pages
Loading

0 comments on commit a1a0a94

Please sign in to comment.