✨
This commit is contained in:
@ -3,7 +3,7 @@ class NoToken(Exception):
|
|||||||
self.message = "No discord bot token has been set in the .env file"
|
self.message = "No discord bot token has been set in the .env file"
|
||||||
super().__init__(self.message)
|
super().__init__(self.message)
|
||||||
|
|
||||||
class MongoCannotConnect(Exception):
|
class CannotConnectToService(Exception):
|
||||||
def __init__(self) -> None:
|
def __init__(self, service: str) -> None:
|
||||||
self.message = "Cannot connect to the mongo client"
|
self.message = f"Cannot connect to {service}"
|
||||||
super().__init__(self.message)
|
super().__init__(self.message)
|
12
gwendolyn/ext/better_netflix.py
Normal file
12
gwendolyn/ext/better_netflix.py
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
from interactions import Extension, slash_command, SlashContext
|
||||||
|
from gwendolyn.utils import PARAMS as params
|
||||||
|
|
||||||
|
class BetterNeflixExtension(Extension):
|
||||||
|
"""Contains the Better Netflix commands."""
|
||||||
|
@slash_command(**params["better_netflix"]["movie"])
|
||||||
|
async def movie(self, ctx: SlashContext):
|
||||||
|
await self.bot.better_netflix.movie(ctx)
|
||||||
|
|
||||||
|
@slash_command(**params["better_netflix"]["show"])
|
||||||
|
async def show(self, ctx: SlashContext):
|
||||||
|
await self.bot.better_netflix.show(ctx)
|
@ -50,3 +50,7 @@ class MiscExtension(Extension):
|
|||||||
log_message = f"{ctx.author.display_name} tried to stop me!"
|
log_message = f"{ctx.author.display_name} tried to stop me!"
|
||||||
self.bot.log(log_message, str(ctx.channel_id))
|
self.bot.log(log_message, str(ctx.channel_id))
|
||||||
await ctx.send(f"I don't think I will, {ctx.author.display_name}")
|
await ctx.send(f"I don't think I will, {ctx.author.display_name}")
|
||||||
|
|
||||||
|
@slash_command(**params["misc"]["echo"])
|
||||||
|
async def echo(self, ctx: SlashContext, text: str):
|
||||||
|
await ctx.send(text)
|
@ -1,5 +1,6 @@
|
|||||||
"""A collection of all Gwendolyn functions."""
|
"""A collection of all Gwendolyn functions."""
|
||||||
|
|
||||||
__all__ = ["Other"]
|
__all__ = ["Other","BetterNetflix", "Sonarr", "Radarr", "TMDb"]
|
||||||
|
|
||||||
from .other import Other
|
from .other import Other
|
||||||
|
from .better_netflix import Radarr, Sonarr, BetterNetflix, TMDb
|
5
gwendolyn/funcs/better_netflix/__init__.py
Normal file
5
gwendolyn/funcs/better_netflix/__init__.py
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
"""Better Netflix functions for Gwendolyn."""
|
||||||
|
|
||||||
|
__all__ = ["BetterNetflix", "Sonarr", "Radarr", "TMDb"]
|
||||||
|
|
||||||
|
from .better_netflix import BetterNetflix, Sonarr, Radarr, TMDb
|
159
gwendolyn/funcs/better_netflix/better_netflix.py
Normal file
159
gwendolyn/funcs/better_netflix/better_netflix.py
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
from requests import get
|
||||||
|
from random import choice
|
||||||
|
import io
|
||||||
|
|
||||||
|
from PIL import Image
|
||||||
|
from interactions import SlashContext, Embed, EmbedFooter, EmbedAttachment, File
|
||||||
|
|
||||||
|
from gwendolyn.exceptions import CannotConnectToService
|
||||||
|
|
||||||
|
class Service():
|
||||||
|
def __init__(self, ip: str, port: str, api_key: str) -> None:
|
||||||
|
self.ip = ip
|
||||||
|
self.port = port
|
||||||
|
self.header = {
|
||||||
|
"accept": "application/json",
|
||||||
|
"X-Api-Key": api_key
|
||||||
|
}
|
||||||
|
|
||||||
|
def test(self):
|
||||||
|
return get(f"http://{self.ip}:{self.port}/api", headers=self.header).ok
|
||||||
|
|
||||||
|
class Radarr(Service):
|
||||||
|
def movies(self):
|
||||||
|
response = get(f"http://{self.ip}:{self.port}/api/v3/movie", headers=self.header)
|
||||||
|
if not response.ok:
|
||||||
|
return []
|
||||||
|
|
||||||
|
return [m for m in response.json() if m["hasFile"]]
|
||||||
|
|
||||||
|
class Sonarr(Service):
|
||||||
|
def shows(self):
|
||||||
|
response = get(f"http://{self.ip}:{self.port}/api/v3/series", headers=self.header)
|
||||||
|
if not response.ok:
|
||||||
|
return []
|
||||||
|
|
||||||
|
return response.json()
|
||||||
|
|
||||||
|
class TMDb():
|
||||||
|
def __init__(self, api_token: str) -> None:
|
||||||
|
self.header = {
|
||||||
|
"accept": "application/json",
|
||||||
|
"Authorization": "Bearer "+api_token
|
||||||
|
}
|
||||||
|
|
||||||
|
def test(self):
|
||||||
|
return get(f"https://api.themoviedb.org/3/account", headers=self.header).ok
|
||||||
|
|
||||||
|
|
||||||
|
class BetterNetflix():
|
||||||
|
def __init__(self, radarr: Radarr, sonarr: Sonarr, tmdb: TMDb, bot) -> None:
|
||||||
|
self.radarr = radarr
|
||||||
|
self.sonarr = sonarr
|
||||||
|
self.tmdb = tmdb
|
||||||
|
self.bot = bot
|
||||||
|
|
||||||
|
services = ["radarr","sonarr","tmdb"]
|
||||||
|
|
||||||
|
for service in services:
|
||||||
|
if getattr(self,service).test():
|
||||||
|
self.bot.log(f"Connected to {service}")
|
||||||
|
else:
|
||||||
|
raise CannotConnectToService(service)
|
||||||
|
|
||||||
|
def _poster_color(self, poster_url: str):
|
||||||
|
response = get(poster_url, stream=True)
|
||||||
|
img = Image.open(io.BytesIO(response.content))
|
||||||
|
img.thumbnail((150, 100))
|
||||||
|
|
||||||
|
# Reduce colors (uses k-means internally)
|
||||||
|
paletted = img.convert('P', palette=Image.ADAPTIVE, colors=6)
|
||||||
|
|
||||||
|
buf = io.BytesIO()
|
||||||
|
img2 = paletted.convert("RGB")
|
||||||
|
img2.save("gwendolyn/resources/temp.jpg")
|
||||||
|
|
||||||
|
# Find the color that occurs most often
|
||||||
|
palette = paletted.getpalette()
|
||||||
|
color_counts = sorted(paletted.getcolors(), reverse=True)
|
||||||
|
palette_index = color_counts[0][1]
|
||||||
|
dominant_color = palette[palette_index*3:palette_index*3+3]
|
||||||
|
|
||||||
|
return dominant_color
|
||||||
|
|
||||||
|
async def movie(self, ctx: SlashContext):
|
||||||
|
msg = await ctx.send("Finding a random movie...")
|
||||||
|
movies = self.radarr.movies()
|
||||||
|
if len(movies) == 0:
|
||||||
|
await msg.edit(content="Unable to find any movies")
|
||||||
|
return
|
||||||
|
|
||||||
|
picked_movie = choice(movies)
|
||||||
|
description = ""
|
||||||
|
|
||||||
|
if "imdb" in picked_movie['ratings']:
|
||||||
|
description += f"<:imdb:1301506320603676782> {picked_movie['ratings']['imdb']['value']}"
|
||||||
|
description += "\u1CBC\u1CBC"
|
||||||
|
|
||||||
|
if "rottenTomatoes" in picked_movie['ratings']:
|
||||||
|
rt_value = picked_movie['ratings']['rottenTomatoes']['value']
|
||||||
|
rt_icon = "<:fresh:1301509701338660894>" if rt_value >= 60 else "<:rotten:1301509685907820607>"
|
||||||
|
description += f"{rt_icon} {rt_value}%"
|
||||||
|
|
||||||
|
if description != "":
|
||||||
|
description += "\n\n"
|
||||||
|
|
||||||
|
year = EmbedFooter(str(picked_movie["year"])) if "year" in picked_movie else None
|
||||||
|
has_poster = len(picked_movie["images"]) > 0 and "remoteUrl" in picked_movie["images"][0]
|
||||||
|
poster = EmbedAttachment(picked_movie["images"][0]["remoteUrl"]) if has_poster else None
|
||||||
|
|
||||||
|
color = self._poster_color(picked_movie["images"][0]["remoteUrl"]) if has_poster else "#ff0000"
|
||||||
|
|
||||||
|
description += picked_movie["overview"]
|
||||||
|
embed = Embed(
|
||||||
|
picked_movie["title"],
|
||||||
|
description,
|
||||||
|
color,
|
||||||
|
thumbnail=poster,
|
||||||
|
footer=year
|
||||||
|
)
|
||||||
|
await msg.edit(content="",embed=embed)
|
||||||
|
|
||||||
|
async def show(self, ctx: SlashContext):
|
||||||
|
msg = await ctx.send("Finding a random show...")
|
||||||
|
shows = self.sonarr.shows()
|
||||||
|
if len(shows) == 0:
|
||||||
|
await msg.edit(content="Unable to find any shows")
|
||||||
|
return
|
||||||
|
|
||||||
|
picked_show = choice(shows)
|
||||||
|
description = ""
|
||||||
|
|
||||||
|
if "imdb" in picked_show['ratings']:
|
||||||
|
description += f"<:imdb:1301506320603676782> {picked_show['ratings']['imdb']['value']}"
|
||||||
|
description += "\u1CBC\u1CBC"
|
||||||
|
|
||||||
|
if "rottenTomatoes" in picked_show['ratings']:
|
||||||
|
rt_value = picked_show['ratings']['rottenTomatoes']['value']
|
||||||
|
rt_icon = "<:fresh:1301509701338660894>" if rt_value >= 60 else "<:rotten:1301509685907820607>"
|
||||||
|
description += f"{rt_icon} {rt_value}%"
|
||||||
|
|
||||||
|
if description != "":
|
||||||
|
description += "\n\n"
|
||||||
|
|
||||||
|
year = EmbedFooter(str(picked_show["year"])) if "year" in picked_show else None
|
||||||
|
images = {i["coverType"]:i for i in picked_show["images"]}
|
||||||
|
has_poster = "poster" in images and "remoteUrl" in images["poster"]
|
||||||
|
poster = EmbedAttachment(images["poster"]["remoteUrl"]) if has_poster else None
|
||||||
|
|
||||||
|
color = self._poster_color(images["poster"]["remoteUrl"]) if has_poster else "#ff0000"
|
||||||
|
|
||||||
|
description += picked_show["overview"]
|
||||||
|
embed = Embed(
|
||||||
|
picked_show["title"],
|
||||||
|
description,
|
||||||
|
color,
|
||||||
|
thumbnail=poster,
|
||||||
|
footer=year
|
||||||
|
)
|
||||||
|
await msg.edit(content="",embed=embed)
|
@ -357,8 +357,14 @@ class ComparePoint(Exp):
|
|||||||
return None
|
return None
|
||||||
if self.comp_op == "=":
|
if self.comp_op == "=":
|
||||||
return 1 if val == r else 0
|
return 1 if val == r else 0
|
||||||
|
if self.comp_op == "<":
|
||||||
|
return 1 if val < r else 0
|
||||||
if self.comp_op == "<=":
|
if self.comp_op == "<=":
|
||||||
return 1 if val <= r else 0
|
return 1 if val <= r else 0
|
||||||
|
if self.comp_op == ">":
|
||||||
|
return 1 if val <= r else 0
|
||||||
|
if self.comp_op == ">=":
|
||||||
|
return 1 if val <= r else 0
|
||||||
else:
|
else:
|
||||||
raise Exception(f"Unknown binop {self.op}")
|
raise Exception(f"Unknown binop {self.op}")
|
||||||
|
|
||||||
@ -451,11 +457,12 @@ class Roll(Exp):
|
|||||||
self.die_type = r2
|
self.die_type = r2
|
||||||
|
|
||||||
self.result = [randint(1,r2) for _ in range(r1)]
|
self.result = [randint(1,r2) for _ in range(r1)]
|
||||||
|
self.show_list = [str(i) for i in self.result]
|
||||||
return self.result
|
return self.result
|
||||||
|
|
||||||
def _show(self, vtable):
|
def _show(self, vtable):
|
||||||
result = self.eval(vtable)
|
self.eval(vtable)
|
||||||
return [str(i) for i in result]
|
return self.show_list
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def die(self) -> int:
|
def die(self) -> int:
|
||||||
@ -505,10 +512,6 @@ class RollKeepHighest(Roll):
|
|||||||
self.show_list = [str(n) if i in max_indices else f"~~{n}~~" for i, n in enumerate(r1)]
|
self.show_list = [str(n) if i in max_indices else f"~~{n}~~" for i, n in enumerate(r1)]
|
||||||
return self.result
|
return self.result
|
||||||
|
|
||||||
def _show(self, vtable):
|
|
||||||
self.eval(vtable)
|
|
||||||
return self.show_list
|
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return f"kep_highest({self.roll},{self.exp})"
|
return f"kep_highest({self.roll},{self.exp})"
|
||||||
|
|
||||||
@ -548,10 +551,6 @@ class RollKeepLowest(Roll):
|
|||||||
self.show_list = [str(n) if i in min_indices else f"~~{n}~~" for i, n in enumerate(r1)]
|
self.show_list = [str(n) if i in min_indices else f"~~{n}~~" for i, n in enumerate(r1)]
|
||||||
return self.result
|
return self.result
|
||||||
|
|
||||||
def _show(self, vtable):
|
|
||||||
self.eval(vtable)
|
|
||||||
return self.show_list
|
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return f"kep_lowest({self.roll},{self.exp})"
|
return f"kep_lowest({self.roll},{self.exp})"
|
||||||
|
|
||||||
@ -591,10 +590,6 @@ class RollMin(Roll):
|
|||||||
self.result = r1
|
self.result = r1
|
||||||
return self.result
|
return self.result
|
||||||
|
|
||||||
def _show(self, vtable):
|
|
||||||
self.eval(vtable)
|
|
||||||
return self.show_list
|
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return f"min({self.roll},{self.exp})"
|
return f"min({self.roll},{self.exp})"
|
||||||
|
|
||||||
@ -634,10 +629,6 @@ class RollMax(Roll):
|
|||||||
self.result = r1
|
self.result = r1
|
||||||
return self.result
|
return self.result
|
||||||
|
|
||||||
def _show(self, vtable):
|
|
||||||
self.eval(vtable)
|
|
||||||
return self.show_list
|
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return f"max({self.roll},{self.exp})"
|
return f"max({self.roll},{self.exp})"
|
||||||
|
|
||||||
@ -687,9 +678,53 @@ class RollExplode(Roll):
|
|||||||
|
|
||||||
return self.result
|
return self.result
|
||||||
|
|
||||||
def _show(self, vtable):
|
def __repr__(self) -> str:
|
||||||
self.eval(vtable)
|
return f"max({self.roll},{self.exp})"
|
||||||
return self.show_list
|
|
||||||
|
def __eq__(self, other: Exp) -> bool:
|
||||||
|
return (
|
||||||
|
isinstance(other, RollMax) and
|
||||||
|
self.roll == other.roll and
|
||||||
|
self.exp == other.exp
|
||||||
|
)
|
||||||
|
|
||||||
|
class RollReroll(Roll):
|
||||||
|
def __init__(self, roll: Roll, comp: ComparePoint = None, once: bool = False):
|
||||||
|
self.roll = roll
|
||||||
|
self.comp = comp
|
||||||
|
self.once = once
|
||||||
|
self.result = None
|
||||||
|
self.show_list = None
|
||||||
|
|
||||||
|
def _eval(self, vtable):
|
||||||
|
if self.result is not None:
|
||||||
|
return self.result
|
||||||
|
|
||||||
|
r1 = self.roll.eval(vtable)
|
||||||
|
|
||||||
|
if not (isinstance(r1,list) and all(isinstance(i,int) for i in r1)):
|
||||||
|
return []
|
||||||
|
|
||||||
|
d = self.die
|
||||||
|
|
||||||
|
if self.comp is None:
|
||||||
|
self.comp = ComparePoint("=", ExpInt(1))
|
||||||
|
|
||||||
|
self.result = []
|
||||||
|
self.show_list = []
|
||||||
|
|
||||||
|
def compare(n, rerolled):
|
||||||
|
if self.comp.eval(vtable, n) and not (rerolled and self.once):
|
||||||
|
self.show_list.append(f"~~{n}~~")
|
||||||
|
compare(randint(1,d), True)
|
||||||
|
else:
|
||||||
|
self.result.append(n)
|
||||||
|
self.show_list.append(str(n))
|
||||||
|
|
||||||
|
for n in r1:
|
||||||
|
compare(n, False)
|
||||||
|
|
||||||
|
return self.result
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return f"max({self.roll},{self.exp})"
|
return f"max({self.roll},{self.exp})"
|
||||||
|
@ -2,18 +2,22 @@
|
|||||||
from string import ascii_letters, digits
|
from string import ascii_letters, digits
|
||||||
from rply import LexerGenerator
|
from rply import LexerGenerator
|
||||||
|
|
||||||
VALID_CHARACTERS = ascii_letters[:3]+ascii_letters[4:]+"_"+digits
|
VALID_CHARACTERS = ascii_letters+"_"+digits
|
||||||
|
|
||||||
TOKENS = [
|
TOKENS = [
|
||||||
("ROLL_DIE", r"d"),
|
("ROLL_DIE", r"d"),
|
||||||
("ROLL_KEEP_HIGHEST", r"kh"),
|
|
||||||
("ROLL_KEEP_LOWEST", r"kl"),
|
("ROLL_KEEP_LOWEST", r"kl"),
|
||||||
|
("ROLL_KEEP_HIGHEST", r"kh?"),
|
||||||
|
("ROLL_REROLL_ONCE", r"ro"),
|
||||||
|
("ROLL_REROLL", r"r"),
|
||||||
("ROLL_MIN", r"min"),
|
("ROLL_MIN", r"min"),
|
||||||
("ROLL_MAX", r"max"),
|
("ROLL_MAX", r"max"),
|
||||||
("ROLL_EXPLODE", r"!"),
|
("ROLL_EXPLODE", r"!"),
|
||||||
|
|
||||||
("SYMBOL_LE", r"\<\="),
|
("SYMBOL_LE", r"\<\="),
|
||||||
# ("SYMBOL_GE", r"\>\="),
|
("SYMBOL_GE", r"\>\="),
|
||||||
|
("SYMBOL_LT", r"\<"),
|
||||||
|
("SYMBOL_GT", r"\>"),
|
||||||
("SYMBOL_EQUALS", r"\="),
|
("SYMBOL_EQUALS", r"\="),
|
||||||
("SYMBOL_ARROW", r"\-\>"),
|
("SYMBOL_ARROW", r"\-\>"),
|
||||||
("SYMBOL_BACKSLASH", r"\\"),
|
("SYMBOL_BACKSLASH", r"\\"),
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
from rply import ParserGenerator
|
from rply import ParserGenerator
|
||||||
|
|
||||||
from lexer import TOKENS
|
from lexer import TOKENS
|
||||||
from ast_nodes import Exp, ExpInt, ExpBinop, ExpLet, ExpVar, ExpMin, ExpMax, ExpRoll, Roll, RollKeepHighest, RollKeepLowest, RollMin, RollMax, RollExplode, ComparePoint, ExpIf, ExpTest, ExpApply, ExpLambda, ExpNeg
|
from ast_nodes import Exp, ExpInt, ExpBinop, ExpLet, ExpVar, ExpMin, ExpMax, ExpRoll, Roll, RollKeepHighest, RollKeepLowest, RollMin, RollMax, RollExplode, ComparePoint, ExpIf, ExpTest, ExpApply, ExpLambda, ExpNeg, RollReroll
|
||||||
|
|
||||||
|
|
||||||
class Parser():
|
class Parser():
|
||||||
@ -11,11 +11,11 @@ class Parser():
|
|||||||
precedence=[
|
precedence=[
|
||||||
('left', ["SYMBOL_BACKSLASH","SYMBOL_ARROW"]),
|
('left', ["SYMBOL_BACKSLASH","SYMBOL_ARROW"]),
|
||||||
('left', ["KEYWORD_LET", "KEYWORD_IN", "KEYWORD_IF", "KEYWORD_THEN", "KEYWORD_ELSE"]),
|
('left', ["KEYWORD_LET", "KEYWORD_IN", "KEYWORD_IF", "KEYWORD_THEN", "KEYWORD_ELSE"]),
|
||||||
('left', ["SYMBOL_EQUALS", "SYMBOL_LE"]),
|
('left', ["SYMBOL_EQUALS", "SYMBOL_LT", "SYMBOL_LE", "SYMBOL_GT", "SYMBOL_GE"]),
|
||||||
('left', ["SYMBOL_PLUS", "SYMBOL_MINUS"]),
|
('left', ["SYMBOL_PLUS", "SYMBOL_MINUS"]),
|
||||||
('left', ["SYMBOL_TIMES", "SYMBOL_DIVIDE"]),
|
('left', ["SYMBOL_TIMES", "SYMBOL_DIVIDE"]),
|
||||||
('left', ["ROLL_DIE"]),
|
('left', ["ROLL_DIE"]),
|
||||||
('right', ["ROLL_KEEP_HIGHEST","ROLL_KEEP_LOWEST","ROLL_MIN","ROLL_MAX","ROLL_EXPLODE"])
|
('right', ["ROLL_KEEP_HIGHEST","ROLL_KEEP_LOWEST","ROLL_MIN","ROLL_MAX","ROLL_EXPLODE","ROLL_REROLL","ROLL_REROLL_ONCE"])
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
self._get_parser()
|
self._get_parser()
|
||||||
@ -97,6 +97,22 @@ class Parser():
|
|||||||
def roll_explode_comp(tokens):
|
def roll_explode_comp(tokens):
|
||||||
return RollExplode(tokens[0], tokens[2])
|
return RollExplode(tokens[0], tokens[2])
|
||||||
|
|
||||||
|
@self.pg.production('roll : roll ROLL_REROLL ')
|
||||||
|
def roll_reroll(tokens):
|
||||||
|
return RollReroll(tokens[0])
|
||||||
|
|
||||||
|
@self.pg.production('roll : roll ROLL_REROLL comp')
|
||||||
|
def roll_reroll_comp(tokens):
|
||||||
|
return RollReroll(tokens[0], tokens[2])
|
||||||
|
|
||||||
|
@self.pg.production('roll : roll ROLL_REROLL_ONCE')
|
||||||
|
def roll_reroll_once(tokens):
|
||||||
|
return RollReroll(tokens[0], None, True)
|
||||||
|
|
||||||
|
@self.pg.production('roll : roll ROLL_REROLL_ONCE comp')
|
||||||
|
def roll_reroll_once_comp(tokens):
|
||||||
|
return RollReroll(tokens[0], tokens[2], True)
|
||||||
|
|
||||||
@self.pg.production('roll : atom ROLL_DIE atom')
|
@self.pg.production('roll : atom ROLL_DIE atom')
|
||||||
def roll(tokens):
|
def roll(tokens):
|
||||||
return Roll(tokens[0], tokens[2])
|
return Roll(tokens[0], tokens[2])
|
||||||
@ -108,7 +124,10 @@ class Parser():
|
|||||||
# Compare Points
|
# Compare Points
|
||||||
|
|
||||||
@self.pg.production("comp : SYMBOL_EQUALS atom")
|
@self.pg.production("comp : SYMBOL_EQUALS atom")
|
||||||
|
@self.pg.production("comp : SYMBOL_LT atom")
|
||||||
@self.pg.production("comp : SYMBOL_LE atom")
|
@self.pg.production("comp : SYMBOL_LE atom")
|
||||||
|
@self.pg.production("comp : SYMBOL_GT atom")
|
||||||
|
@self.pg.production("comp : SYMBOL_GE atom")
|
||||||
def comp_point(tokens):
|
def comp_point(tokens):
|
||||||
return ComparePoint(tokens[0].value,tokens[1])
|
return ComparePoint(tokens[0].value,tokens[1])
|
||||||
|
|
||||||
|
@ -5,8 +5,8 @@ from interactions import Client, Status
|
|||||||
from pymongo import MongoClient # Used for database management
|
from pymongo import MongoClient # Used for database management
|
||||||
|
|
||||||
from gwendolyn.utils import log
|
from gwendolyn.utils import log
|
||||||
from gwendolyn.exceptions import NoToken, MongoCannotConnect
|
from gwendolyn.exceptions import NoToken, CannotConnectToService
|
||||||
from gwendolyn.funcs import Other
|
from gwendolyn.funcs import Other, BetterNetflix, Sonarr, Radarr, TMDb
|
||||||
|
|
||||||
class Gwendolyn(Client):
|
class Gwendolyn(Client):
|
||||||
def __init__(self, testing: bool = True):
|
def __init__(self, testing: bool = True):
|
||||||
@ -41,17 +41,25 @@ class Gwendolyn(Client):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
database_client.admin.command("ping")
|
database_client.admin.command("ping")
|
||||||
|
self.log("Connected to Mango Client")
|
||||||
except:
|
except:
|
||||||
raise MongoCannotConnect()
|
raise CannotConnectToService("Mango Client")
|
||||||
|
|
||||||
if self.testing:
|
if self.testing:
|
||||||
self.log("Testing mode")
|
self.log("Testing mode")
|
||||||
self.database = database_client["Gwendolyn-Test"]
|
self.database = database_client["Gwendolyn-Test"]
|
||||||
|
self.load_extension("interactions.ext.jurigged")
|
||||||
else:
|
else:
|
||||||
self.database = database_client["Gwendolyn"]
|
self.database = database_client["Gwendolyn"]
|
||||||
|
|
||||||
def _add_functions(self):
|
def _add_functions(self):
|
||||||
self.other = Other(self)
|
self.other = Other(self)
|
||||||
|
self.better_netflix = BetterNetflix(
|
||||||
|
Radarr(getenv("RADARR_IP"),getenv("RADARR_PORT"),getenv("RADARR_API_KEY")),
|
||||||
|
Sonarr(getenv("SONARR_IP"),getenv("SONARR_PORT"),getenv("SONARR_API_KEY")),
|
||||||
|
TMDb(getenv("TMDB_API_ACCESS_TOKEN")),
|
||||||
|
self
|
||||||
|
)
|
||||||
|
|
||||||
def _add_extensions(self):
|
def _add_extensions(self):
|
||||||
"""Load cogs."""
|
"""Load cogs."""
|
||||||
|
@ -16,6 +16,18 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"echo" : {
|
||||||
|
"name": "echo",
|
||||||
|
"description": "Make Gwendolyn repeat something",
|
||||||
|
"options" : [
|
||||||
|
{
|
||||||
|
"name" : "text",
|
||||||
|
"description" : "The text you want Gwendolyn to repeat",
|
||||||
|
"type" : 3,
|
||||||
|
"required" : "true"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"gen_name" : {
|
"gen_name" : {
|
||||||
"name": "gen_name",
|
"name": "gen_name",
|
||||||
"description": "Generate a random name"
|
"description": "Generate a random name"
|
||||||
@ -44,5 +56,15 @@
|
|||||||
"name" : "thank",
|
"name" : "thank",
|
||||||
"description" : "Thank Gwendolyn for her service"
|
"description" : "Thank Gwendolyn for her service"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"better_netflix": {
|
||||||
|
"movie": {
|
||||||
|
"name": "movie",
|
||||||
|
"description": "Get a random movie from Better Netflix"
|
||||||
|
},
|
||||||
|
"show": {
|
||||||
|
"name": "show",
|
||||||
|
"description": "Get a random show from Better Netflix"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
BIN
gwendolyn/resources/temp.jpg
Normal file
BIN
gwendolyn/resources/temp.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.8 KiB |
Reference in New Issue
Block a user