Merge pull request #42 from ElBe-Development/dev

Add a few examples and download function
This commit is contained in:
ElBe 2023-01-29 16:55:21 +01:00 committed by GitHub
commit ff7e5775aa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 286 additions and 84 deletions

View File

@ -1,118 +1,265 @@
'''
Functions for the discord.py Bot.
© by ElBe.
Version: 1.6
Version: 1.2
NOTE: Async functions in this file cause errors and should not be created.
'''
#Imports
import json
import os
import discord
import colorama
import datetime
import re
import json
import logging
import os
import platform
import prettytable
import requests
import sqlite3
import typing
#Bot modules
import errors
#Setup
colorama.init()
#Variables
class variables():
'''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():
def get_config(name: str, file = variables.standart_config_file):
'''Returns a value from the given/standart JSON file.'''
with open(file, 'r') as f:
return json.load(f)[name]
'''Module for dealing with JSON files.'''
def write_json(data, show_text = False, file = variables.standart_config_file):
'''Writes the text to the given/standart JSON file.'''
with open(file, 'w') as f:
json.dump(data, f)
f.close()
def __init__(self, file: str = variables.standard_config_file) -> None:
'''Sets a file to be read.
if show_text:
print(console.log('Data ' + str(data) + ' added to ' + str(file) + '.'))
Args:
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():
def info(text: str):
'''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():
def clear() -> None:
'''Clear the console.'''
os.system('cls')
if platform.system() == 'Windows':
os.system('cls')
else:
os.system('clear')
def crusor_up():
'''Changes the position of the crusor to the line above.'''
def cursor_up() -> None:
'''Changes the position of the cursor to the line above.'''
print('\x1b[1A')
def erase_line():
def erase_line() -> None:
'''Erases the current line.'''
print('\x1b[2K')
def erase_last():
def erase_last() -> None:
'''Erases the last line.'''
print('\x1b[1A' + '\x1b[2K' + '\x1b[1A')
class outdated():
def __init__(package: str, min_version: str):
min_version_int = int(min_version.replace('.',''))
class translate_text():
def __init__(category: str, text: str) -> str: #TODO: Add language system (LATER)
'''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:
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:
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
View 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
View 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
}
}