refactor(command|sondage): continue rewrite of sondage
known issues: datas are not commited in database on reaction on
This commit is contained in:
parent
d5f1f71a0a
commit
76e845e5be
18 changed files with 313 additions and 101 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -3,7 +3,6 @@ __pycache__/
|
||||||
*.pyc
|
*.pyc
|
||||||
.env
|
.env
|
||||||
config.py
|
config.py
|
||||||
!cogs/utils/*
|
|
||||||
.DS_Store
|
.DS_Store
|
||||||
private.py
|
private.py
|
||||||
|
|
||||||
|
@ -11,4 +10,4 @@ private.py
|
||||||
.idea/
|
.idea/
|
||||||
|
|
||||||
#other
|
#other
|
||||||
logs/*
|
*.log
|
|
@ -6,12 +6,12 @@
|
||||||
- [ ] Alias system for commands (e.g. `.alias .ci show .cs`)
|
- [ ] Alias system for commands (e.g. `.alias .ci show .cs`)
|
||||||
- [ ] Migrate MySQL to postgresql
|
- [ ] Migrate MySQL to postgresql
|
||||||
- [x] Prepare bot for python 3.8 and discord.py 1.3.0
|
- [x] Prepare bot for python 3.8 and discord.py 1.3.0
|
||||||
- [x] Create launcher
|
- [ ] Create launcher
|
||||||
- [ ] Create documentation
|
- [ ] Create documentation
|
||||||
|
|
||||||
## Launcher requirements :
|
## Launcher requirements :
|
||||||
|
|
||||||
- [x] Can install the bot
|
- [ ] Can install the bot
|
||||||
- [x] Can launch the bot
|
- [x] Can launch the bot
|
||||||
- [x] Can propose updates
|
- [x] Can propose updates
|
||||||
|
|
||||||
|
@ -82,5 +82,5 @@
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# Cogs.sondage commands `(renamed as cogs.poll)`
|
# Cogs.sondage commands `(renamed as cogs.poll)` `canceled until the frontend development`
|
||||||
- [ ] sondage (help?)
|
- [ ] sondage (help?)
|
||||||
|
|
13
bot.py
13
bot.py
|
@ -26,6 +26,7 @@ l_extensions = (
|
||||||
'cogs.basics',
|
'cogs.basics',
|
||||||
'cogs.utility',
|
'cogs.utility',
|
||||||
'cogs.logs',
|
'cogs.logs',
|
||||||
|
'cogs.poll',
|
||||||
'jishaku',
|
'jishaku',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -127,11 +128,13 @@ class TuxBot(commands.AutoShardedBot):
|
||||||
@property
|
@property
|
||||||
def logs_webhook(self) -> discord.Webhook:
|
def logs_webhook(self) -> discord.Webhook:
|
||||||
logs_webhook = self.config.logs_webhook
|
logs_webhook = self.config.logs_webhook
|
||||||
webhook = discord.Webhook.partial(id=logs_webhook.get('id'),
|
webhook = discord.Webhook.partial(
|
||||||
token=logs_webhook.get('token'),
|
id=logs_webhook.get('id'),
|
||||||
adapter=discord.AsyncWebhookAdapter(
|
token=logs_webhook.get('token'),
|
||||||
self.session)
|
adapter=discord.AsyncWebhookAdapter(
|
||||||
)
|
self.session
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
return webhook
|
return webhook
|
||||||
|
|
||||||
|
|
|
@ -9,9 +9,8 @@ import humanize
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
|
|
||||||
from bot import TuxBot
|
from bot import TuxBot
|
||||||
from .utils.models.lang import Lang
|
|
||||||
from .utils.lang import Texts
|
from .utils.lang import Texts
|
||||||
from .utils.models.warn import Warn
|
from .utils.models import Warn, Lang
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -87,8 +86,9 @@ class Admin(commands.Cog):
|
||||||
message_id)
|
message_id)
|
||||||
await message.edit(content=content)
|
await message.edit(content=content)
|
||||||
except (discord.errors.NotFound, discord.errors.Forbidden):
|
except (discord.errors.NotFound, discord.errors.Forbidden):
|
||||||
await ctx.send(Texts('utils', ctx).get("Unable to find the message"),
|
await ctx.send(
|
||||||
delete_after=5)
|
Texts('utils', ctx).get("Unable to find the message"),
|
||||||
|
delete_after=5)
|
||||||
|
|
||||||
@_say.command(name='to')
|
@_say.command(name='to')
|
||||||
async def _say_to(self, ctx: commands.Context,
|
async def _say_to(self, ctx: commands.Context,
|
||||||
|
@ -120,11 +120,13 @@ class Admin(commands.Cog):
|
||||||
|
|
||||||
await ctx.send(embed=e)
|
await ctx.send(embed=e)
|
||||||
except discord.Forbidden:
|
except discord.Forbidden:
|
||||||
await ctx.send(Texts('admin', ctx).get("Unable to ban this user"),
|
await ctx.send(
|
||||||
delete_after=5)
|
Texts('admin', ctx).get("Unable to ban this user"),
|
||||||
|
delete_after=5)
|
||||||
except discord.errors.NotFound:
|
except discord.errors.NotFound:
|
||||||
await ctx.send(Texts('utils', ctx).get("Unable to find the user..."),
|
await ctx.send(
|
||||||
delete_after=5)
|
Texts('utils', ctx).get("Unable to find the user..."),
|
||||||
|
delete_after=5)
|
||||||
|
|
||||||
"""---------------------------------------------------------------------"""
|
"""---------------------------------------------------------------------"""
|
||||||
|
|
||||||
|
@ -145,11 +147,13 @@ class Admin(commands.Cog):
|
||||||
|
|
||||||
await ctx.send(embed=e)
|
await ctx.send(embed=e)
|
||||||
except discord.Forbidden:
|
except discord.Forbidden:
|
||||||
await ctx.send(Texts('admin', ctx).get("Unable to kick this user"),
|
await ctx.send(
|
||||||
delete_after=5)
|
Texts('admin', ctx).get("Unable to kick this user"),
|
||||||
|
delete_after=5)
|
||||||
except discord.errors.NotFound:
|
except discord.errors.NotFound:
|
||||||
await ctx.send(Texts('utils', ctx).get("Unable to find the user..."),
|
await ctx.send(
|
||||||
delete_after=5)
|
Texts('utils', ctx).get("Unable to find the user..."),
|
||||||
|
delete_after=5)
|
||||||
|
|
||||||
"""---------------------------------------------------------------------"""
|
"""---------------------------------------------------------------------"""
|
||||||
|
|
||||||
|
@ -180,8 +184,9 @@ class Admin(commands.Cog):
|
||||||
for emoji in emojis:
|
for emoji in emojis:
|
||||||
await message.add_reaction(emoji)
|
await message.add_reaction(emoji)
|
||||||
except discord.errors.NotFound:
|
except discord.errors.NotFound:
|
||||||
await ctx.send(Texts('utils', ctx).get("Unable to find the message"),
|
await ctx.send(
|
||||||
delete_after=5)
|
Texts('utils', ctx).get("Unable to find the message"),
|
||||||
|
delete_after=5)
|
||||||
|
|
||||||
@_react.command(name='clear')
|
@_react.command(name='clear')
|
||||||
async def _react_remove(self, ctx: commands.Context, message_id: int):
|
async def _react_remove(self, ctx: commands.Context, message_id: int):
|
||||||
|
@ -190,8 +195,9 @@ class Admin(commands.Cog):
|
||||||
message_id)
|
message_id)
|
||||||
await message.clear_reactions()
|
await message.clear_reactions()
|
||||||
except discord.errors.NotFound:
|
except discord.errors.NotFound:
|
||||||
await ctx.send(Texts('utils', ctx).get("Unable to find the message"),
|
await ctx.send(
|
||||||
delete_after=5)
|
Texts('utils', ctx).get("Unable to find the message"),
|
||||||
|
delete_after=5)
|
||||||
|
|
||||||
"""---------------------------------------------------------------------"""
|
"""---------------------------------------------------------------------"""
|
||||||
|
|
||||||
|
@ -207,8 +213,9 @@ class Admin(commands.Cog):
|
||||||
message_id)
|
message_id)
|
||||||
await message.delete()
|
await message.delete()
|
||||||
except (discord.errors.NotFound, discord.errors.Forbidden):
|
except (discord.errors.NotFound, discord.errors.Forbidden):
|
||||||
await ctx.send(Texts('utils', ctx).get("Unable to find the message"),
|
await ctx.send(
|
||||||
delete_after=5)
|
Texts('utils', ctx).get("Unable to find the message"),
|
||||||
|
delete_after=5)
|
||||||
|
|
||||||
@_delete.command(name='from', aliases=['to', 'in'])
|
@_delete.command(name='from', aliases=['to', 'in'])
|
||||||
async def _delete_from(self, ctx: commands.Context,
|
async def _delete_from(self, ctx: commands.Context,
|
||||||
|
@ -223,8 +230,9 @@ class Admin(commands.Cog):
|
||||||
message_id)
|
message_id)
|
||||||
await message.delete()
|
await message.delete()
|
||||||
except (discord.errors.NotFound, discord.errors.Forbidden):
|
except (discord.errors.NotFound, discord.errors.Forbidden):
|
||||||
await ctx.send(Texts('utils', ctx).get("Unable to find the message"),
|
await ctx.send(
|
||||||
delete_after=5)
|
Texts('utils', ctx).get("Unable to find the message"),
|
||||||
|
delete_after=5)
|
||||||
|
|
||||||
"""---------------------------------------------------------------------"""
|
"""---------------------------------------------------------------------"""
|
||||||
|
|
||||||
|
@ -394,17 +402,18 @@ class Admin(commands.Cog):
|
||||||
|
|
||||||
@commands.command(name='language', aliases=['lang', 'langue', 'langage'])
|
@commands.command(name='language', aliases=['lang', 'langue', 'langage'])
|
||||||
async def _language(self, ctx: commands.Context, locale: str):
|
async def _language(self, ctx: commands.Context, locale: str):
|
||||||
available = self.bot.engine\
|
available = self.bot.engine \
|
||||||
.query(Lang.value)\
|
.query(Lang.value) \
|
||||||
.filter(Lang.key == 'available')\
|
.filter(Lang.key == 'available') \
|
||||||
.one()[0]\
|
.one()[0] \
|
||||||
.split(', ')
|
.split(', ')
|
||||||
|
|
||||||
if locale.lower() not in available:
|
if locale.lower() not in available:
|
||||||
await ctx.send(Texts('admin', ctx).get('Unable to find this language'))
|
await ctx.send(
|
||||||
|
Texts('admin', ctx).get('Unable to find this language'))
|
||||||
else:
|
else:
|
||||||
current = self.bot.engine\
|
current = self.bot.engine \
|
||||||
.query(Lang)\
|
.query(Lang) \
|
||||||
.filter(Lang.key == str(ctx.guild.id))
|
.filter(Lang.key == str(ctx.guild.id))
|
||||||
|
|
||||||
if current.count() > 0:
|
if current.count() > 0:
|
||||||
|
@ -416,7 +425,8 @@ class Admin(commands.Cog):
|
||||||
self.bot.engine.add(new_row)
|
self.bot.engine.add(new_row)
|
||||||
self.bot.engine.commit()
|
self.bot.engine.commit()
|
||||||
|
|
||||||
await ctx.send(Texts('admin', ctx).get('Language changed successfully'))
|
await ctx.send(
|
||||||
|
Texts('admin', ctx).get('Language changed successfully'))
|
||||||
|
|
||||||
|
|
||||||
def setup(bot: TuxBot):
|
def setup(bot: TuxBot):
|
||||||
|
|
|
@ -55,7 +55,8 @@ class Basics(commands.Cog):
|
||||||
file_amount += 1
|
file_amount += 1
|
||||||
with open(file_dir, "r", encoding="utf-8") as file:
|
with open(file_dir, "r", encoding="utf-8") as file:
|
||||||
for line in file:
|
for line in file:
|
||||||
if not line.strip().startswith("#") or not line.strip():
|
if not line.strip().startswith("#") \
|
||||||
|
or not line.strip():
|
||||||
total += 1
|
total += 1
|
||||||
|
|
||||||
return total, file_amount
|
return total, file_amount
|
||||||
|
@ -68,7 +69,7 @@ class Basics(commands.Cog):
|
||||||
with proc.oneshot():
|
with proc.oneshot():
|
||||||
mem = proc.memory_full_info()
|
mem = proc.memory_full_info()
|
||||||
e = discord.Embed(
|
e = discord.Embed(
|
||||||
title=f"{Texts('basics', ctx).get('Information about TuxBot')}",
|
title=Texts('basics', ctx).get('Information about TuxBot'),
|
||||||
color=0x89C4F9)
|
color=0x89C4F9)
|
||||||
|
|
||||||
e.add_field(
|
e.add_field(
|
||||||
|
@ -129,7 +130,7 @@ class Basics(commands.Cog):
|
||||||
name=f"__:link: {Texts('basics', ctx).get('Links')}__",
|
name=f"__:link: {Texts('basics', ctx).get('Links')}__",
|
||||||
value="[tuxbot.gnous.eu](https://tuxbot.gnous.eu/) "
|
value="[tuxbot.gnous.eu](https://tuxbot.gnous.eu/) "
|
||||||
"| [gnous.eu](https://gnous.eu/) "
|
"| [gnous.eu](https://gnous.eu/) "
|
||||||
f"| [{Texts('basics').get('Invite')}](https://discordapp.com/oauth2/authorize?client_id=301062143942590465&scope=bot&permissions=268749888)",
|
f"| [{Texts('basics', ctx).get('Invite')}](https://discordapp.com/oauth2/authorize?client_id=301062143942590465&scope=bot&permissions=268749888)",
|
||||||
inline=False
|
inline=False
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
123
cogs/poll.py
123
cogs/poll.py
|
@ -1,22 +1,133 @@
|
||||||
|
from typing import Union
|
||||||
|
|
||||||
|
import discord
|
||||||
|
import bcrypt
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
|
|
||||||
from bot import TuxBot
|
from bot import TuxBot
|
||||||
from .utils.lang import Texts
|
from .utils.lang import Texts
|
||||||
|
from .utils.models import Poll
|
||||||
|
from .utils import emotes as utils_emotes
|
||||||
|
|
||||||
|
|
||||||
class Poll(commands.Cog):
|
class Polls(commands.Cog):
|
||||||
|
|
||||||
def __init__(self, bot: TuxBot):
|
def __init__(self, bot: TuxBot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
|
||||||
|
def get_poll(self, pld) -> Union[bool, Poll]:
|
||||||
|
if pld.user_id != self.bot.user.id:
|
||||||
|
poll = self.bot.engine \
|
||||||
|
.query(Poll) \
|
||||||
|
.filter(Poll.message_id == pld.message_id) \
|
||||||
|
.one_or_none()
|
||||||
|
|
||||||
|
if poll is not None:
|
||||||
|
emotes = utils_emotes.get(len(poll.responses))
|
||||||
|
|
||||||
|
if pld.emoji.name in emotes:
|
||||||
|
return poll
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
async def remove_reaction(self, pld):
|
||||||
|
channel: discord.TextChannel = self.bot.get_channel(
|
||||||
|
pld.channel_id
|
||||||
|
)
|
||||||
|
message: discord.Message = await channel.fetch_message(
|
||||||
|
pld.message_id
|
||||||
|
)
|
||||||
|
user: discord.User = await self.bot.fetch_user(pld.user_id)
|
||||||
|
|
||||||
|
await message.remove_reaction(pld.emoji.name, user)
|
||||||
|
|
||||||
|
@commands.Cog.listener()
|
||||||
|
async def on_raw_reaction_add(self, pld: discord.RawReactionActionEvent):
|
||||||
|
poll = self.get_poll(pld)
|
||||||
|
|
||||||
|
if poll:
|
||||||
|
if poll.is_anonymous:
|
||||||
|
await self.remove_reaction(pld)
|
||||||
|
|
||||||
|
user_id = str(pld.user_id).encode()
|
||||||
|
responses = poll.responses
|
||||||
|
|
||||||
|
choice = utils_emotes.get_index(pld.emoji.name) + 1
|
||||||
|
responders = responses.get(str(choice))
|
||||||
|
|
||||||
|
if not responders:
|
||||||
|
print(responders, 'before0')
|
||||||
|
user_id_hash = bcrypt.hashpw(user_id, bcrypt.gensalt())
|
||||||
|
responders.append(user_id_hash)
|
||||||
|
print(responders, 'after0')
|
||||||
|
else:
|
||||||
|
for i, responder in enumerate(responders):
|
||||||
|
if bcrypt.checkpw(user_id, responder.encode()):
|
||||||
|
print(responders, 'before1')
|
||||||
|
responders.pop(i)
|
||||||
|
print(responders, 'after1')
|
||||||
|
else:
|
||||||
|
print(responders, 'before2')
|
||||||
|
user_id_hash = bcrypt.hashpw(user_id, bcrypt.gensalt())
|
||||||
|
responders.append(user_id_hash)
|
||||||
|
print(responders, 'after2')
|
||||||
|
|
||||||
|
poll.responses = responses
|
||||||
|
print(poll.responses)
|
||||||
|
self.bot.engine.commit()
|
||||||
|
|
||||||
|
return 1
|
||||||
|
|
||||||
"""---------------------------------------------------------------------"""
|
"""---------------------------------------------------------------------"""
|
||||||
|
|
||||||
|
async def make_poll(self, ctx: commands.Context, poll: str, anonymous):
|
||||||
|
question = (poll.split('|')[0]).strip()
|
||||||
|
responses = [response.strip() for response in poll.split('|')[1:]]
|
||||||
|
responses_row = {}
|
||||||
|
emotes = utils_emotes.get(len(responses))
|
||||||
|
|
||||||
|
stmt = await ctx.send(Texts('poll', ctx).get('**Preparation...**'))
|
||||||
|
|
||||||
|
poll_row = Poll()
|
||||||
|
self.bot.engine.add(poll_row)
|
||||||
|
self.bot.engine.flush()
|
||||||
|
|
||||||
|
e = discord.Embed(description=f"**{question}**")
|
||||||
|
e.set_author(
|
||||||
|
name=ctx.author,
|
||||||
|
icon_url='https://cdn.pixabay.com/photo/2017/05/15/23/48/survey-2316468_960_720.png'
|
||||||
|
)
|
||||||
|
for i, response in enumerate(responses):
|
||||||
|
responses_row[str(i+1)] = []
|
||||||
|
e.add_field(
|
||||||
|
name=f"{emotes[i]} __{response.capitalize()}__",
|
||||||
|
value="**0** vote"
|
||||||
|
)
|
||||||
|
e.set_footer(text=f"ID: {poll_row.id}")
|
||||||
|
|
||||||
|
poll_row.message_id = stmt.id
|
||||||
|
poll_row.poll = e.to_dict()
|
||||||
|
poll_row.is_anonymous = anonymous
|
||||||
|
poll_row.responses = responses_row
|
||||||
|
|
||||||
|
self.bot.engine.commit()
|
||||||
|
|
||||||
|
await stmt.edit(content='', embed=e)
|
||||||
|
for emote in range(len(responses)):
|
||||||
|
await stmt.add_reaction(emotes[emote])
|
||||||
|
|
||||||
@commands.group(name='sondage', aliases=['poll'])
|
@commands.group(name='sondage', aliases=['poll'])
|
||||||
async def _poll(self, ctx):
|
async def _poll(self, ctx: commands.Context):
|
||||||
"""
|
if ctx.invoked_subcommand is None:
|
||||||
todo: refer to readme.md
|
...
|
||||||
"""
|
|
||||||
|
@_poll.group(name='create', aliases=['new', 'nouveau'])
|
||||||
|
async def _poll_create(self, ctx: commands.Context, *, poll: str):
|
||||||
|
is_anonymous = '--anonyme' in poll
|
||||||
|
poll = poll.replace('--anonyme', '')
|
||||||
|
|
||||||
|
await self.make_poll(ctx, poll, anonymous=is_anonymous)
|
||||||
|
|
||||||
|
|
||||||
def setup(bot: TuxBot):
|
def setup(bot: TuxBot):
|
||||||
bot.add_cog(Poll(bot))
|
bot.add_cog(Polls(bot))
|
||||||
|
|
110
cogs/utility.py
110
cogs/utility.py
|
@ -5,6 +5,7 @@ import discord
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
from bot import TuxBot
|
from bot import TuxBot
|
||||||
import socket
|
import socket
|
||||||
|
from socket import AF_INET6
|
||||||
|
|
||||||
from .utils.lang import Texts
|
from .utils.lang import Texts
|
||||||
|
|
||||||
|
@ -23,53 +24,60 @@ class Utility(commands.Cog):
|
||||||
|
|
||||||
await ctx.trigger_typing()
|
await ctx.trigger_typing()
|
||||||
|
|
||||||
if ip_type in ('v6', 'ipv6'):
|
try:
|
||||||
try:
|
if ip_type in ('v6', 'ipv6'):
|
||||||
ip = socket.getaddrinfo(addr, None, socket.AF_INET6)[1][4][0]
|
try:
|
||||||
except socket.gaierror:
|
ip = socket.getaddrinfo(addr, None, AF_INET6)[1][4][0]
|
||||||
return await ctx.send(
|
except socket.gaierror:
|
||||||
Texts('utility', ctx).get('ipv6 not available'))
|
return await ctx.send(
|
||||||
else:
|
Texts('utility', ctx).get('ipv6 not available'))
|
||||||
ip = socket.gethostbyname(addr)
|
|
||||||
|
|
||||||
async with self.bot.session.get(f"http://ip-api.com/json/{ip}") as s:
|
|
||||||
response: dict = await s.json()
|
|
||||||
|
|
||||||
if response.get('status') == 'success':
|
|
||||||
e = discord.Embed(
|
|
||||||
title=f"{Texts('utility', ctx).get('Information for')} "
|
|
||||||
f"``{addr}`` *`({response.get('query')})`*",
|
|
||||||
color=0x5858d7
|
|
||||||
)
|
|
||||||
|
|
||||||
e.add_field(
|
|
||||||
name=Texts('utility', ctx).get('Belongs to :'),
|
|
||||||
value=response.get('org', 'N/A'),
|
|
||||||
inline=False
|
|
||||||
)
|
|
||||||
|
|
||||||
e.add_field(
|
|
||||||
name=Texts('utility', ctx).get('Is located at :'),
|
|
||||||
value=response.get('city', 'N/A'),
|
|
||||||
inline=True
|
|
||||||
)
|
|
||||||
|
|
||||||
e.add_field(
|
|
||||||
name="Region :",
|
|
||||||
value=f"{response.get('regionName', 'N/A')} "
|
|
||||||
f"({response.get('country', 'N/A')})",
|
|
||||||
inline=True
|
|
||||||
)
|
|
||||||
|
|
||||||
e.set_thumbnail(
|
|
||||||
url=f"https://www.countryflags.io/"
|
|
||||||
f"{response.get('countryCode')}/flat/64.png")
|
|
||||||
|
|
||||||
await ctx.send(embed=e)
|
|
||||||
else:
|
else:
|
||||||
await ctx.send(
|
ip = socket.gethostbyname(addr)
|
||||||
content=f"{Texts('utility', ctx).get('info not available')}"
|
|
||||||
f"``{response.get('query')}``")
|
async with self.bot.session.get(f"http://ip-api.com/json/{ip}") \
|
||||||
|
as s:
|
||||||
|
response: dict = await s.json()
|
||||||
|
|
||||||
|
if response.get('status') == 'success':
|
||||||
|
e = discord.Embed(
|
||||||
|
title=f"{Texts('utility', ctx).get('Information for')}"
|
||||||
|
f" ``{addr}`` *`({response.get('query')})`*",
|
||||||
|
color=0x5858d7
|
||||||
|
)
|
||||||
|
|
||||||
|
e.add_field(
|
||||||
|
name=Texts('utility', ctx).get('Belongs to :'),
|
||||||
|
value=response.get('org', 'N/A'),
|
||||||
|
inline=False
|
||||||
|
)
|
||||||
|
|
||||||
|
e.add_field(
|
||||||
|
name=Texts('utility', ctx).get('Is located at :'),
|
||||||
|
value=response.get('city', 'N/A'),
|
||||||
|
inline=True
|
||||||
|
)
|
||||||
|
|
||||||
|
e.add_field(
|
||||||
|
name="Region :",
|
||||||
|
value=f"{response.get('regionName', 'N/A')} "
|
||||||
|
f"({response.get('country', 'N/A')})",
|
||||||
|
inline=True
|
||||||
|
)
|
||||||
|
|
||||||
|
e.set_thumbnail(
|
||||||
|
url=f"https://www.countryflags.io/"
|
||||||
|
f"{response.get('countryCode')}/flat/64.png")
|
||||||
|
|
||||||
|
await ctx.send(embed=e)
|
||||||
|
else:
|
||||||
|
await ctx.send(
|
||||||
|
content=f"{Texts('utility', ctx).get('info not available')}"
|
||||||
|
f"``{response.get('query')}``")
|
||||||
|
|
||||||
|
except Exception:
|
||||||
|
await ctx.send(
|
||||||
|
f"{Texts('utility', ctx).get('Cannot connect to host')} {addr}"
|
||||||
|
)
|
||||||
|
|
||||||
"""---------------------------------------------------------------------"""
|
"""---------------------------------------------------------------------"""
|
||||||
|
|
||||||
|
@ -78,9 +86,10 @@ class Utility(commands.Cog):
|
||||||
if (addr.startswith('http') or addr.startswith('ftp')) is not True:
|
if (addr.startswith('http') or addr.startswith('ftp')) is not True:
|
||||||
addr = f"http://{addr}"
|
addr = f"http://{addr}"
|
||||||
|
|
||||||
|
await ctx.trigger_typing()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
async with self.bot.session.get(addr) as s:
|
async with self.bot.session.get(addr) as s:
|
||||||
await ctx.trigger_typing()
|
|
||||||
e = discord.Embed(
|
e = discord.Embed(
|
||||||
title=f"{Texts('utility', ctx).get('Headers of')} {addr}",
|
title=f"{Texts('utility', ctx).get('Headers of')} {addr}",
|
||||||
color=0xd75858
|
color=0xd75858
|
||||||
|
@ -95,9 +104,10 @@ class Utility(commands.Cog):
|
||||||
e.add_field(name=key, value=value, inline=True)
|
e.add_field(name=key, value=value, inline=True)
|
||||||
await ctx.send(embed=e)
|
await ctx.send(embed=e)
|
||||||
|
|
||||||
except aiohttp.client_exceptions.ClientConnectorError:
|
except aiohttp.client_exceptions.ClientError:
|
||||||
await ctx.send(f"{Texts('utility', ctx).get('Cannot connect to host')} "
|
await ctx.send(
|
||||||
f"{addr}")
|
f"{Texts('utility', ctx).get('Cannot connect to host')} {addr}"
|
||||||
|
)
|
||||||
|
|
||||||
"""---------------------------------------------------------------------"""
|
"""---------------------------------------------------------------------"""
|
||||||
|
|
||||||
|
|
10
cogs/utils/emotes.py
Normal file
10
cogs/utils/emotes.py
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
emotes = ['1⃣', '2⃣', '3⃣', '4⃣', '5⃣', '6⃣', '7⃣', '8⃣', '9⃣', '🔟', '0⃣',
|
||||||
|
'🇦', '🇧', '🇨', '🇩', '🇪', '🇫', '🇬', '🇭', '🇮']
|
||||||
|
|
||||||
|
|
||||||
|
def get(count):
|
||||||
|
return emotes[:count]
|
||||||
|
|
||||||
|
|
||||||
|
def get_index(emote):
|
||||||
|
return emotes.index(emote)
|
3
cogs/utils/models/__init__.py
Normal file
3
cogs/utils/models/__init__.py
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
from .lang import Lang
|
||||||
|
from .warn import Warn
|
||||||
|
from .poll import Poll
|
|
@ -4,7 +4,7 @@ Base = declarative_base()
|
||||||
|
|
||||||
|
|
||||||
class Lang(Base):
|
class Lang(Base):
|
||||||
__tablename__ = 'lang'
|
__tablename__ = 'langs'
|
||||||
|
|
||||||
key = Column(String, primary_key=True)
|
key = Column(String, primary_key=True)
|
||||||
value = Column(String)
|
value = Column(String)
|
||||||
|
|
20
cogs/utils/models/poll.py
Normal file
20
cogs/utils/models/poll.py
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
from sqlalchemy.ext.declarative import declarative_base
|
||||||
|
from sqlalchemy import Column, Integer, Boolean, BigInteger, JSON
|
||||||
|
|
||||||
|
Base = declarative_base()
|
||||||
|
|
||||||
|
|
||||||
|
class Poll(Base):
|
||||||
|
__tablename__ = 'polls'
|
||||||
|
|
||||||
|
id = Column(Integer, primary_key=True)
|
||||||
|
message_id = Column(BigInteger)
|
||||||
|
poll = Column(JSON)
|
||||||
|
is_anonymous = Column(Boolean)
|
||||||
|
responses = Column(JSON, nullable=True)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "<Poll(id='%s', message_id='%s', poll='%s', " \
|
||||||
|
"is_anonymous='%s', responses='%s')>" % \
|
||||||
|
(self.id, self.message_id, self.poll,
|
||||||
|
self.is_anonymous, self.responses)
|
|
@ -2,6 +2,7 @@ import datetime
|
||||||
|
|
||||||
from sqlalchemy.ext.declarative import declarative_base
|
from sqlalchemy.ext.declarative import declarative_base
|
||||||
from sqlalchemy import Column, Integer, String, BIGINT, TIMESTAMP
|
from sqlalchemy import Column, Integer, String, BIGINT, TIMESTAMP
|
||||||
|
|
||||||
Base = declarative_base()
|
Base = declarative_base()
|
||||||
|
|
||||||
|
|
||||||
|
@ -16,5 +17,5 @@ class Warn(Base):
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<Warn(server_id='%s', user_id='%s', reason='%s', " \
|
return "<Warn(server_id='%s', user_id='%s', reason='%s', " \
|
||||||
"created_at='%s')>"\
|
"created_at='%s')>" \
|
||||||
% (self.server_id, self.user_id, self.reason, self.created_at)
|
% (self.server_id, self.user_id, self.reason, self.created_at)
|
||||||
|
|
BIN
extras/locales/en/LC_MESSAGES/poll.mo
Normal file
BIN
extras/locales/en/LC_MESSAGES/poll.mo
Normal file
Binary file not shown.
20
extras/locales/en/LC_MESSAGES/poll.po
Normal file
20
extras/locales/en/LC_MESSAGES/poll.po
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
# SOME DESCRIPTIVE TITLE.
|
||||||
|
# Copyright (C) YEAR ORGANIZATION
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
|
"POT-Creation-Date: 2019-09-08 19:04+0200\n"
|
||||||
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"Generated-By: pygettext.py 1.5\n"
|
||||||
|
|
||||||
|
|
||||||
|
#: launcher.py:51
|
||||||
|
msgid "**Preparation...**"
|
||||||
|
msgstr ""
|
BIN
extras/locales/fr/LC_MESSAGES/poll.mo
Normal file
BIN
extras/locales/fr/LC_MESSAGES/poll.mo
Normal file
Binary file not shown.
20
extras/locales/fr/LC_MESSAGES/poll.po
Normal file
20
extras/locales/fr/LC_MESSAGES/poll.po
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
# SOME DESCRIPTIVE TITLE.
|
||||||
|
# Copyright (C) YEAR ORGANIZATION
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
|
"POT-Creation-Date: 2019-09-08 19:04+0200\n"
|
||||||
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"Generated-By: pygettext.py 1.5\n"
|
||||||
|
|
||||||
|
|
||||||
|
#: launcher.py:51
|
||||||
|
msgid "**Preparation...**"
|
||||||
|
msgstr "**Préparation...**"
|
|
@ -1,5 +1,8 @@
|
||||||
{
|
{
|
||||||
"280805240977227776": [
|
"280805240977227776": [
|
||||||
"b."
|
"b!"
|
||||||
|
],
|
||||||
|
"303633056944881686": [
|
||||||
|
"b! "
|
||||||
]
|
]
|
||||||
}
|
}
|
|
@ -8,3 +8,4 @@ sqlalchemy
|
||||||
gitpython
|
gitpython
|
||||||
requests
|
requests
|
||||||
psutil
|
psutil
|
||||||
|
bcrypt
|
Loading…
Reference in a new issue