Cleaned up code and added name exceptions to the config files

doc_update
Joey Hines 2018-08-11 18:02:50 -05:00
parent 1474cc54ce
commit 9723fa6b9a
16 changed files with 156 additions and 127 deletions

View File

@ -1,4 +1,5 @@
import configparser
import codecs
def create_config(config):
@ -27,7 +28,7 @@ def create_config(config):
def read_config():
config = configparser.ConfigParser()
config.read('GeoffreyConfig.ini')
config.read_file(codecs.open("GeoffreyConfig.ini", "r", "utf8"))
if len(config.sections()) == 0:
create_config(config)
@ -51,6 +52,7 @@ class Config:
self.bot_mod = self.config['Discord']['Bot_Mod']
self.count = int(self.config['Logging']['Count'])
self.rotation_duration = int(self.config['Logging']['Rotation_Duration'])
self.special_name_list = dict(self.config.items('Special Names'))
except Exception as e:
print("Invalid config file, missing {}.".format(e))
quit(1)

View File

@ -1,57 +1,75 @@
class DataBaseError(Exception):
'''Base class for exceptions in this module.'''
"""Base class for exceptions in this module."""
pass
class LocationInitError(DataBaseError):
'''Error in initializing Location'''
"""Error in initializing Location"""
class TunnelInitError(DataBaseError):
'''Error in initializing Tunnel'''
"""Error in initializing Tunnel"""
class NoMatchFoundError(DataBaseError):
'''No matches were found in the database'''
"""No matches were found in the database"""
class LocationLookUpError(DataBaseError):
'''Error in finding location in database'''
"""Error in finding location in database"""
class DeleteEntryError(DataBaseError):
'''Error in deleting entry'''
"""Error in deleting entry"""
class UsernameLookupFailed(Exception):
'''Error in username lookup, is the player's nickname set correctly? *stares at aeskdar*'''
"""Error in username lookup, is the player's nickname set correctly? *stares at aeskdar*"""
class PlayerNotFound(DataBaseError):
'''Player not found in database.'''
"""Player not found in database."""
class EntryNameNotUniqueError(DataBaseError):
'''A location by that name is already in the database.'''
"""A location by that name is already in the database."""
class StringTooLong(DataBaseError):
'''Given string is too long.'''
"""Given string is too long."""
class DatabaseValueError(DataBaseError):
''''String too long or number too large'''
"""'String too long or number too large"""
class ItemNotFound(DataBaseError):
'''No item matches found in database'''
"""No item matches found in database"""
class InvalidDimError(DataBaseError):
"""Invalid dimension name"""
class InvalidTunnelError(DataBaseError):
"""Invalid tunnel name"""
class PlayerInDBError(DataBaseError):
"""Player already registered in database"""
class LocationHasTunnelError(DataBaseError):
"""That location already has a tunnel"""
class NoPermissionError(DataBaseError):
"""You have no permission to run this command"""
class NotOnServerError(DataBaseError):
'''You need to run this command on 24CC'''
"""You need to run this command on 24CC"""
class FuckyWucky:
'''You made one.'''
"""You made one."""

View File

@ -372,5 +372,3 @@ class Commands:
raise e
finally:
session.close()

View File

@ -164,7 +164,7 @@ class DatabaseInterface:
if len(locations) == limit:
loc_string = loc_string + '\n**. . .**'
expr = Tunnel.owner.has(Player.name.ilike('%{}%'.format(search))) & Tunnel.location == None
expr = Tunnel.owner.has(Player.name.ilike('%{}%'.format(search))) & Tunnel.location is None
tunnels = self.database.query_by_filter(session, Tunnel, expr)
if len(tunnels) > 0:
@ -200,4 +200,4 @@ def list_to_string(loc_list, str_format='{}\n{}'):
for loc in loc_list:
loc_string = str_format.format(loc_string, loc)
return loc_string
return loc_string

View File

@ -1,4 +1,6 @@
from itertools import zip_longest
from BotConfig import bot_config
def get_name(args):
if len(args) > 0:
@ -8,19 +10,21 @@ def get_name(args):
return name
def get_nickname(discord_user):
if discord_user.nick is None:
name = discord_user.display_name
else:
name = discord_user.nick
if name == 'dootb.in ꙩ ⃤':
name = 'aeskdar'
if name in bot_config.special_name_list:
return bot_config.special_name_list[name]
else:
return name
return name
def get_args_dict(args):
if len(args) != 0:
return dict(zip_longest(*[iter(args)] * 2, fillvalue=" "))
else:
return {}
return {}

View File

@ -28,10 +28,7 @@ def setup_logging():
if __name__ == '__main__':
print("Starting logging...")
setup_logging()
print("Starting bot...")
start_bot()

View File

@ -2,7 +2,6 @@ import requests
from json import JSONDecodeError
from BotErrors import UsernameLookupFailed
uuid_lookup_url = 'https://api.mojang.com/users/profiles/minecraft/{}'
username_lookup_url = 'https://api.mojang.com/user/profiles/{}/names'
@ -18,17 +17,18 @@ def grab_json(url):
return json
def grab_UUID(username):
player_data = grab_json(uuid_lookup_url.format(username))
return player_data['id']
def grab_playername(uuid):
player_data = grab_json(username_lookup_url.format(uuid))
if len(player_data) == 0:
raise UsernameLookupFailed
else:
last_index = len(player_data)-1
last_index = len(player_data) - 1
return player_data[last_index]['name']

4
bot.py
View File

@ -112,5 +112,5 @@ def start_bot():
bot.run(bot_config.token)
except TimeoutError:
print("Disconnected, is Discord offline?")
except:
print("Bye")
finally:
print("Bot shutting down...")

View File

@ -6,20 +6,21 @@ from bot import bot_commands
@commands.cooldown(5, 60, commands.BucketType.user)
class Add_Commands:
'''
"""
Commands for adding things to Geoffrey.
*You must use ?register before using any of these commands!*
'''
"""
def __init__(self, bot):
self.bot = bot
@commands.command(pass_context=True)
@commands.cooldown(5, 60, commands.BucketType.user)
async def register(self, ctx):
'''
"""
Registers your Discord and Minecraft account with the the database.
You must do this before adding entries to the database.
'''
"""
try:
player_name = get_nickname(ctx.message.author)
@ -33,11 +34,11 @@ class Add_Commands:
@commands.command(pass_context=True)
@commands.cooldown(5, 60, commands.BucketType.user)
async def add_base(self, ctx, x_pos: int, z_pos: int, *args):
'''
"""
Adds your base to the database.
The name is optional.
?add_base [X Coordinate] [Z Coordinate] [Base Name]
'''
"""
name = get_name(args)
@ -50,19 +51,20 @@ class Add_Commands:
except EntryNameNotUniqueError:
if name is None:
await self.bot.say('{}, you already have one base in the database, you need to specify a base'
' name'.format(ctx.message.author.mention))
' name'.format(ctx.message.author.mention))
else:
await self.bot.say('{}, a base called **{}** already exists. You need to specify a different name.'.format(
ctx.message.author.mention, name))
await self.bot.say(
'{}, a base called **{}** already exists. You need to specify a different name.'.format(
ctx.message.author.mention, name))
@commands.command(pass_context=True)
@commands.cooldown(5, 60, commands.BucketType.user)
async def add_shop(self, ctx, x_pos: int, z_pos: int, *args):
'''
"""
Adds your shop to the database.
The name is optional.
?add_shop [X Coordinate] [Z Coordinate] [Shop Name]
'''
"""
name = get_name(args)
@ -74,19 +76,21 @@ class Add_Commands:
raise commands.UserInputError
except EntryNameNotUniqueError:
if name is None:
await self.bot.say('{}, you already have one shop in the database, you need to specify a shop name'.format(
ctx.message.author.mention))
await self.bot.say(
'{}, you already have one shop in the database, you need to specify a shop name'.format(
ctx.message.author.mention))
else:
await self.bot.say('{}, a shop called **{}** already exists. You need to specify a different name.'.format(
ctx.message.author.mention, name))
await self.bot.say(
'{}, a shop called **{}** already exists. You need to specify a different name.'.format(
ctx.message.author.mention, name))
@commands.command(pass_context=True)
@commands.cooldown(5, 60, commands.BucketType.user)
async def add_tunnel(self, ctx, tunnel_color: str, tunnel_number: int, *args):
'''
"""
Adds your tunnel to the database. If you only have one location, you do not need to specify a location name.
?tunnel [Tunnel Color] [Tunnel Number] [Location Name]
'''
"""
loc_name = get_name(args)
try:
@ -102,29 +106,31 @@ class Add_Commands:
await self.bot.say('{}, invalid tunnel color.'.format(ctx.message.author.mention))
except EntryNameNotUniqueError:
await self.bot.say('{}, you have more than one location, you need to specify a location.'
.format(ctx.message.author.mention))
.format(ctx.message.author.mention))
except InvalidTunnelError:
await self.bot.say('{}, **{}** is an invalid tunnel color.'.format(ctx.message.author.mention, tunnel_color))
await self.bot.say(
'{}, **{}** is an invalid tunnel color.'.format(ctx.message.author.mention, tunnel_color))
@commands.command(pass_context=True)
@commands.cooldown(5, 60, commands.BucketType.user)
async def add_item(self, ctx, item_name: str, quantity: int, diamond_price: int, *args):
'''
"""
Adds an item to a shop's inventory.
Quantity for Diamond Price.
?additem [Item Name] [Quantity] [Price] [Shop name]
'''
"""
shop_name = get_name(args)
try:
bot_commands.add_item(item_name, quantity, diamond_price, shop_name=shop_name,
discord_uuid=ctx.message.author.id)
await self.bot.say('{}, **{}** has been added to the inventory of your shop.'.format(ctx.message.author.mention,
item_name))
await self.bot.say(
'{}, **{}** has been added to the inventory of your shop.'.format(ctx.message.author.mention,
item_name))
except PlayerNotFound:
await self.bot.say('{}, you don\'t have any shops in the database.'.format(ctx.message.author.mention))
except LocationInitError:
await self.bot.say('{}, you have more than one shop in the database, please specify a shop name.'
.format(ctx.message.author.mention))
.format(ctx.message.author.mention))
except LocationLookUpError:
await self.bot.say(
'{}, you don\'t have any shops named **{}** in the database.'.format(ctx.message.author.mention,
@ -132,4 +138,4 @@ class Add_Commands:
def setup(bot):
bot.add_cog(Add_Commands(bot))
bot.add_cog(Add_Commands(bot))

View File

@ -17,9 +17,9 @@ def check_mod(user):
class Admin_Commands:
'''
"""
Commands for cool people only.
'''
"""
def __init__(self, bot):
self.bot = bot
@ -36,9 +36,9 @@ class Admin_Commands:
@commands.command(pass_context=True)
async def test(self, ctx):
'''
"""
Checks if the bot is alive.
'''
"""
if check_mod(ctx.message.author):
await self.bot.say('I\'m here you ding dong')
else:
@ -46,9 +46,9 @@ class Admin_Commands:
@commands.group(pass_context=True)
async def mod(self, ctx):
'''
"""
Bot moderation tools.
'''
"""
if check_mod(ctx.message.author):
if ctx.invoked_subcommand is None:
await self.bot.say('{}, invalid sub-command for command **mod**.'.format(ctx.message.author.mention))
@ -57,9 +57,9 @@ class Admin_Commands:
@mod.command(pass_context=True)
async def delete(self, ctx, discord_uuid: str, location_name: str):
'''
"""
Deletes a location in the database/
'''
"""
bot_commands.delete(location_name, discord_uuid=discord_uuid)
await self.bot.say('{}, **{}** has been deleted.'.format(ctx.message.author.mention, location_name))
@ -69,9 +69,9 @@ class Admin_Commands:
@mod.command(pass_context=True)
async def edit_name(self, ctx, discord_uuid: str, new_name: str, current_name: str):
'''
"""
Edits the name of a location in the database.
'''
"""
bot_commands.edit_name(new_name, current_name, discord_uuid=discord_uuid)
await self.bot.say('{}, **{}** has been rename to **{}**.'.format(ctx.message.author.mention, current_name,
new_name))
@ -82,9 +82,9 @@ class Admin_Commands:
@mod.command(pass_context=True)
async def update_mc_uuid(self, ctx, discord_uuid: str, mc_uuid: str):
'''
"""
Updates a user's MC UUID
'''
"""
bot_commands.update_mc_uuid(discord_uuid, mc_uuid)
await self.bot.say('{}, **{}** has been updated.'.format(ctx.message.author.mention, discord_uuid))
@ -94,9 +94,9 @@ class Admin_Commands:
@mod.command(pass_context=True)
async def update_discord_uuid(self, ctx, current_discord_uuid: str, new_discord_uuid: str):
'''
"""
Updates a user's Discord UUID
'''
"""
bot_commands.update_mc_uuid(current_discord_uuid, new_discord_uuid)
await self.bot.say('{}, user **{}** has been updated.'.format(ctx.message.author.mention, current_discord_uuid))
@ -106,9 +106,9 @@ class Admin_Commands:
@mod.command(pass_context=True)
async def update_mc_name(self, ctx, discord_uuid: str):
'''
"""
Updates a user's MC name to the current name on the MC UUID
'''
"""
bot_commands.update_mc_name(discord_uuid)
await self.bot.say('{}, user **{}**\'s MC name has update.'.format(ctx.message.author.mention, discord_uuid))
@ -118,12 +118,12 @@ class Admin_Commands:
@mod.command(pass_context=True)
async def status(self, ctx, status: str):
'''
"""
Updates playing game status of the bot
'''
"""
await self.bot.change_presence(game=Game(name=status))
await self.bot.say('{}, status has been changed'.format(ctx.message.author.mention))
def setup(bot):
bot.add_cog(Admin_Commands(bot))
bot.add_cog(Admin_Commands(bot))

View File

@ -4,23 +4,22 @@ from DiscordHelperFunctions import *
from bot import bot_commands
@commands.cooldown(5, 60, commands.BucketType.user)
class Delete_Commands:
'''
"""
Commands to help Geoffrey forget.
*You must use ?register before using any of these commands!*
'''
"""
def __init__(self, bot):
self.bot = bot
@commands.command(pass_context=True)
async def delete(self, ctx, *args):
'''
"""
Deletes a location from the database.
?delete [Location name]
'''
"""
loc = get_name(args)
try:
if loc is None:
@ -34,18 +33,18 @@ class Delete_Commands:
@commands.command(pass_context=True)
async def delete_item(self, ctx, item: str, *args):
'''
"""
Deletes an item listing from a shop inventory
?delete_name [Item] [Shop Name]
'''
"""
shop = get_name(args)
try:
bot_commands.delete_item(item, shop, discord_uuid=ctx.message.author.id)
await self.bot.say('{}, **{}** has been removed from the inventory of **{}**.'.
format(ctx.message.author.mention, item, shop))
format(ctx.message.author.mention, item, shop))
except LocationLookUpError:
if shop is None:
await self.bot.say('{}, you do have any shops in the database.'.format(ctx.message.author.mention))
@ -53,7 +52,7 @@ class Delete_Commands:
await self.bot.say('{}, you do not have a shop called **{}**.'.format(ctx.message.author.mention, shop))
except EntryNameNotUniqueError:
await self.bot.say('{}, you have more than one shop in the database, please specify a shop name.'
.format(ctx.message.author.mention))
.format(ctx.message.author.mention))
except DeleteEntryError:
if shop is not None:
await self.bot.say('{}, **{}** does not sell **{}**.'.format(ctx.message.author.mention, shop, item))

View File

@ -12,11 +12,11 @@ class Edit_Commands:
@commands.command(pass_context=True)
@commands.cooldown(5, 60, commands.BucketType.user)
async def edit_pos(self, ctx, x_pos: int, y_pos: int, *args):
'''
"""
Edits the position of a location
?edit_pos [X Coordinate] [Z Coordinate] [Location Name]
'''
"""
loc = get_name(args)
try:
loc_str = bot_commands.edit_pos(x_pos, y_pos, loc, discord_uuid=ctx.message.author.id)
@ -30,11 +30,11 @@ class Edit_Commands:
@commands.command(pass_context=True)
@commands.cooldown(5, 60, commands.BucketType.user)
async def edit_tunnel(self, ctx, tunnel_color: str, tunnel_number: int, *args):
'''
"""
Edits the tunnel of a location
?edit_tunnel [Tunnel Color] [Tunnel Number] [Location Name]
'''
"""
loc = get_name(args)
try:
loc_str = bot_commands.edit_tunnel(tunnel_color, tunnel_number, loc, discord_uuid=ctx.message.author.id)
@ -45,17 +45,18 @@ class Edit_Commands:
await self.bot.say('{}, you do not have a location called **{}**.'.format(
ctx.message.author.mention, loc))
except InvalidTunnelError:
await self.bot.say('{}, **{}** is an invalid tunnel color.'.format(ctx.message.author.mention, tunnel_color))
await self.bot.say(
'{}, **{}** is an invalid tunnel color.'.format(ctx.message.author.mention, tunnel_color))
@commands.command(pass_context=True)
@commands.cooldown(5, 60, commands.BucketType.user)
async def edit_name(self, ctx, new_name: str, current_name: str):
'''
"""
Edits the name of a location
IF A NAME HAS SPACES IN IT YOU NEED TO WRAP IT IN QUOTATION MARKS. ie "Cool Shop 123"
?edit_name [New Name] [Current Name]
'''
"""
try:
loc_str = bot_commands.edit_name(new_name, current_name, discord_uuid=ctx.message.author.id)

View File

@ -5,9 +5,9 @@ from bot import bot_commands
class Search_Commands:
'''
"""
Commands to find stuff.
'''
"""
def __init__(self, bot):
self.bot = bot
@ -15,10 +15,10 @@ class Search_Commands:
@commands.command(pass_context=True)
@commands.cooldown(5, 60, commands.BucketType.user)
async def find(self, ctx, * args):
'''
"""
Finds all the locations and tunnels matching the search term
?find [Search]
'''
"""
search = get_name(args)
try:
@ -35,10 +35,10 @@ class Search_Commands:
@commands.command(pass_context=True)
@commands.cooldown(5, 60, commands.BucketType.user)
async def tunnel(self, ctx, player: str):
'''
"""
Finds all the tunnels a player owns.
?tunnel [Player]
'''
"""
try:
result = bot_commands.tunnel(player)
@ -51,7 +51,7 @@ class Search_Commands:
@commands.command(pass_context=True)
@commands.cooldown(5, 60, commands.BucketType.user)
async def find_around(self, ctx, x_pos: int, z_pos: int, * args):
'''
"""
Finds all the locations around a certain point.
The radius defaults to 200 blocks if no value is given.
Default dimension is overworld.
@ -60,7 +60,7 @@ class Search_Commands:
Optional Flags:
-d [dimension]
'''
"""
radius = 200
dimension = 'Overworld'
@ -94,11 +94,11 @@ class Search_Commands:
@commands.command(pass_context=True)
@commands.cooldown(5, 60, commands.BucketType.user)
async def selling(self, ctx, item_name: str):
'''
"""
Lists all the shops selling an item
?selling [item]
'''
"""
try:
result = bot_commands.selling(item_name)
await self.bot.say('{}, the following shops sell **{}**: \n{}'.format(ctx.message.author.mention, item_name, result))
@ -108,13 +108,13 @@ class Search_Commands:
@commands.command(pass_context=True)
@commands.cooldown(5, 60, commands.BucketType.user)
async def info(self, ctx, * args):
'''
"""
Displays info about a location.
If the location is a shop, it displays the shop's inventory.
?info [Location Name]
'''
"""
loc = get_name(args)
try:
@ -129,9 +129,9 @@ class Search_Commands:
@commands.command(pass_context=True)
@commands.cooldown(5, 60, commands.BucketType.user)
async def me(self, ctx):
'''
"""
Displays all your locations in the database
'''
"""
try:
loc_str = bot_commands.me(discord_uuid=ctx.message.author.id)

View File

@ -139,7 +139,7 @@ class TestCommands(TestCase):
self.commands.register('ZeroHD', '143072699567177728')
self.commands.add_shop(0, 0, shop_name='test shop', discord_uuid='143072699567177728')
tunnel = self.commands.add_tunnel('green', 50, None, discord_uuid='143072699567177728')
self.commands.add_tunnel('green', 50, None, discord_uuid='143072699567177728')
result = self.commands.tunnel('ZeroHD')
@ -240,7 +240,7 @@ class TestCommands(TestCase):
self.commands.update_mc_uuid('0', '143072699567177728')
self.assertRaises(PlayerNotFound, self.commands.add_shop, 0, 0, shop_name='test shop',
mc_uuid='fe7e84132570458892032b69ff188bc3')
mc_uuid='fe7e84132570458892032b69ff188bc3')
def test_update_mc_name(self):
self.commands.register('ZeroHD', '143072699567177728')
@ -253,4 +253,4 @@ class TestCommands(TestCase):
self.commands.update_discord_uuid('143072699567177728', '0')
self.assertRaises(PlayerNotFound, self.commands.add_shop, 0, 0, shop_name='test shop',
discord_uuid='143072699567177728')
discord_uuid='143072699567177728')

View File

@ -56,7 +56,7 @@ class TestGeoffreyDatabase(TestCase):
self.interface.database.add_object(self.session, self.loc)
self.interface.database.add_object(self.session, self.owner)
self.session.commit()
self.loc.owner_id
expr = Location.owner == self.owner
self.interface.database.delete_entry(self.session, Location, expr)
@ -83,7 +83,7 @@ class TestGeoffreyDatabase(TestCase):
def test_add_two_shops(self):
owner = self.add_player()
shop1 = self.add_shop(owner)
self.add_shop(owner)
shop2 = self.interface.add_shop(self.session, owner, 'no u', 1, 3)
loc_list = self.interface.find_location_by_owner(self.session, owner)
@ -97,7 +97,6 @@ class TestGeoffreyDatabase(TestCase):
tunnel2 = self.interface.find_tunnel_by_owner_name(self.session, 'ZeroHD')[0]
self.assertEqual(tunnel1, tunnel2)
def test_add_item(self):
owner = self.add_player()
self.add_shop(owner)
@ -134,7 +133,7 @@ class TestGeoffreyDatabase(TestCase):
def test_find_location_around(self):
owner = self.add_player()
loc = self.add_loc(owner)
self.add_loc(owner)
dim = "o"
@ -172,7 +171,7 @@ class TestGeoffreyDatabase(TestCase):
def test_search_all(self):
owner = self.add_player()
loc = self.add_loc(owner)
self.add_loc(owner)
loc_list = self.interface.search_all_fields(self.session, 'ZeroHD')
@ -202,9 +201,9 @@ class TestGeoffreyDatabase(TestCase):
owner = self.add_player()
self.assertRaises(DatabaseValueError, self.interface.add_base, self.session, owner,
'TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT'
'TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT'
'TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT', 0, 0,)
'TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT'
'TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT'
'TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT', 0, 0, )
def test_duplicate_name(self):
owner = self.add_player()
@ -215,7 +214,7 @@ class TestGeoffreyDatabase(TestCase):
def test_delete_parent(self):
owner = self.add_player()
loc = self.add_shop(owner)
self.add_shop(owner)
self.interface.add_item(self.session, owner, 'test', 'dirt', 1, 15)
@ -223,11 +222,3 @@ class TestGeoffreyDatabase(TestCase):
shops = self.interface.find_shop_selling_item(self.session, 'dirt')
self.assertEqual(len(shops), 0)

View File

@ -0,0 +1,13 @@
from unittest import TestCase
from DiscordHelperFunctions import get_nickname
class TestGet_nickname(TestCase):
def test_get_nickname(self):
class test:
def __init__(self):
self.display_name = 'dootb.in ꙩ ⃤'
self.nick = 'dootb.in ꙩ ⃤'
tmp = test()
self.assertEqual(get_nickname(tmp), 'aeskdar')