From da0aea540c46a98800d7406ae0750d971e241eaa Mon Sep 17 00:00:00 2001 From: Nikolaj Danger Date: Tue, 24 Mar 2020 10:58:36 +0100 Subject: [PATCH 01/16] Made token an external file --- Gwendolyn.py | 6 +++++- token.txt | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 token.txt diff --git a/Gwendolyn.py b/Gwendolyn.py index c0a4457..6a2172a 100644 --- a/Gwendolyn.py +++ b/Gwendolyn.py @@ -10,6 +10,10 @@ import codecs import funcs logging.basicConfig(filename="logfilename.log", level=logging.INFO) + +with open("token.txt","r") as f: + token =f.read() + client = discord.Client() @client.event @@ -167,5 +171,5 @@ async def on_message(message): await message.channel.send(desc) -client.run("MzgwNzI4OTkwMTEwODQyODgx.DO81GQ.rctkEQtieciETXnmsYbwZvvOkaA") +client.run(token) diff --git a/token.txt b/token.txt new file mode 100644 index 0000000..8aa83e1 --- /dev/null +++ b/token.txt @@ -0,0 +1 @@ +MzgwNzI4OTkwMTEwODQyODgx.DO81GQ.rctkEQtieciETXnmsYbwZvvOkaA \ No newline at end of file From de6ee115e7836f3799317842a6ed2008ecd1377f Mon Sep 17 00:00:00 2001 From: Nikolaj Danger Date: Tue, 24 Mar 2020 11:09:31 +0100 Subject: [PATCH 02/16] More logging --- .gitignore | 4 ++++ Gwendolyn.py | 7 +++++-- funcs/lookup/lookupFuncs.py | 19 +++++++++++++------ 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index 28fa97c..832f63e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,10 @@ # Byte-compiled / optimized / DLL files __pycache__/ funcs/__pycache__/ +funcs/lookup/__pycache__/ +funcs/other/__pycache__/ +funcs/roll/__pycache__/ +funcs/swfuncs/__pycache__/ *.py[cod] *$py.class diff --git a/Gwendolyn.py b/Gwendolyn.py index 6a2172a..5615e22 100644 --- a/Gwendolyn.py +++ b/Gwendolyn.py @@ -9,7 +9,7 @@ import codecs import funcs -logging.basicConfig(filename="logfilename.log", level=logging.INFO) +logging.basicConfig(filename="gwendolyn.log", level=logging.INFO) with open("token.txt","r") as f: token =f.read() @@ -40,7 +40,10 @@ async def on_message(message): em = discord.Embed(title = "Help", description = text,colour = 0x59f442) await message.channel.send(embed = em) - if message.content.lower().startswith("!hello"): + elif message.content.lower().startswith("!stop"): + await client.logout() + + elif message.content.lower().startswith("!hello"): localtime = time.asctime( time.localtime(time.time()) ) print("\n"+localtime+"\n"+message.author.name+" ran !hello") logging.info("\n"+localtime+"\n"+message.author.name+" ran !hello") diff --git a/funcs/lookup/lookupFuncs.py b/funcs/lookup/lookupFuncs.py index bf050b9..05b6759 100644 --- a/funcs/lookup/lookupFuncs.py +++ b/funcs/lookup/lookupFuncs.py @@ -1,10 +1,11 @@ import math import discord import json +import logging from funcs import gwendolynFuncs as gf - +logging.basicConfig(filename="gwendolyn.log", level=logging.INFO) def modifier(statistic): mods = math.floor((statistic-10)/2) @@ -18,15 +19,17 @@ abilities = ["acrobatics","animal_handling","arcana","athletics","deception","hi def monsterFunc(content): command = gf.cap(content.lower().replace("!monster ","")) print("Looking up "+command) + logging.info("Looking up "+command) if len(content.lower().split()) < 2: - print("Monster doesn't exist in database") - print("") + print("Monster doesn't exist in database\n") + logging.info("Monster doesn't exist in database\n") return("I don't know that monster...","","","","","") else: data = json.load(open('funcs/lookup/monsters.json', encoding = "utf8")) for monster in data: - print("Found it!") if str(command) == monster["name"]: + print("Found it!") + logging.info("Found it!") if monster["subtype"] != "": typs = (monster["type"]+" ("+monster["subtype"]+")") else: @@ -104,8 +107,8 @@ def monsterFunc(content): text3 = (act) text4 = (react) text5 = (leg_act) - print("Returning monster information") - print("") + print("Returning monster information\n") + logging.info("Returning monster information\n") return(str(command),text1,text2,text3,text4,text5) print("") return("I don't know that monster...","","","","","") @@ -113,12 +116,16 @@ def monsterFunc(content): def spellFunc(content): command = gf.cap(content.lower().replace("!spell ","")) print("Looking up "+command) + logging.info("Looking up "+command) data = json.load(open('funcs/lookup/spells.json', encoding = "utf8")) if str(command) in data: print("Returning spell information") + logging.info("Returning spell information") spell_output = ("***"+str(command)+"***\n*"+str(data[str(command)]["level"])+" level "+str(data[str(command)]["school"])+"\nCasting Time: "+str(data[str(command)]["casting_time"])+"\nRange: "+str(data[str(command)]["range"])+"\nComponents: "+str(data[str(command)]["components"])+"\nDuration: "+str(data[str(command)]["duration"])+"*\n \n"+str(data[str(command)]["description"])) else: print("I don't know that spell") + logging.info("I don't know that spell") spell_output = "I don't think that's a spell" print("Successfully ran !spell") + logging.info("Successfully ran !spell") return(spell_output) From 5394046aebd8eb4ead78a71eeb136e4b3f2ea72e Mon Sep 17 00:00:00 2001 From: Nikolaj Danger Date: Tue, 24 Mar 2020 15:30:45 +0100 Subject: [PATCH 03/16] packaging and testing --- funcs/__init__.py | 8 +++- funcs/gwendolynFuncs.py | 51 +------------------------ funcs/lookup/__init__.py | 1 + funcs/other/__init__.py | 2 + funcs/other/generators.py | 2 +- funcs/other/movie.py | 45 +++++++++++----------- funcs/swfuncs/__init__.py | 2 + funcs/swfuncs/characters.json | 71 +++++++++++++++++++++++++++++++++++ funcs/swfuncs/swchar.py | 5 +++ gwendolynTest.py | 30 +++++++++++++++ 10 files changed, 145 insertions(+), 72 deletions(-) create mode 100644 funcs/lookup/__init__.py create mode 100644 funcs/other/__init__.py create mode 100644 funcs/swfuncs/__init__.py create mode 100644 gwendolynTest.py diff --git a/funcs/__init__.py b/funcs/__init__.py index 0ad39a5..aadbe21 100644 --- a/funcs/__init__.py +++ b/funcs/__init__.py @@ -1 +1,7 @@ -from .gwendolynFuncs import helloFunc, roll_dice, cap, imageFunc, movieFunc, parseChar, parseRoll, spellFunc, monsterFunc, nameGen, tavernGen \ No newline at end of file +from .gwendolynFuncs import helloFunc, roll_dice, cap, imageFunc + +from .swfuncs import parseChar, parseRoll + +from .lookup import spellFunc, monsterFunc + +from .other import nameGen, tavernGen, movieFunc \ No newline at end of file diff --git a/funcs/gwendolynFuncs.py b/funcs/gwendolynFuncs.py index d4744a1..eb3316f 100644 --- a/funcs/gwendolynFuncs.py +++ b/funcs/gwendolynFuncs.py @@ -11,7 +11,7 @@ from .lookup import lookupFuncs from .other import movie, generators from .swfuncs import swchar, swroll -def roll_dice(author, rollStr: str = "1d20"): +def roll_dice(author : str, rollStr : str = "1d20"): print("Rolling "+str(rollStr)) if rollStr == '0/0': # easter eggs return("What do you expect me to do, destroy the universe?") @@ -19,7 +19,7 @@ def roll_dice(author, rollStr: str = "1d20"): adv = 0 if re.search('(^|\s+)(adv|dis)(\s+|$)', rollStr) is not None: adv = 1 if re.search('(^|\s+)adv(\s+|$)', rollStr) is not None else -1 - rollStr = re.sub('(adv|dis)(\s+|$)', '', rollStr) + rollStr = re.sub('(adv|dis)(\s+|$)', '', rollSt res = dice.roll(rollStr, adv=adv) out = res.result outStr = author + ' :game_die:\n' + out @@ -100,50 +100,3 @@ def imageFunc(): print("Successfully returned an image") print("") return(image) - -def movieFunc(): - try: - print("Creating IMDb object") - ia = imdb.IMDb() - - print("Picking a movie") - movs = open("funcs/other/movies.txt", "r") - movlist = movs.read().split("\n") - mov = random.choice(movlist) - movs.close() - - print("Searching for "+mov) - s_result = ia.search_movie(mov) - - print("Getting the data") - movie = s_result[0] - ia.update(movie) - cast = movie['cast'] - pcast = "" - for x in range(3): - if cast[x]: - pcast += cast[x]['name']+", " - print("Successfully ran !movie") - print("") - return(movie['title'], movie['plot'][0].split("::")[0], movie['cover url'].replace("150","600").replace("101","404"), pcast[:-2]) - except: - print("Something bad happened...") - return("error","","","") - -def parseChar(user : str, cmd : str = ""): - return swchar.parseChar(user,cmd) - -def parseRoll(user : str, cmd : str = ""): - return swroll.parseRoll(user,cmd) - -def spellFunc(content): - return lookupFuncs.spellFunc(content) - -def monsterFunc(content): - return lookupFuncs.monsterFunc(content) - -def nameGen(): - return generators.nameGen() - -def tavernGen(): - return generators.tavernGen() diff --git a/funcs/lookup/__init__.py b/funcs/lookup/__init__.py new file mode 100644 index 0000000..5c748ff --- /dev/null +++ b/funcs/lookup/__init__.py @@ -0,0 +1 @@ +from .lookupFuncs import spellFunc, monsterFunc \ No newline at end of file diff --git a/funcs/other/__init__.py b/funcs/other/__init__.py new file mode 100644 index 0000000..8f788c5 --- /dev/null +++ b/funcs/other/__init__.py @@ -0,0 +1,2 @@ +from .generators import nameGen, tavernGen +from .movie import movieFunc \ No newline at end of file diff --git a/funcs/other/generators.py b/funcs/other/generators.py index 5a72823..0a6b339 100644 --- a/funcs/other/generators.py +++ b/funcs/other/generators.py @@ -36,7 +36,7 @@ def nameGen(): if new_letter == "\n": done = True genName = "".join(chain) - print("Generated "+genName+"\n") + print("Generated "+genName) return(genName) def tavernGen(): diff --git a/funcs/other/movie.py b/funcs/other/movie.py index e80a7f9..96d42dc 100644 --- a/funcs/other/movie.py +++ b/funcs/other/movie.py @@ -2,27 +2,30 @@ import imdb import random def movieFunc(): - print("Running !movie") - print("Creating IMDb object") - ia = imdb.IMDb() + try: + print("Creating IMDb object") + ia = imdb.IMDb() - print("Picking a movie") - movs = open("movies.txt", "r") - movlist = movs.read().split("\n") - mov = random.choice(movlist) - movs.close() + print("Picking a movie") + movs = open("funcs/other/movies.txt", "r") + movlist = movs.read().split("\n") + mov = random.choice(movlist) + movs.close() - print("Searching") - s_result = ia.search_movie(mov) + print("Searching for "+mov) + s_result = ia.search_movie(mov) - print("Picking the movie") - movie = s_result[0] - ia.update(movie) - cast = movie['cast'] - pcast = "" - for x in range(3): - if cast[x]: - pcast += cast[x]['name']+", " - print("Successfully ran !movie") - print("") - return(movie['title'], movie['plot'][0].split("::")[0], movie['cover url'].replace("150","600").replace("101","404"), pcast[:-2]) + print("Getting the data") + movie = s_result[0] + ia.update(movie) + cast = movie['cast'] + pcast = "" + for x in range(3): + if cast[x]: + pcast += cast[x]['name']+", " + print("Successfully ran !movie") + print("") + return(movie['title'], movie['plot'][0].split("::")[0], movie['cover url'].replace("150","600").replace("101","404"), pcast[:-2]) + except: + print("Something bad happened...") + return("error","","","") diff --git a/funcs/swfuncs/__init__.py b/funcs/swfuncs/__init__.py new file mode 100644 index 0000000..e4a73de --- /dev/null +++ b/funcs/swfuncs/__init__.py @@ -0,0 +1,2 @@ +from .swchar import parseChar +from .swroll import parseRoll \ No newline at end of file diff --git a/funcs/swfuncs/characters.json b/funcs/swfuncs/characters.json index 3f17672..49edd62 100644 --- a/funcs/swfuncs/characters.json +++ b/funcs/swfuncs/characters.json @@ -69,5 +69,76 @@ "Weapons": {}, "Talents": {}, "Force Powers": {} + }, + "TestUser": { + "Name": "New Character", + "Species": "", + "Career": "", + "Specialization Trees": [], + "Soak": 0, + "Wound Threshold": 0, + "Wounds": 0, + "Strain Threshold": 0, + "Strain": 0, + "Defense, Ranged": 0, + "Defense, Melee": 0, + "Force Rating": 0, + "Characteristics": { + "Brawn": 0, + "Agility": 0, + "Intellect": 0, + "Cunning": 0, + "Willpower": 0, + "Presence": 0 + }, + "Skills": { + "Astrogation": 0, + "Athletics": 0, + "Brawl": 0, + "Charm": 0, + "Coercion": 0, + "Computers": 0, + "Cool": 0, + "Coordination": 0, + "Core Worlds": 0, + "Discipline": 0, + "Gunnery": 0, + "Leadership": 0, + "Lightsaber": 0, + "Lore": 0, + "Mechanics": 0, + "Medicine": 0, + "Melee": 0, + "Negotiation": 0, + "Outer Rim": 0, + "Perception": 0, + "Piloting - Planetary": 0, + "Piloting - Space": 0, + "Ranged - Heavy": 0, + "Ranged - Light": 0, + "Resilience": 0, + "Skullduggery": 0, + "Stealth": 0, + "Streetwise": 0, + "Survival": 0, + "Underworld": 0, + "Vigilance": 0, + "Xenology": 0 + }, + "Lightsaber Characteristic": "Brawn", + "Obligations": {}, + "Morality": { + "Emotional Weakness": "", + "Emotional Strength": "", + "Conflict": "", + "Morality": "" + }, + "Credits": 0, + "Equipment": [], + "Armor": "", + "Critical Injuries": {}, + "Weapons": {}, + "Talents": {}, + "Force Powers": {} } } \ No newline at end of file diff --git a/funcs/swfuncs/swchar.py b/funcs/swfuncs/swchar.py index 85c3fa5..8fa6451 100644 --- a/funcs/swfuncs/swchar.py +++ b/funcs/swfuncs/swchar.py @@ -165,6 +165,11 @@ def parseChar(user : str, cmd : str): json.dump(data,f,indent = 4) return "", "Character for " + user + " created" else: + if cmd == "purge": + del data[user] + with open("funcs/swfuncs/characters.json", "w") as f: + json.dump(data,f,indent = 4) + return "", "Character for " + user + " deleted" return "", charData(user,cmd) def lightsaberChar(user : str): diff --git a/gwendolynTest.py b/gwendolynTest.py new file mode 100644 index 0000000..1ba9dcd --- /dev/null +++ b/gwendolynTest.py @@ -0,0 +1,30 @@ +import unittest + +import funcs + +class testSwChar(unittest.TestCase): + def testNewChar(self): + text1, result = funcs.parseChar("TestUser","") + self.assertEqual(result,"Character for TestUser created") + + def testChangeName(self): + text1, result = funcs.parseChar("TestUser","name TestChar") + self.assertEqual(result,"Changed TestChar's Name to TestChar") + + def testChangeChar(self): + text1, result = funcs.parseChar("TestUser","characteristics brawn 1") + self.assertEqual(result,"Changed New Character's Characteristics") + + def testDelChar(self): + text1, result = funcs.parseChar("TestUser","purge") + self.assertEqual(result,"Character for TestUser deleted") + + +class testGwendolynFuncs(unittest.TestCase): + def testCap(self): + self.assertEqual(funcs.cap("planet of the apes"),"Planet of the Apes") + self.assertEqual(funcs.cap("the greatest showman"),"The Greatest Showman") + self.assertEqual(funcs.cap("i'm the best person!"),"I'm the Best Person!") + +if __name__ == "__main__": + unittest.main() \ No newline at end of file From 780e32fcc6f51511ec2deb1a510963e3e72df0b2 Mon Sep 17 00:00:00 2001 From: Nikolaj Danger Date: Tue, 24 Mar 2020 15:31:39 +0100 Subject: [PATCH 04/16] Packaging and testing --- funcs/gwendolynFuncs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/funcs/gwendolynFuncs.py b/funcs/gwendolynFuncs.py index eb3316f..67428f3 100644 --- a/funcs/gwendolynFuncs.py +++ b/funcs/gwendolynFuncs.py @@ -19,7 +19,7 @@ def roll_dice(author : str, rollStr : str = "1d20"): adv = 0 if re.search('(^|\s+)(adv|dis)(\s+|$)', rollStr) is not None: adv = 1 if re.search('(^|\s+)adv(\s+|$)', rollStr) is not None else -1 - rollStr = re.sub('(adv|dis)(\s+|$)', '', rollSt + rollStr = re.sub('(adv|dis)(\s+|$)', '', rollStr) res = dice.roll(rollStr, adv=adv) out = res.result outStr = author + ' :game_die:\n' + out From b2a47ce11a2c7c3ab1643bf21f84da445e9d7040 Mon Sep 17 00:00:00 2001 From: Nikolaj Danger Date: Tue, 24 Mar 2020 15:49:31 +0100 Subject: [PATCH 05/16] Cleanup in resources --- Gwendolyn.py | 2 +- funcs/gwendolynFuncs.py | 3 --- funcs/lookup/lookupFuncs.py | 4 ++-- funcs/other/generators.py | 2 +- funcs/other/movie.py | 2 +- funcs/swfuncs/swchar.py | 20 +++++++++---------- funcs/swfuncs/swroll.py | 3 ++- help.txt => resources/help.txt | 0 {funcs/lookup => resources}/monsters.json | 0 {funcs/other => resources}/movies.txt | 12 +++++------ {funcs/other => resources}/names.txt | 0 {funcs/lookup => resources}/spells.json | 0 .../swcharacters.json | 0 .../skills.json => resources/swskills.json | 0 .../skills.txt => resources/swskills.txt | 0 .../swtemplates.json | 0 16 files changed, 23 insertions(+), 25 deletions(-) rename help.txt => resources/help.txt (100%) rename {funcs/lookup => resources}/monsters.json (100%) rename {funcs/other => resources}/movies.txt (98%) rename {funcs/other => resources}/names.txt (100%) rename {funcs/lookup => resources}/spells.json (100%) rename funcs/swfuncs/characters.json => resources/swcharacters.json (100%) rename funcs/swfuncs/skills.json => resources/swskills.json (100%) rename funcs/swfuncs/skills.txt => resources/swskills.txt (100%) rename funcs/swfuncs/templates.json => resources/swtemplates.json (100%) diff --git a/Gwendolyn.py b/Gwendolyn.py index 5615e22..96961dc 100644 --- a/Gwendolyn.py +++ b/Gwendolyn.py @@ -34,7 +34,7 @@ async def on_message(message): localtime = time.asctime( time.localtime(time.time()) ) print("\n"+localtime+"\n"+message.author.name+" ran !help") logging.info("\n"+localtime+"\n"+message.author.name+" ran !help") - with codecs.open("help.txt",encoding="utf-8") as f: + with codecs.open("resources/help.txt",encoding="utf-8") as f: text = f.read() print(text) em = discord.Embed(title = "Help", description = text,colour = 0x59f442) diff --git a/funcs/gwendolynFuncs.py b/funcs/gwendolynFuncs.py index 67428f3..ebb6a66 100644 --- a/funcs/gwendolynFuncs.py +++ b/funcs/gwendolynFuncs.py @@ -7,9 +7,6 @@ import urllib #used by imageFunc import imdb #used by movieFunc from .roll import dice -from .lookup import lookupFuncs -from .other import movie, generators -from .swfuncs import swchar, swroll def roll_dice(author : str, rollStr : str = "1d20"): print("Rolling "+str(rollStr)) diff --git a/funcs/lookup/lookupFuncs.py b/funcs/lookup/lookupFuncs.py index 05b6759..73b2c4e 100644 --- a/funcs/lookup/lookupFuncs.py +++ b/funcs/lookup/lookupFuncs.py @@ -25,7 +25,7 @@ def monsterFunc(content): logging.info("Monster doesn't exist in database\n") return("I don't know that monster...","","","","","") else: - data = json.load(open('funcs/lookup/monsters.json', encoding = "utf8")) + data = json.load(open('resources/monsters.json', encoding = "utf8")) for monster in data: if str(command) == monster["name"]: print("Found it!") @@ -117,7 +117,7 @@ def spellFunc(content): command = gf.cap(content.lower().replace("!spell ","")) print("Looking up "+command) logging.info("Looking up "+command) - data = json.load(open('funcs/lookup/spells.json', encoding = "utf8")) + data = json.load(open('resources/spells.json', encoding = "utf8")) if str(command) in data: print("Returning spell information") logging.info("Returning spell information") diff --git a/funcs/other/generators.py b/funcs/other/generators.py index 0a6b339..efa0533 100644 --- a/funcs/other/generators.py +++ b/funcs/other/generators.py @@ -8,7 +8,7 @@ def make_pairs(corpus): yield (corpus[i], corpus[i+1]) def nameGen(): - names = open('funcs/other/names.txt', encoding='utf8').read() + names = open('resources/names.txt', encoding='utf8').read() corpus = list(names) pairs = make_pairs(corpus) diff --git a/funcs/other/movie.py b/funcs/other/movie.py index 96d42dc..207159e 100644 --- a/funcs/other/movie.py +++ b/funcs/other/movie.py @@ -7,7 +7,7 @@ def movieFunc(): ia = imdb.IMDb() print("Picking a movie") - movs = open("funcs/other/movies.txt", "r") + movs = open("resources/movies.txt", "r") movlist = movs.read().split("\n") mov = random.choice(movlist) movs.close() diff --git a/funcs/swfuncs/swchar.py b/funcs/swfuncs/swchar.py index 8fa6451..92fad7c 100644 --- a/funcs/swfuncs/swchar.py +++ b/funcs/swfuncs/swchar.py @@ -2,7 +2,7 @@ import json import string def getName(user : str): - with open("funcs/swfuncs/characters.json", "r") as f: + with open("resources/swcharacters.json", "r") as f: data = json.load(f) if user in data: @@ -81,7 +81,7 @@ def characterSheet(character : dict): return name, text1+"\n\n"+text2+divider+text3 def charData(user : str,cmd : str): - with open("funcs/swfuncs/characters.json", "r") as f: + with open("resources/swcharacters.json", "r") as f: data = json.load(f) key = string.capwords(cmd.split(" ")[0]) @@ -107,7 +107,7 @@ def charData(user : str,cmd : str): if type(lookUpResult) is dict: data[user][key] = lookUpResult - with open("funcs/swfuncs/characters.json", "w") as f: + with open("resources/swcharacters.json", "w") as f: json.dump(data,f,indent = 4) return "Changed " + data[user]["Name"] + "'s " + key else: @@ -133,7 +133,7 @@ def charData(user : str,cmd : str): return "Can't add that" else: data[user][key] = cmd - with open("funcs/swfuncs/characters.json", "w") as f: + with open("resources/swcharacters.json", "w") as f: json.dump(data,f,indent = 4) return "Changed " + data[user]["Name"] + "'s " + key +" to " + cmd else: @@ -142,7 +142,7 @@ def charData(user : str,cmd : str): return "You don't have a character. You can make one with !swchar" def parseChar(user : str, cmd : str): - with open("funcs/swfuncs/characters.json", "r") as f: + with open("resources/swcharacters.json", "r") as f: data = json.load(f) if cmd == " ": @@ -157,30 +157,30 @@ def parseChar(user : str, cmd : str): if user in data: return characterSheet(data[user]) else: - with open("funcs/swfuncs/templates.json", "r") as f: + with open("resources/swtemplates.json", "r") as f: templates = json.load(f) newChar = templates["Character"] data[user] = newChar - with open("funcs/swfuncs/characters.json", "w") as f: + with open("resources/swcharacters.json", "w") as f: json.dump(data,f,indent = 4) return "", "Character for " + user + " created" else: if cmd == "purge": del data[user] - with open("funcs/swfuncs/characters.json", "w") as f: + with open("resources/swcharacters.json", "w") as f: json.dump(data,f,indent = 4) return "", "Character for " + user + " deleted" return "", charData(user,cmd) def lightsaberChar(user : str): - with open("funcs/swfuncs/characters.json", "r") as f: + with open("resources/swcharacters.json", "r") as f: data = json.load(f) if user in data: return data[user]["Lightsaber Characteristic"] def userHasChar(user : str): - with open("funcs/swfuncs/characters.json", "r") as f: + with open("resources/swcharacters.json", "r") as f: data = json.load(f) return user in data diff --git a/funcs/swfuncs/swroll.py b/funcs/swfuncs/swroll.py index e43a002..27182e0 100644 --- a/funcs/swfuncs/swroll.py +++ b/funcs/swfuncs/swroll.py @@ -2,10 +2,11 @@ import random import re import string import json +import os from . import swchar -with open("funcs/swfuncs/skills.json", "r") as f: +with open("resources/swskills.json", "r") as f: skillData = json.load(f) def roll(abi : int = 1, prof : int = 0, dif : int = 3, cha : int = 0, boo : int = 0, setb : int = 0, force : int = 0): diff --git a/help.txt b/resources/help.txt similarity index 100% rename from help.txt rename to resources/help.txt diff --git a/funcs/lookup/monsters.json b/resources/monsters.json similarity index 100% rename from funcs/lookup/monsters.json rename to resources/monsters.json diff --git a/funcs/other/movies.txt b/resources/movies.txt similarity index 98% rename from funcs/other/movies.txt rename to resources/movies.txt index f1a6295..874b825 100644 --- a/funcs/other/movies.txt +++ b/resources/movies.txt @@ -303,13 +303,13 @@ Fantastic Four Fantastic Mr Fox Fargo The Fast and the Furious -The Fast and the Furious 2 (2 Fast 2 Furious) -The Fast and the Furious 3 (Tokyo Drift) -The Fast and the Furious 4 (Fast & Furious) -The Fast and the Furious 5 (Fast Five) +2 Fast 2 Furious +The Fast and the Furious Tokyo Drift +Fast & Furious +Fast Five The Fast and the Furious 6 -The Fast and the Furious 7 (Furious 7) -The Fast and the Furious 8 (The Fate of the Furious) +Furious 7 +The Fate of the Furious Fast and Furious Presents: Hobbs and Shaw Fast Times of Ridgemont High The Fault in Our Stars diff --git a/funcs/other/names.txt b/resources/names.txt similarity index 100% rename from funcs/other/names.txt rename to resources/names.txt diff --git a/funcs/lookup/spells.json b/resources/spells.json similarity index 100% rename from funcs/lookup/spells.json rename to resources/spells.json diff --git a/funcs/swfuncs/characters.json b/resources/swcharacters.json similarity index 100% rename from funcs/swfuncs/characters.json rename to resources/swcharacters.json diff --git a/funcs/swfuncs/skills.json b/resources/swskills.json similarity index 100% rename from funcs/swfuncs/skills.json rename to resources/swskills.json diff --git a/funcs/swfuncs/skills.txt b/resources/swskills.txt similarity index 100% rename from funcs/swfuncs/skills.txt rename to resources/swskills.txt diff --git a/funcs/swfuncs/templates.json b/resources/swtemplates.json similarity index 100% rename from funcs/swfuncs/templates.json rename to resources/swtemplates.json From c0de78d2a7024c17f922459b7b0087ab030934fd Mon Sep 17 00:00:00 2001 From: NikolajDanger <55736883+NikolajDanger@users.noreply.github.com> Date: Tue, 24 Mar 2020 15:59:54 +0100 Subject: [PATCH 06/16] Update .gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 832f63e..655f45b 100644 --- a/.gitignore +++ b/.gitignore @@ -146,4 +146,6 @@ cython_debug/ # static files generated from Django application using `collectstatic` media static + .vscode/ +token.txt From 81589cf533d4248d65b7d11d7c6bf8b0fe04533d Mon Sep 17 00:00:00 2001 From: NikolajDanger <55736883+NikolajDanger@users.noreply.github.com> Date: Tue, 24 Mar 2020 16:00:25 +0100 Subject: [PATCH 07/16] Update token.txt --- token.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/token.txt b/token.txt index 8aa83e1..26e5236 100644 --- a/token.txt +++ b/token.txt @@ -1 +1 @@ -MzgwNzI4OTkwMTEwODQyODgx.DO81GQ.rctkEQtieciETXnmsYbwZvvOkaA \ No newline at end of file +REPLACE WITH TOKEN From d5625e9f42d393c1922f149b97a21b59c0afb3f9 Mon Sep 17 00:00:00 2001 From: Nikolaj Danger Date: Tue, 24 Mar 2020 16:04:54 +0100 Subject: [PATCH 08/16] Updated token.txt --- token.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/token.txt b/token.txt index 26e5236..8aa83e1 100644 --- a/token.txt +++ b/token.txt @@ -1 +1 @@ -REPLACE WITH TOKEN +MzgwNzI4OTkwMTEwODQyODgx.DO81GQ.rctkEQtieciETXnmsYbwZvvOkaA \ No newline at end of file From f96f70d471d33c885b0581f4b5f9f0dc7a7f024a Mon Sep 17 00:00:00 2001 From: NikolajDanger <55736883+NikolajDanger@users.noreply.github.com> Date: Tue, 24 Mar 2020 16:03:04 +0100 Subject: [PATCH 09/16] Update .gitignore --- .gitignore | 2 -- 1 file changed, 2 deletions(-) diff --git a/.gitignore b/.gitignore index 655f45b..832f63e 100644 --- a/.gitignore +++ b/.gitignore @@ -146,6 +146,4 @@ cython_debug/ # static files generated from Django application using `collectstatic` media static - .vscode/ -token.txt From 6e9082c2013ee0326a8bc436a9e265751f2b2bad Mon Sep 17 00:00:00 2001 From: Nikolaj Danger Date: Tue, 24 Mar 2020 16:12:00 +0100 Subject: [PATCH 10/16] remove token.txt --- token.txt | 1 - 1 file changed, 1 deletion(-) delete mode 100644 token.txt diff --git a/token.txt b/token.txt deleted file mode 100644 index 8aa83e1..0000000 --- a/token.txt +++ /dev/null @@ -1 +0,0 @@ -MzgwNzI4OTkwMTEwODQyODgx.DO81GQ.rctkEQtieciETXnmsYbwZvvOkaA \ No newline at end of file From 494716cb9702a0889b046bd0eab0e28fab819057 Mon Sep 17 00:00:00 2001 From: NikolajDanger <55736883+NikolajDanger@users.noreply.github.com> Date: Tue, 24 Mar 2020 16:11:23 +0100 Subject: [PATCH 11/16] Update .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 832f63e..3f6527a 100644 --- a/.gitignore +++ b/.gitignore @@ -147,3 +147,4 @@ cython_debug/ media static .vscode/ +token.txt From 5c85ea8d5b5482a15fa99d28de237d3fa69ada40 Mon Sep 17 00:00:00 2001 From: NikolajDanger <55736883+NikolajDanger@users.noreply.github.com> Date: Tue, 24 Mar 2020 16:27:31 +0100 Subject: [PATCH 12/16] Update README.md --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index bd8f0cc..4f83995 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,7 @@ # Gwendolyn -Gwendolyn is a discord bot that I made. It does a bunch of stuff. \ No newline at end of file +Gwendolyn is a discord bot that I made. It does a bunch of stuff. + +## Setup + +Create a file named "token.txt" that contains your bot token. From 5f78967eb252522fa0b2ed5f8b986ba5ad51fa96 Mon Sep 17 00:00:00 2001 From: Nikolaj Danger Date: Tue, 24 Mar 2020 17:02:27 +0100 Subject: [PATCH 13/16] Some logging and comments --- Gwendolyn.py | 3 +++ funcs/lookup/lookupFuncs.py | 17 ++++++++++++++--- funcs/other/generators.py | 7 +++++-- funcs/other/movie.py | 10 +++++++++- funcs/roll/dice.py | 12 ++++++------ funcs/swfuncs/swchar.py | 3 +++ 6 files changed, 40 insertions(+), 12 deletions(-) diff --git a/Gwendolyn.py b/Gwendolyn.py index 96961dc..6c8526b 100644 --- a/Gwendolyn.py +++ b/Gwendolyn.py @@ -70,6 +70,9 @@ async def on_message(message): logging.info("\n"+localtime+"\n"+message.author.name+" ran !monster") title, text1, text2, text3, text4, text5 = funcs.monsterFunc(message.content) em1 = discord.Embed(title = title, description = text1, colour=0xDEADBF) + + # Sends the received information. Seperates into seperate messages if + # there is too much text await message.channel.send(embed = em1) if text2 != "": if len(text2) < 2048: diff --git a/funcs/lookup/lookupFuncs.py b/funcs/lookup/lookupFuncs.py index 73b2c4e..749fb02 100644 --- a/funcs/lookup/lookupFuncs.py +++ b/funcs/lookup/lookupFuncs.py @@ -30,6 +30,10 @@ def monsterFunc(content): if str(command) == monster["name"]: print("Found it!") logging.info("Found it!") + + # Looks at the information about the monster and returns that information + # in seperate variables, allowing Gwendolyn to know where to seperate + # the messages if monster["subtype"] != "": typs = (monster["type"]+" ("+monster["subtype"]+")") else: @@ -99,18 +103,25 @@ def monsterFunc(content): hit_dice += (" - "+str(con_mod * int(monster["hit_dice"].replace("d"," ").split()[0])*(-1))) if con_mod > 0: hit_dice += (" + "+str(con_mod * int(monster["hit_dice"].replace("d"," ").split()[0]))) + new_part = "\n--------------------" + monster_type = monster["size"]+" "+typs+", "+monster["alignment"]+"*" + basic_info = "\n**Armor Class** "+str(monster["armor_class"])+"\n**Hit Points** "+str(monster["hit_points"])+" ("+hit_dice+")\n**Speed **"+monster["speed"]+new_part+"\n" + text1 = (monster_type+new_part+basic_info+stats+new_part+saving_throws+skills+vulnerabilities+resistances+immunities+c_immunities+"\n**Senses** "+monster["senses"]+"\n**Languages** "+monster["languages"]+"\n**Challenge** "+monster["challenge_rating"]) + text2 = (spec_ab) text3 = (act) text4 = (react) text5 = (leg_act) - print("Returning monster information\n") - logging.info("Returning monster information\n") + + print("Returning monster information") + logging.info("Returning monster information") return(str(command),text1,text2,text3,text4,text5) - print("") + print("Couldn't find monster") + logging.info("Couldn't find monster") return("I don't know that monster...","","","","","") def spellFunc(content): diff --git a/funcs/other/generators.py b/funcs/other/generators.py index efa0533..36278cd 100644 --- a/funcs/other/generators.py +++ b/funcs/other/generators.py @@ -1,7 +1,8 @@ import numpy as np import random +import logging - +logging.basicConfig(filename="gwendolyn.log", level=logging.INFO) def make_pairs(corpus): for i in range(len(corpus)-1): @@ -37,6 +38,7 @@ def nameGen(): done = True genName = "".join(chain) print("Generated "+genName) + logging.info("Generated "+genName) return(genName) def tavernGen(): @@ -44,5 +46,6 @@ def tavernGen(): sp = ["Eel","Dolphin","Dwarf","Pegasus","Pony","Rose","Stag","Wolf","Lamb","Demon","Goat","Spirit","Horde","Jester","Mountain","Eagle","Satyr","Dog","Spider","Star","Dad","Rat","Jeremy","Mouse","Unicorn","Pearl","Ant","Crab","Penguin","Octopus","Lawyer","Ghost","Toad","Handjob","Immigrant","SJW","Dragon","Bard","Sphinx","Soldier","Salmon","Owlbear","Kite","Frost Giant","'̶̧̗̣̰̞̜̤̦̖͗̈́̏͊͒͜+̴͎̰͓̱̻̝̬̼͕̥͍̪͕̮͙͂͝*̶̲̓̊̏'̷̥̺͈̞͒̆̏͋̀̐̇͆̓͊͠'̷͖̱̟̟͉̝̪̮͕̃͑́̍͆̓̌͒̄͛̇͘̚ͅ!̷̡̻̈́#̸̳̰̿̿̏͐̏̓̌̚̚͠¨̷̟͙̱͎̟̱̅̀͋̇͗͂͋͋̕͘´̴̡̡͎͔̦̜̟̼̠̰̤͋́̀̓́̄́̏͂̀͜.̸̛̭͍̮̜͑̋̀̋̈́̇̆̆̌_̸̡̥̜̞̝̮̑͑̓̓̇͜͜^̴̡̢͕̠̖̤̺̭̮̙͕̼̳̺̼͋̿̏̎̑͑̊̀̅͐̚͝͝","Arsonist"] tp = [" Tavern"," Inn","","","","","","","","",""] genTav = random.choice(fp)+" "+random.choice(sp)+random.choice(tp) - print("Generated "+genTav+"\n") + print("Generated "+genTav) + print("Generated "+genTav) return(genTav) diff --git a/funcs/other/movie.py b/funcs/other/movie.py index 207159e..c8b69a1 100644 --- a/funcs/other/movie.py +++ b/funcs/other/movie.py @@ -1,21 +1,28 @@ import imdb import random +import logging + +logging.basicConfig(filename="gwendolyn.log", level=logging.INFO) def movieFunc(): try: print("Creating IMDb object") + logging.info("Creating IMDb object") ia = imdb.IMDb() print("Picking a movie") + logging.info("Picking a movie") movs = open("resources/movies.txt", "r") movlist = movs.read().split("\n") mov = random.choice(movlist) movs.close() print("Searching for "+mov) + logging.info("Searching for "+mov) s_result = ia.search_movie(mov) print("Getting the data") + logging.info("Getting the data") movie = s_result[0] ia.update(movie) cast = movie['cast'] @@ -24,8 +31,9 @@ def movieFunc(): if cast[x]: pcast += cast[x]['name']+", " print("Successfully ran !movie") - print("") + logging.info("Successfully ran !movie") return(movie['title'], movie['plot'][0].split("::")[0], movie['cover url'].replace("150","600").replace("101","404"), pcast[:-2]) except: print("Something bad happened...") + logging.info("Something bad happened...") return("error","","","") diff --git a/funcs/roll/dice.py b/funcs/roll/dice.py index e41e89a..5e4d73f 100644 --- a/funcs/roll/dice.py +++ b/funcs/roll/dice.py @@ -10,7 +10,7 @@ import numexpr from . import errors -log = logging.getLogger(__name__) +logging.basicConfig(filename="gwendolyn.log", level=logging.INFO) VALID_OPERATORS = 'k|rr|ro|mi|ma|ra|e|p' VALID_OPERATORS_ARRAY = VALID_OPERATORS.split('|') @@ -41,10 +41,10 @@ def get_roll_comment(rollStr): no_comment = '' dice_set = re.split('([-+*/().=])', rollStr) dice_set = [d for d in dice_set if not d in (None, '')] - log.debug("Found dice set: " + str(dice_set)) + logging.debug("Found dice set: " + str(dice_set)) for index, dice in enumerate(dice_set): match = DICE_PATTERN.match(dice) - log.debug("Found dice group: " + str(match.groups())) + logging.debug("Found dice group: " + str(match.groups())) no_comment += dice.replace(match.group(5), '') if match.group(5): comment = match.group(5) + ''.join(dice_set[index + 1:]) @@ -85,10 +85,10 @@ class Roll(object): # parse each, returning a SingleDiceResult dice_set = re.split('([-+*/().=])', rollStr) dice_set = [d for d in dice_set if not d in (None, '')] - log.debug("Found dice set: " + str(dice_set)) + logging.debug("Found dice set: " + str(dice_set)) for index, dice in enumerate(dice_set): match = DICE_PATTERN.match(dice) - log.debug("Found dice group: " + str(match.groups())) + logging.debug("Found dice group: " + str(match.groups())) # check if it's dice if match.group(1): roll = self.roll_one(dice.replace(match.group(5), ''), adv) @@ -157,7 +157,7 @@ class Roll(object): skeleton=skeletonReply, raw_dice=self) except Exception as ex: if not isinstance(ex, (SyntaxError, KeyError, errors.AvraeException)): - log.error('Error in roll() caused by roll {}:'.format(rollStr)) + logging.error('Error in roll() caused by roll {}:'.format(rollStr)) traceback.print_exc() return DiceResult(verbose_result="Invalid input: {}".format(ex)) diff --git a/funcs/swfuncs/swchar.py b/funcs/swfuncs/swchar.py index 92fad7c..60721cb 100644 --- a/funcs/swfuncs/swchar.py +++ b/funcs/swfuncs/swchar.py @@ -1,5 +1,8 @@ import json import string +import logging + +logging.basicConfig(filename="gwendolyn.log", level=logging.INFO) def getName(user : str): with open("resources/swcharacters.json", "r") as f: From ec531dbd21c912eab2d6094b2ef2cb244692c9ed Mon Sep 17 00:00:00 2001 From: Nikolaj Danger Date: Tue, 24 Mar 2020 17:05:50 +0100 Subject: [PATCH 14/16] Fixet indentation --- funcs/other/movie.py | 46 ++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/funcs/other/movie.py b/funcs/other/movie.py index c8b69a1..0874163 100644 --- a/funcs/other/movie.py +++ b/funcs/other/movie.py @@ -5,35 +5,35 @@ import logging logging.basicConfig(filename="gwendolyn.log", level=logging.INFO) def movieFunc(): - try: - print("Creating IMDb object") + try: + print("Creating IMDb object") logging.info("Creating IMDb object") - ia = imdb.IMDb() + ia = imdb.IMDb() - print("Picking a movie") + print("Picking a movie") logging.info("Picking a movie") - movs = open("resources/movies.txt", "r") - movlist = movs.read().split("\n") - mov = random.choice(movlist) - movs.close() + movs = open("resources/movies.txt", "r") + movlist = movs.read().split("\n") + mov = random.choice(movlist) + movs.close() - print("Searching for "+mov) + print("Searching for "+mov) logging.info("Searching for "+mov) - s_result = ia.search_movie(mov) + s_result = ia.search_movie(mov) - print("Getting the data") + print("Getting the data") logging.info("Getting the data") - movie = s_result[0] - ia.update(movie) - cast = movie['cast'] - pcast = "" - for x in range(3): - if cast[x]: - pcast += cast[x]['name']+", " - print("Successfully ran !movie") + movie = s_result[0] + ia.update(movie) + cast = movie['cast'] + pcast = "" + for x in range(3): + if cast[x]: + pcast += cast[x]['name']+", " + print("Successfully ran !movie") logging.info("Successfully ran !movie") - return(movie['title'], movie['plot'][0].split("::")[0], movie['cover url'].replace("150","600").replace("101","404"), pcast[:-2]) - except: - print("Something bad happened...") + return(movie['title'], movie['plot'][0].split("::")[0], movie['cover url'].replace("150","600").replace("101","404"), pcast[:-2]) + except: + print("Something bad happened...") logging.info("Something bad happened...") - return("error","","","") + return("error","","","") From 309ee2582ce031b1157afa50d426caecc83576bc Mon Sep 17 00:00:00 2001 From: NikolajDanger Date: Tue, 24 Mar 2020 17:16:31 +0100 Subject: [PATCH 15/16] Fixed a thing --- Gwendolyn.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Gwendolyn.py b/Gwendolyn.py index 6c8526b..7bc1f4b 100644 --- a/Gwendolyn.py +++ b/Gwendolyn.py @@ -12,7 +12,8 @@ import funcs logging.basicConfig(filename="gwendolyn.log", level=logging.INFO) with open("token.txt","r") as f: - token =f.read() + token = f.read() + token = token.replace("\n","") client = discord.Client() From be55f8c564c13e12bae884ffb06d1015d7ffff7f Mon Sep 17 00:00:00 2001 From: Nikolaj Danger Date: Wed, 25 Mar 2020 11:39:29 +0100 Subject: [PATCH 16/16] Minor changes --- Gwendolyn.py | 3 +-- funcs/other/generators.py | 6 +++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Gwendolyn.py b/Gwendolyn.py index 7bc1f4b..db745cb 100644 --- a/Gwendolyn.py +++ b/Gwendolyn.py @@ -12,8 +12,7 @@ import funcs logging.basicConfig(filename="gwendolyn.log", level=logging.INFO) with open("token.txt","r") as f: - token = f.read() - token = token.replace("\n","") + token = f.read().replace("\n","") client = discord.Client() diff --git a/funcs/other/generators.py b/funcs/other/generators.py index 36278cd..7f779ab 100644 --- a/funcs/other/generators.py +++ b/funcs/other/generators.py @@ -42,10 +42,10 @@ def nameGen(): return(genName) def tavernGen(): - fp = ["The Silver","The Golden","The Staggering","The Laughing","The Prancing","The Gilded","The Running","The Howling","The Slaughtered","The Leering","The Drunken","The Leaping","The Roaring","The Frowning","The Lonely","The Wandering","The Mysterious","The Barking","The Black","The Gleaming","The Tap-Dancing","The Sad","The Sexy","The Artificial","The Groovy","The Merciful","The Confused","The Pouting","The Horny","The Okay","The Friendly","The Hungry","The Handicapped","The Fire-breathing","The One-Eyed","The Psychotic","The Mad","The Evil","The Idiotic"] - sp = ["Eel","Dolphin","Dwarf","Pegasus","Pony","Rose","Stag","Wolf","Lamb","Demon","Goat","Spirit","Horde","Jester","Mountain","Eagle","Satyr","Dog","Spider","Star","Dad","Rat","Jeremy","Mouse","Unicorn","Pearl","Ant","Crab","Penguin","Octopus","Lawyer","Ghost","Toad","Handjob","Immigrant","SJW","Dragon","Bard","Sphinx","Soldier","Salmon","Owlbear","Kite","Frost Giant","'̶̧̗̣̰̞̜̤̦̖͗̈́̏͊͒͜+̴͎̰͓̱̻̝̬̼͕̥͍̪͕̮͙͂͝*̶̲̓̊̏'̷̥̺͈̞͒̆̏͋̀̐̇͆̓͊͠'̷͖̱̟̟͉̝̪̮͕̃͑́̍͆̓̌͒̄͛̇͘̚ͅ!̷̡̻̈́#̸̳̰̿̿̏͐̏̓̌̚̚͠¨̷̟͙̱͎̟̱̅̀͋̇͗͂͋͋̕͘´̴̡̡͎͔̦̜̟̼̠̰̤͋́̀̓́̄́̏͂̀͜.̸̛̭͍̮̜͑̋̀̋̈́̇̆̆̌_̸̡̥̜̞̝̮̑͑̓̓̇͜͜^̴̡̢͕̠̖̤̺̭̮̙͕̼̳̺̼͋̿̏̎̑͑̊̀̅͐̚͝͝","Arsonist"] + fp = ["The Silver","The Golden","The Staggering","The Laughing","The Prancing","The Gilded","The Running","The Howling","The Slaughtered","The Leering","The Drunken","The Leaping","The Roaring","The Frowning","The Lonely","The Wandering","The Mysterious","The Barking","The Black","The Gleaming","The Tap-Dancing","The Sad","The Sexy","The Artificial","The Groovy","The Merciful","The Confused","The Pouting","The Horny","The Okay","The Friendly","The Hungry","The Handicapped","The Fire-breathing","The One-Eyed","The Psychotic","The Mad","The Evil","The Idiotic","The Trusty","The Busty"] + sp = ["Eel","Dolphin","Dwarf","Pegasus","Pony","Rose","Stag","Wolf","Lamb","Demon","Goat","Spirit","Horde","Jester","Mountain","Eagle","Satyr","Dog","Spider","Star","Dad","Rat","Jeremy","Mouse","Unicorn","Pearl","Ant","Crab","Penguin","Octopus","Lawyer","Ghost","Toad","Handjob","Immigrant","SJW","Dragon","Bard","Sphinx","Soldier","Salmon","Owlbear","Kite","Frost Giant","Arsonist"] tp = [" Tavern"," Inn","","","","","","","","",""] genTav = random.choice(fp)+" "+random.choice(sp)+random.choice(tp) print("Generated "+genTav) - print("Generated "+genTav) + logging.info("Generated "+genTav) return(genTav)