Merge pull request #42 from ElBe-Development/dev
Add a few examples and download function
This commit is contained in:
commit
ff7e5775aa
315
Bot/functions.py
315
Bot/functions.py
@ -1,118 +1,265 @@
|
|||||||
'''
|
'''
|
||||||
Functions for the discord.py Bot.
|
Functions for the discord.py Bot.
|
||||||
© by ElBe.
|
© by ElBe.
|
||||||
|
Version: 1.6
|
||||||
|
|
||||||
Version: 1.2
|
NOTE: Async functions in this file cause errors and should not be created.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
#Imports
|
#Imports
|
||||||
import json
|
import discord
|
||||||
import os
|
|
||||||
import colorama
|
import colorama
|
||||||
import datetime
|
import datetime
|
||||||
import re
|
import json
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import platform
|
||||||
|
import prettytable
|
||||||
import requests
|
import requests
|
||||||
|
import sqlite3
|
||||||
|
import typing
|
||||||
|
|
||||||
#Bot modules
|
#Bot modules
|
||||||
import errors
|
import errors
|
||||||
|
|
||||||
|
#Setup
|
||||||
|
colorama.init()
|
||||||
|
|
||||||
|
#Variables
|
||||||
class variables():
|
class variables():
|
||||||
'''All variables used in this module.'''
|
'''All variables used in this module.'''
|
||||||
standart_config_file = 'config.json'
|
|
||||||
standart_datetime_format = datetime.date.isoformat
|
standard_logging_file: typing.Final[str] = 'data\\log\\' + str(datetime.datetime.today()) + '.txt'
|
||||||
|
standard_datetime_format: typing.Final[str] = '%Y-%m-%d %H:%M:%S'
|
||||||
|
standard_logging_format: typing.Final[str] = colorama.Fore.LIGHTBLUE_EX + '{timestamp}' + colorama.Style.RESET_ALL + ' [{color}{level}' + colorama.Style.RESET_ALL + '] {name} {message}'
|
||||||
|
standard_config_file: typing.Final[str] = 'data\\config.json'
|
||||||
|
standard_database_file: typing.Final[str] = 'data\\bot.db'
|
||||||
|
standard_intents: typing.Final[discord.Intents] = discord.Intents.all()
|
||||||
|
|
||||||
class json_module():
|
class json_module():
|
||||||
def get_config(name: str, file = variables.standart_config_file):
|
'''Module for dealing with JSON files.'''
|
||||||
'''Returns a value from the given/standart JSON file.'''
|
|
||||||
with open(file, 'r') as f:
|
|
||||||
return json.load(f)[name]
|
|
||||||
|
|
||||||
def write_json(data, show_text = False, file = variables.standart_config_file):
|
def __init__(self, file: str = variables.standard_config_file) -> None:
|
||||||
'''Writes the text to the given/standart JSON file.'''
|
'''Sets a file to be read.
|
||||||
with open(file, 'w') as f:
|
|
||||||
json.dump(data, f)
|
|
||||||
f.close()
|
|
||||||
|
|
||||||
if show_text:
|
Args:
|
||||||
print(console.log('Data ' + str(data) + ' added to ' + str(file) + '.'))
|
file (str, optional): File to read. Defaults to variables.standard_config_file.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None
|
||||||
|
'''
|
||||||
|
|
||||||
|
self.file = file
|
||||||
|
|
||||||
|
def get_value(name: str, file: str = variables.standard_config_file) -> object: #TODO: Change all occurrences
|
||||||
|
'''Returns a value parsed from a JSON config file.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
name (str): Name of the key to be parsed.
|
||||||
|
file (str, optional): Relative path to the json config file. Default to 'data\\config.json'.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
object: Object parsed from the JSON file.
|
||||||
|
'''
|
||||||
|
try:
|
||||||
|
with open(file, 'r') as f:
|
||||||
|
return json.load(f)[name]
|
||||||
|
except Exception as e:
|
||||||
|
return errors.DataLoadingError(e.__cause__)
|
||||||
|
|
||||||
|
def write_json(data: object, file: str) -> None:
|
||||||
|
'''Writes data to a JSON file.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
data (object): Data to insert.
|
||||||
|
file (str): Relative path to the json file.
|
||||||
|
'''
|
||||||
|
try:
|
||||||
|
with open(file, 'w') as f:
|
||||||
|
json.dump(data, f)
|
||||||
|
f.close()
|
||||||
|
except Exception as e:
|
||||||
|
return errors.DataWritingError(e.__cause__)
|
||||||
|
|
||||||
|
def __str__(self) -> str:
|
||||||
|
'''Returns contents of the file as a string.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: Contents of the file.
|
||||||
|
'''
|
||||||
|
|
||||||
|
with open(self.file, 'r') as f:
|
||||||
|
return str(f.read())
|
||||||
|
|
||||||
|
class database():
|
||||||
|
'''Still in beta!'''
|
||||||
|
def __init__(self, database: str = variables.standard_database_file) -> None:
|
||||||
|
self.database = sqlite3.connect(database)
|
||||||
|
self.cursor = database.cursor()
|
||||||
|
|
||||||
|
def get_value(self, key: str, table: str, whereKey: str, whereValue: str) -> object:
|
||||||
|
self.cursor.execute('SELECT ' + key + ' FROM ' + table + ' WHERE ' + whereKey + ' = ' + whereValue)
|
||||||
|
return self.cursor.fetchall()
|
||||||
|
|
||||||
|
def insert_value(self, key: str) -> object:
|
||||||
|
pass
|
||||||
|
|
||||||
class console():
|
class console():
|
||||||
def info(text: str):
|
def clear() -> None:
|
||||||
'''Returns a info text.'''
|
|
||||||
i = 0
|
|
||||||
if len(re.findall('\n', text)) > 1:
|
|
||||||
text = '\n' + text
|
|
||||||
search = len(re.findall('\n', text))
|
|
||||||
|
|
||||||
if search > 1:
|
|
||||||
for i in range(search):
|
|
||||||
text = text.replace('\n', '//n[' + colorama.Fore.LIGHTBLUE_EX + str(i + 1) + colorama.Style.RESET_ALL + '] ', 1)
|
|
||||||
i = i + 1
|
|
||||||
text = text.replace('//n', '\n')
|
|
||||||
return colorama.Fore.LIGHTBLUE_EX + str(datetime.datetime.now().strftime('%d.%m.%Y %T')) + colorama.Style.RESET_ALL + ' [' + colorama.Fore.GREEN + 'INFO' + colorama.Style.RESET_ALL + '] ' + text
|
|
||||||
|
|
||||||
def error(text: str):
|
|
||||||
'''Returns a error text.'''
|
|
||||||
i = 0
|
|
||||||
if len(re.findall('\n', text)) > 1:
|
|
||||||
text = '\n' + text
|
|
||||||
search = len(re.findall('\n', text))
|
|
||||||
|
|
||||||
if search > 1:
|
|
||||||
for i in range(search):
|
|
||||||
text = text.replace('\n', '//n[' + colorama.Fore.LIGHTBLUE_EX + str(i + 1) + colorama.Style.RESET_ALL + '] ', 1)
|
|
||||||
i = i + 1
|
|
||||||
text = text.replace('//n', '\n')
|
|
||||||
return colorama.Fore.LIGHTBLUE_EX + str(datetime.datetime.now().strftime('%d.%m.%Y %T')) + colorama.Style.RESET_ALL + ' [' + colorama.Fore.RED + 'ERROR' + colorama.Style.RESET_ALL + '] ' + text
|
|
||||||
|
|
||||||
def warn(text: str):
|
|
||||||
'''Returns a warn text.'''
|
|
||||||
i = 0
|
|
||||||
if len(re.findall('\n', text)) > 1:
|
|
||||||
text = '\n' + text
|
|
||||||
search = len(re.findall('\n', text))
|
|
||||||
|
|
||||||
if search > 1:
|
|
||||||
for i in range(search):
|
|
||||||
text = text.replace('\n', '//n[' + colorama.Fore.LIGHTBLUE_EX + str(i + 1) + colorama.Style.RESET_ALL + '] ', 1)
|
|
||||||
i = i + 1
|
|
||||||
text = text.replace('//n', '\n')
|
|
||||||
return colorama.Fore.LIGHTBLUE_EX + str(datetime.datetime.now().strftime('%d.%m.%Y %T')) + colorama.Style.RESET_ALL + ' [' + colorama.Fore.YELLOW + 'WARNING' + colorama.Style.RESET_ALL + '] ' + text
|
|
||||||
|
|
||||||
def log(text: str):
|
|
||||||
'''Returns a log text.'''
|
|
||||||
i = 0
|
|
||||||
if len(re.findall('\n', text)) > 1:
|
|
||||||
text = '\n' + text
|
|
||||||
search = len(re.findall('\n', text))
|
|
||||||
|
|
||||||
if search > 1:
|
|
||||||
for i in range(search):
|
|
||||||
text = text.replace('\n', '//n[' + colorama.Fore.LIGHTBLUE_EX + str(i + 1) + colorama.Style.RESET_ALL + '] ', 1)
|
|
||||||
i = i + 1
|
|
||||||
text = text.replace('//n', '\n')
|
|
||||||
return colorama.Fore.LIGHTBLUE_EX + str(datetime.datetime.now().strftime('%d.%m.%Y %T')) + colorama.Style.RESET_ALL + ' [LOG] ' + text
|
|
||||||
|
|
||||||
def clear():
|
|
||||||
'''Clear the console.'''
|
'''Clear the console.'''
|
||||||
os.system('cls')
|
if platform.system() == 'Windows':
|
||||||
|
os.system('cls')
|
||||||
|
else:
|
||||||
|
os.system('clear')
|
||||||
|
|
||||||
def crusor_up():
|
def cursor_up() -> None:
|
||||||
'''Changes the position of the crusor to the line above.'''
|
'''Changes the position of the cursor to the line above.'''
|
||||||
print('\x1b[1A')
|
print('\x1b[1A')
|
||||||
|
|
||||||
def erase_line():
|
def erase_line() -> None:
|
||||||
'''Erases the current line.'''
|
'''Erases the current line.'''
|
||||||
print('\x1b[2K')
|
print('\x1b[2K')
|
||||||
|
|
||||||
def erase_last():
|
def erase_last() -> None:
|
||||||
'''Erases the last line.'''
|
'''Erases the last line.'''
|
||||||
print('\x1b[1A' + '\x1b[2K' + '\x1b[1A')
|
print('\x1b[1A' + '\x1b[2K' + '\x1b[1A')
|
||||||
|
|
||||||
class outdated():
|
class translate_text():
|
||||||
def __init__(package: str, min_version: str):
|
def __init__(category: str, text: str) -> str: #TODO: Add language system (LATER)
|
||||||
min_version_int = int(min_version.replace('.',''))
|
'''MODULE IS TURNED OFF'''
|
||||||
|
return
|
||||||
|
|
||||||
|
#language = str(json_module.get_config('Config')['Language'])
|
||||||
|
#if category == 'B':
|
||||||
|
# return json_module.get_config('Bot', 'data/lang/' + language + '/bot.json')[text]
|
||||||
|
#elif category == 'C':
|
||||||
|
# return json_module.get_config('Commands', 'data/lang/' + language + '/commands.json')[text]
|
||||||
|
#elif category == 'CC':
|
||||||
|
# return json_module.get_config('Command creator', 'data/lang/' + language + '/command_creator.json')[text]
|
||||||
|
#elif category == 'E':
|
||||||
|
# return json_module.get_config('Error', 'data/lang/' + language + '/errors.json')[text]
|
||||||
|
#elif category == 'F':
|
||||||
|
# return json_module.get_config('Functions', 'data\\lang\\' + language + '\\functions.json')[text]
|
||||||
|
#elif category == 'R':
|
||||||
|
# with open('data\\lang\\' + json_module.get_config('Config')['Language'] + '\\rules.txt', 'r') as f:
|
||||||
|
# return f.read()
|
||||||
|
#else:
|
||||||
|
# errors.UnexpectedValueError('B, C, CC, E, F, R', category)
|
||||||
|
|
||||||
|
class formation():
|
||||||
|
def format_table(table: prettytable.PrettyTable):
|
||||||
|
'''Format prettytable.PrettyTables to look better.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
table (prettytable.PrettyTable): Table to format.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
table: Formatted table.
|
||||||
|
'''
|
||||||
|
|
||||||
|
table.vertical_char = '│'
|
||||||
|
table.horizontal_char = '─'
|
||||||
|
table.junction_char = '┼'
|
||||||
|
table.left_junction_char = '├'
|
||||||
|
table.right_junction_char = '┤'
|
||||||
|
table.top_left_junction_char = '┌'
|
||||||
|
table.top_right_junction_char = '┐'
|
||||||
|
table.top_junction_char = '┬'
|
||||||
|
table.bottom_left_junction_char = '└'
|
||||||
|
table.bottom_right_junction_char = '┘'
|
||||||
|
table.bottom_junction_char = '┴'
|
||||||
|
|
||||||
|
return table
|
||||||
|
|
||||||
|
class create_command():
|
||||||
|
def __init__(self, json: dict) -> None:
|
||||||
|
'''Creates a command with given json data.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
json (dict): Json data to use when creating the command.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None
|
||||||
|
'''
|
||||||
|
|
||||||
|
self.json = json
|
||||||
|
|
||||||
try:
|
try:
|
||||||
latest_version = int(str(json.loads(requests.get('https://pypi.python.org/pypi/' + package + '/json').text)['info']['version']).replace('.', ''))
|
requests.post('https://discord.com/api/v10/applications/' + str(json_module.get_config('Config')['Application ID']) + '/commands', headers={'Authorization': 'Bot ' + str(json_module.get_config('Config')['Token'])}, json=json)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(console.error('Package not found.'))
|
print('Error while trying to create the command /' + str(json['name']) + '.\n' + str(e))
|
||||||
|
|
||||||
|
def __str__(self) -> str:
|
||||||
|
'''String representation of the command creator.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: The string representation of the command creator.
|
||||||
|
'''
|
||||||
|
|
||||||
|
return 'Trying to create command /' + self.json['name'] + ' with json:' + str(self.json)
|
||||||
|
|
||||||
|
class log():
|
||||||
|
def __init__(self, message: str, level: str) -> None:
|
||||||
|
'''Logs a message on the given level.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
message (str): Message to log.
|
||||||
|
level (str): Level to log with. Has to be 'CRITICAL','ERROR','WARNING','INFO' or'DEBUG'. Defaults to 'DEBUG'.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None
|
||||||
|
'''
|
||||||
|
|
||||||
|
self.message = message
|
||||||
|
self.level = level if level is not None else self.default_level
|
||||||
|
|
||||||
|
|
||||||
|
def setup(self, format: str = variables.standard_logging_format, default_level: str = 'DEBUG', default_name: str = 'ROOT') -> None:
|
||||||
|
'''Sets up logging with the given format, a default level and a default name for unnamed loggers.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
format (str, optional): Format for logging. Has to contain '{message}', '{level}' and '{timestamp}'. Can contain '{name}' and '{color}'. Defaults to variables.standard_logging_format.
|
||||||
|
default_level (str, optional): Default logging level. Has to be 'CRITICAL','ERROR','WARNING','INFO' or'DEBUG'. Defaults to 'DEBUG'.
|
||||||
|
default_name (str, optional): Default logger name. Each function can have its own logger or logger. Defaults to 'ROOT'.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None
|
||||||
|
'''
|
||||||
|
|
||||||
|
self.format = format
|
||||||
|
self.default_level = default_level
|
||||||
|
self.default_name = default_name
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
'''String representation of the logged message.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: The string representation of the logged message.
|
||||||
|
'''
|
||||||
|
|
||||||
|
return #TODO: add return value
|
||||||
|
|
||||||
|
class download():
|
||||||
|
def __init__(url: str, file: str) -> None:
|
||||||
|
'''ATTENTION: The download function is still in experimental state! Errors are expected and should be reported.
|
||||||
|
|
||||||
|
Downloads a file from the specified url to the specified file in the download directory.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
url (str): URL to download file from.
|
||||||
|
file (str): File name to write to. Don't include path.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None
|
||||||
|
'''
|
||||||
|
|
||||||
|
if os.path.splitext(url)[1] == os.path.splitext(file)[1]:
|
||||||
|
if os.path.exists(os.path.expanduser('~\\Downloads\\' + file)):
|
||||||
|
raise FileExistsError('File ' + file + ' already exists')
|
||||||
|
else:
|
||||||
|
with open(os.path.expanduser('~\\Downloads\\' + file), 'x') as f:
|
||||||
|
for line in str(str(requests.get(url).content).replace('b\'', '')).split('\\n')[:-1]:
|
||||||
|
f.write(line + '\n')
|
||||||
|
else:
|
||||||
|
errors.FileExtensionError('File extension from ' + url + ' is not the same as the file extension from ' + file + '.')
|
||||||
|
|||||||
29
Examples/command.py
Normal file
29
Examples/command.py
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
'''
|
||||||
|
Example command for the discord.py Bot.
|
||||||
|
© by ElBe.
|
||||||
|
Version: 1.0
|
||||||
|
'''
|
||||||
|
#Imports
|
||||||
|
import discord
|
||||||
|
import functions
|
||||||
|
|
||||||
|
#Main
|
||||||
|
async def __init__(interaction: discord.Interaction, *args):
|
||||||
|
'''Example command cog.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
`/example`
|
||||||
|
|
||||||
|
Args:
|
||||||
|
interaction (discord.Interaction): Interaction provided by on_interaction.
|
||||||
|
'''
|
||||||
|
|
||||||
|
if interaction.data['name'] == 'example':
|
||||||
|
functions.log('Command /example was used by @' + str(interaction.user) + '.')
|
||||||
|
if functions.json_module.get_config('Commands')['example']:
|
||||||
|
print('This is an example!')
|
||||||
|
else:
|
||||||
|
commandDisabledEmbed = discord.Embed(title='Command disabled', description='This command was disabled in the bot config file. Ask a member with access to the bot to enable this command.')
|
||||||
|
commandDisabledEmbed.set_thumbnail(url=interaction.client.user.avatar.url)
|
||||||
|
commandDisabledEmbed.set_footer(text=functions.json_module.get_config('Config')['Footer'])
|
||||||
|
await interaction.response.send_message(embed=commandDisabledEmbed, ephemeral=True)
|
||||||
26
Examples/config.json
Normal file
26
Examples/config.json
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"Config": {
|
||||||
|
"Token": "MYDISCORDBOT",
|
||||||
|
"Application ID": "1234567890",
|
||||||
|
"Version": "1.9.3 final",
|
||||||
|
"Version-Comment": "That happend.",
|
||||||
|
"Footer": "Made by ElBe.",
|
||||||
|
"Credits": true
|
||||||
|
},
|
||||||
|
"Channels": {
|
||||||
|
"Welcome": "welcome-and-goodbye",
|
||||||
|
"Goodbye": "welcome-and-goodbye"
|
||||||
|
},
|
||||||
|
"Roles": {
|
||||||
|
"Member": "member"
|
||||||
|
},
|
||||||
|
"Commands": {
|
||||||
|
"stop": true,
|
||||||
|
"help": true,
|
||||||
|
"info": true,
|
||||||
|
"ping": true,
|
||||||
|
"kick": true,
|
||||||
|
"ban": true,
|
||||||
|
"unban": true
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user