114 Commits
master ... v0.1

Author SHA1 Message Date
bb2966a867 testing registry 2024-05-29 22:04:33 +03:00
5915bde104 testing registry 2024-05-29 22:01:20 +03:00
1ac50de2d1 testing registry 2024-05-29 22:00:32 +03:00
693d865b95 testing registry 2024-05-29 21:58:24 +03:00
fff65ba25d testing registry 2024-05-29 21:55:28 +03:00
40bf30b19f testing registry 2024-05-29 21:51:11 +03:00
3e4f8937f3 testing registry 2024-05-29 21:47:40 +03:00
a9eb223616 testing registry 2024-05-29 21:46:01 +03:00
b515fb0f81 testing registry 2024-05-29 21:43:38 +03:00
9a280d3814 testing registry 2024-05-29 21:37:01 +03:00
031758c2cd added requrement.txt 2024-05-29 21:31:23 +03:00
9fb61e2b98 Merge remote-tracking branch 'origin/test' into test
# Conflicts:
#	.gitlab-ci.yml
2024-05-29 21:22:10 +03:00
aafa3c33a9 added requrement.txt 2024-05-29 21:21:41 +03:00
Slava
01792e12da Update .gitlab-ci.yml file 2024-05-29 18:11:24 +00:00
6801d9a0fd added requrement.txt 2024-05-29 21:05:28 +03:00
f314a50e3f Merge remote-tracking branch 'origin/test' into test 2024-05-29 20:51:18 +03:00
c22b71353f added requrement.txt 2024-05-29 20:50:54 +03:00
Slava
899527436f Update .gitlab-ci.yml file 2024-05-29 17:12:12 +00:00
Slava
95ac0caf30 Update .gitlab-ci.yml file 2024-05-29 12:23:28 +00:00
Slava
27f4cd6122 Update file .gitlab-ci.yml 2024-05-29 12:22:27 +00:00
39ec9b9bf7 added requrement.txt 2024-05-29 04:54:17 +03:00
1aaa489f55 added requrement.txt 2024-05-29 04:04:46 +03:00
bb3fda4778 added requrement.txt 2024-05-29 03:45:44 +03:00
c108d7d32c added requrement.txt 2024-05-29 02:31:18 +03:00
9bb86699f7 added requrement.txt 2024-05-29 02:27:24 +03:00
c9f6407149 added requrement.txt 2024-05-29 02:21:32 +03:00
335c661a34 added requrement.txt 2024-05-29 02:20:24 +03:00
bc304827f5 added requrement.txt 2024-05-29 02:19:48 +03:00
9a143ba84a added requrement.txt 2024-05-29 02:15:55 +03:00
Slava
9fc0c4c071 Update .gitlab-ci.yml file 2024-05-28 22:39:09 +00:00
Slava
1852f4ebe2 Update .gitlab-ci.yml file 2024-05-28 21:41:28 +00:00
bacon
37eef98e20 docker bush ended 2024-03-22 01:07:29 +03:00
bacon
62a8921e10 docker bush ended 2024-03-21 21:04:00 +03:00
bacon
14dd773d5c docker 2024-03-21 18:37:56 +03:00
bacon
c8d2f7c344 docker 2024-03-21 18:35:23 +03:00
bacon
720cff55c1 docker 2024-03-21 18:27:49 +03:00
Slava
4a539becca Update Dockerfile 2024-03-21 09:13:34 +00:00
bacon
734427d16f docker 2024-03-21 10:59:41 +03:00
bacon
fa08480a34 docker 2024-03-21 10:32:53 +03:00
bacon
581d9d4c84 docker 2024-03-21 02:47:04 +03:00
bacon
bbb597f5f6 docker 2024-03-21 02:42:40 +03:00
bacon
109f61c146 Merge remote-tracking branch 'gitlab/test' into test 2024-03-21 02:26:28 +03:00
bacon
f9ce4c9d2d docker 2024-03-21 02:26:22 +03:00
Slava
2725b7a499 Удалить .editorconfig 2024-03-20 23:15:59 +00:00
bacon
721b33d963 docker 2024-03-21 01:59:53 +03:00
bacon
b3e8502804 docker 2024-03-21 01:59:13 +03:00
bacon
9652cac405 docker 2024-03-21 01:53:17 +03:00
bacon
cd182db4ba docker 2024-03-21 01:52:20 +03:00
bacon
fde794e7aa docker 2024-03-21 01:44:58 +03:00
bacon
efb5fd0531 docker 2024-03-21 01:39:39 +03:00
bacon
641ab7c3fb docker 2024-03-21 00:27:30 +03:00
bacon
0e7a32f36a docker 2024-03-21 00:21:45 +03:00
bacon
7faad7df23 docker 2024-03-20 23:58:32 +03:00
bacon
43457b7fc1 docker 2024-03-20 23:58:06 +03:00
bacon
5ee3403c3f docker 2024-03-20 23:51:20 +03:00
bacon
5f8cf83d35 docker 2024-03-20 23:40:58 +03:00
bacon
e3cdb3812a docker 2024-03-20 23:39:26 +03:00
bacon
50ccbca4be docker 2024-03-20 23:38:44 +03:00
bacon
f19bcabe61 docker 2024-03-20 23:19:41 +03:00
Slava
f33ec2fc20 Update .gitlab-ci.yml file 2024-03-20 20:16:34 +00:00
bacon
877348711e docker 2024-03-20 22:57:52 +03:00
bacon
52c1d2717e docker 2024-03-20 22:40:13 +03:00
bacon
7adfe234fb docker 2024-03-20 22:31:21 +03:00
Slava
e867dd23c1 Update .gitlab-ci.yml file 2024-03-20 19:24:02 +00:00
bacon
99ded107f1 Merge remote-tracking branch 'gitlab/test' into test 2024-03-20 22:21:26 +03:00
bacon
fc492d1ba8 docker 2024-03-20 22:21:09 +03:00
Slava
f98c77faf9 Update .gitlab-ci.yml file 2024-03-17 23:33:46 +00:00
bacon
da9755e948 Merge remote-tracking branch 'gitlab/test' into test 2024-03-18 02:27:15 +03:00
bacon
98e71f66e9 fixed start after move 2024-03-18 02:27:01 +03:00
Slava
ca1837318d Update .gitlab-ci.yml file 2024-03-17 23:12:28 +00:00
bacon
76d1625346 fixed start after move 2024-03-18 02:08:16 +03:00
bacon
fff1a5c0c7 fixed start after move 2024-03-18 01:49:40 +03:00
bacon
e1fc05dea2 Merge remote-tracking branch 'gitlab/test' into test 2024-03-18 01:05:05 +03:00
bacon
d352541a86 fixed start after move 2024-03-18 01:04:53 +03:00
Slava
1a6c0c1f49 Update .gitlab-ci.yml file 2024-03-17 21:51:47 +00:00
bacon
361a39420a fixed start after move 2024-03-18 00:44:04 +03:00
bacon
765acd0d42 fixed start after move 2024-03-18 00:43:18 +03:00
bacon
ee277e44c8 Merge remote-tracking branch 'gitlab/test' into test
# Conflicts:
#	.gitlab-ci.yml
2024-03-18 00:39:59 +03:00
bacon
eaaffd2056 fixed start after move 2024-03-18 00:38:57 +03:00
Slava
4598294bd1 Update .gitlab-ci.yml file 2024-03-17 21:33:40 +00:00
bacon
4c5a5718fc fixed start after move 2024-03-18 00:24:27 +03:00
bacon
29246e7b97 fixed start after move 2024-03-18 00:19:14 +03:00
bacon
3048bf1f51 test coverage 2024-03-17 23:01:59 +03:00
bacon
d93654043a changes in test 2024-03-17 22:56:37 +03:00
Slava
93198bf82b Update .gitlab-ci.yml file 2024-03-17 19:20:26 +00:00
Slava
e60793315b Update .gitlab-ci.yml file 2024-03-17 19:18:21 +00:00
bacon
d1e62a3941 changes in test 2024-03-17 22:13:07 +03:00
bacon
758d775a5b Update .gitlab-ci.yml file 2024-03-17 22:07:39 +03:00
bacon
d22c3ca6b6 updated structure 2024-03-17 22:03:27 +03:00
bacon
4e535f6580 updated lib_Cog test 2024-03-17 21:34:03 +03:00
bacon
cb72e48f09 Merge remote-tracking branch 'gitlab/test' into test
# Conflicts:
#	tests/test_lib_Cog.py
2024-03-17 17:15:42 +03:00
bacon
786c580b47 uptated requrements.txt 2024-03-17 17:14:13 +03:00
Slava
46de864da3 Update test_lib_Cog.py 2024-03-17 12:45:36 +00:00
Slava
a4e672597c Update CogsPrep.py 2024-03-17 12:30:23 +00:00
Slava
9fa7624be7 Update test_lib_Cog.py 2024-03-17 11:59:10 +00:00
Slava
073be5e629 Update .gitlab-ci.yml file 2024-03-17 11:56:02 +00:00
Slava
16ea4ede05 Update .gitlab-ci.yml file 2024-03-17 11:54:47 +00:00
Slava
b6539a31fc Update .gitlab-ci.yml 2024-03-17 11:50:25 +00:00
Slava
6a07ef45f2 Update CogsPrep.py 2024-03-17 11:48:47 +00:00
Slava
814f88756c Update test_lib_Cog.py 2024-03-17 11:48:25 +00:00
Slava
49122706a7 Update requirements.txt 2024-03-17 07:01:16 +00:00
Slava
39da2d53fc Update .gitlab-ci.yml file 2024-03-17 07:00:02 +00:00
Slava
7d32b69809 Update requirements.txt 2024-03-17 06:58:51 +00:00
Slava
8fba876e93 Update .gitlab-ci.yml 2024-03-17 06:58:08 +00:00
Slava
a28cd1e421 Update .gitlab-ci.yml file 2024-03-17 06:54:18 +00:00
Slava
ca25888325 Update .gitlab-ci.yml file 2024-03-17 06:46:18 +00:00
Slava
2ec3efbdeb Update .gitlab-ci.yml file 2024-03-17 06:39:39 +00:00
Slava
e31039eb8b Update .gitlab-ci.yml file 2024-03-17 06:38:12 +00:00
Slava
6fe0df2fb7 Update .gitlab-ci.yml 2024-03-17 06:35:51 +00:00
bacon
308272803d uptated requrements.txt 2024-03-17 09:31:49 +03:00
Slava
a9d50dc478 Update .gitlab-ci.yml file 2024-03-17 06:31:20 +00:00
Slava
958c70ef4d Update .gitlab-ci.yml 2024-03-17 06:28:01 +00:00
bacon
fca483e4e6 ended test_lib_Cog.py 2024-03-17 02:17:07 +03:00
bacon
736621c516 added base tests 2024-03-15 15:46:45 +03:00
54 changed files with 1255 additions and 996 deletions

11
.dockerignore Normal file
View File

@@ -0,0 +1,11 @@
/tmp/
audio/*/
/.idea
user.db
*.pyc
/.run/
.env
*.exe
/venv/
config.json
.editorconfig

11
.gitignore vendored
View File

@@ -1,14 +1,11 @@
/tmp/ /tmp/
/audio/*/ audio/*/
/.idea /.idea
/user.db user.db
*.pyc *.pyc
/.run/ /.run/
/.env .env
*.exe *.exe
/venv/ /venv/
/fun_and_admin_bot.egg-info/
/.YMcache/
config.json config.json
/env/ .editorconfig
/.project

View File

@@ -1,19 +1,111 @@
# You can override the included template(s) by including variable overrides
# SAST customization: https://docs.gitlab.com/ee/user/application_security/sast/#customizing-the-sast-settings
# Secret Detection customization: https://docs.gitlab.com/ee/user/application_security/secret_detection/#customizing-settings
# Dependency Scanning customization: https://docs.gitlab.com/ee/user/application_security/dependency_scanning/#customizing-the-dependency-scanning-settings
# Container Scanning customization: https://docs.gitlab.com/ee/user/application_security/container_scanning/#customizing-the-container-scanning-settings
# Note that environment variables can be set in several places
# See https://docs.gitlab.com/ee/ci/variables/#cicd-variable-precedence
stages: stages:
- 'test' - 'test'
- 'code_quality' - 'build'
- 'deploy' - 'push'
pytest:
sast:
stage: 'test' stage: 'test'
include: image: python
- template: Security/SAST.gitlab-ci.yml only:
- template: Security/Dependency-Scanning.gitlab-ci.yml - test
- template: Security/SAST-IaC.gitlab-ci.yml - tags
cache:
paths:
- $CI_PROJECT_DIR/venv/
before_script:
- cd $CI_PROJECT_DIR
- python -m venv venv
- chmod u+x venv/bin/activate
- source venv/bin/activate
- pip install --upgrade --quiet pip
- pip install --quiet -U -r requirements.txt
- pip install --quiet -U -r tests/requirements.txt
script:
- pytest -v
variables:
# DOCKER_HOST: tcp://docker:2375
# fill those if you have a proxy in your environment
DOCKER_DRIVER: overlay2
# See https://github.com/docker-library/docker/pull/166
DOCKER_TLS_CERTDIR: "/certs"
make_image:
stage: build
needs:
- pytest
image: docker:26.1.3
services:
- docker:26.1.3-dind
before_script:
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
script:
# fetches the latest image (not failing if image is not found)
- docker pull $CI_REGISTRY_IMAGE:latest || true
# builds the project, passing proxy variables, using OCI labels
# notice the cache-from, which is going to use the image we just pulled locally
# the built image is tagged locally with the commit SHA, and then pushed to
# the GitLab registry
- >
DOCKER_BUILDKIT=1 docker build
--pull
--cache-from $CI_REGISTRY_IMAGE:latest
--label "org.opencontainers.image.title=$CI_PROJECT_TITLE"
--label "org.opencontainers.image.url=$CI_PROJECT_URL"
--label "org.opencontainers.image.created=$CI_JOB_STARTED_AT"
--label "org.opencontainers.image.revision=$CI_COMMIT_SHA"
--label "org.opencontainers.image.version=$CI_COMMIT_REF_NAME"
--tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
.
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
# Here, the goal is to tag the "master" branch as "latest"
Push latest:
variables:
# We are just playing with Docker here.
# We do not need GitLab to clone the source code.
GIT_STRATEGY: none
stage: push
before_script:
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
script:
# Because we have no guarantee that this job will be picked up by the same runner
# that built the image in the previous step, we pull it again locally
- docker pull $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
# Then we tag it "latest"
- docker tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA $CI_REGISTRY_IMAGE:latest
# Annnd we push it.
- docker push $CI_REGISTRY_IMAGE:latest
# Finally, the goal here is to Docker tag any Git tag
# GitLab will start a new pipeline everytime a Git tag is created, which is pretty awesome
Push commit:
variables:
# Again, we do not need the source code here. Just playing with Docker.
GIT_STRATEGY: none
stage: push
before_script:
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
script:
- docker pull $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
- docker tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_NAME
Push tag:
variables:
# Again, we do not need the source code here. Just playing with Docker.
GIT_STRATEGY: none
stage: push
only:
# We want this job to be run on tags only.
- tags
before_script:
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
script:
- docker pull $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
- docker tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA $CI_REGISTRY_IMAGE:$CI_COMMIT_TAG
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_TAG

View File

@@ -1,2 +0,0 @@
0.0.5
Initial

22
Dockerfile Normal file
View File

@@ -0,0 +1,22 @@
FROM python:3.12.2-slim-bookworm as builder
LABEL authors="bacon"
WORKDIR /app
COPY requirements.txt /app
RUN pip wheel install \
--no-cache-dir -q \
--no-deps --wheel-dir /app/wheels \
-r requirements.txt
FROM python:3.12.2-slim-bookworm as runner
WORKDIR /app
COPY --from=builder /app/wheels /wheels
RUN apt-get update -qq && \
apt-get install -qq --no-install-recommends ffmpeg -y && \
apt-get clean -qq autoclean && \
pip install --no-cache -q /wheels/*
COPY src/ /app
ENTRYPOINT ["python", "bot.py"]
#ENTRYPOINT ["ffmpeg"]

0
docker-compose.yml Normal file
View File

View File

@@ -1,45 +0,0 @@
"""
lib.CogsPrepare
~~~~~~~~~~~~~
Loads, unloads Cogs files
cog_list: return list of cog filenames
work_with_cogs: loads, reloads and unloads cogs files
"""
from os import listdir, rename
from typing import List
from disnake.ext import commands
# from .Logger import logger
from loguru import logger
async def cog_list(fold: str = './cogs') -> List[str]:
cogs_list = []
for _filename in listdir(fold):
if _filename.endswith('.py'):
cogs_list.append(_filename[:-3])
return cogs_list
async def work_with_cogs(what_do, bot: commands.Bot, cog):
if isinstance(cog, str):
cog = cog.split()
for _filename in cog:
if what_do == "load":
bot.load_extension(f'cogs.{_filename}')
logger.info(f'Loaded cog {_filename}')
elif what_do == 'unload':
bot.unload_extension(f'cogs.{_filename}')
logger.info(f'Cog {_filename} unloaded')
elif what_do == 'reload':
bot.reload_extension(f'cogs.{_filename}')
logger.info(f'Cog {_filename} reloaded')
elif what_do == 'disable':
bot.unload_extension(f'cogs.{_filename}')
rename(f'cogs/{_filename}.py', f'cogs/disabled/{_filename}.py')
logger.info(f'Cog {_filename} stopped and disabled')
elif what_do == 'enable':
rename(f'cogs/disabled/{_filename}.py', f'cogs/{_filename}.py')
bot.load_extension(f'cogs.{_filename}')
logger.info(f'Cog {_filename} started and enabled')

View File

@@ -1,5 +0,0 @@
"""
lib
~~~~~~~~~~~~~
Some libs for the bot which help him
"""

View File

@@ -1,6 +0,0 @@
version: "1.0"
bootstrap: |
rm -rf .idea
pip install -U -r requirements.txt
profile:
name: qodana.recommended

Binary file not shown.

View File

@@ -1,16 +1,16 @@
__version__ = '0.0.8' __version__ = '0.0.7'
__title__ = "Pisya_bot" __title__ = "src"
__author__ = "baconborn" __author__ = "baconborn"
from typing import NamedTuple, Literal from typing import NamedTuple, Literal
class VersionInfo(NamedTuple): class VersionInfo(NamedTuple):
major: int major: int
minor: int minor: int
micro: int micro: int
releaselevel: Literal["alpha", "beta", "candidate", "final"] releaselevel: Literal["alpha", "beta", "candidate", "final"]
serial: int serial: int
version_info: VersionInfo = VersionInfo(major=0, minor=0, micro=8, releaselevel="alpha", serial=0) version_info: VersionInfo = VersionInfo(major=0, minor=0, micro=7, releaselevel="alpha", serial=0)

319
bot.py → src/bot.py Executable file → Normal file
View File

@@ -1,161 +1,158 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import asyncio from os import getenv
from os import getenv from os.path import isfile
from os.path import isfile
from disnake import OptionType, Option, Localized, ApplicationCommandInteraction, Intents, __version__
from disnake import OptionType, Option, Localized, ApplicationCommandInteraction, Intents, __version__ from disnake.ext.commands import Bot, is_owner
from disnake.ext.commands import Bot, is_owner from dotenv import load_dotenv
from dotenv import load_dotenv
from loguru import logger from integral_lib.CogsPrep import work_with_cogs, cog_list
from integral_lib.Comands import determine_prefix
from __init__ import __version__ as ver from integral_lib.Logger import logger
from lib.CogsPrep import work_with_cogs, cog_list
from lib.Comands import determine_prefix load_dotenv()
if not isfile('.env') or not getenv('CONF_FILE'):
load_dotenv() with open('.env', 'a', encoding='utf-8') as f:
if not isfile('.env') or not getenv('CONF_FILE'): f.write("CONF_FILE='config.json'\n")
with open('.env', 'a', encoding='utf-8') as f: load_dotenv()
f.write("CONF_FILE='config.json'\n") if not isfile(getenv('CONF_FILE')):
load_dotenv() with open(getenv('CONF_FILE'), 'a', encoding='utf-8') as f:
if not isfile(getenv('CONF_FILE')): f.write("")
with open(getenv('CONF_FILE'), 'a', encoding='utf-8') as f:
f.write("") intents = Intents(messages=True,
guilds=True,
intents = Intents(messages=True, message_content=True,
guilds=True, voice_states=True,
message_content=True, members=True,
voice_states=True, presences=True
members=True, )
presences=True
) bot = Bot(command_prefix=determine_prefix,
intents=intents,
bot = Bot(command_prefix=determine_prefix, reload=True,
intents=intents, test_guilds=[648126669122568215]
reload=True, )
test_guilds=[648126669122568215]
) bot.i18n.load("locale/")
bot.i18n.load("locale/") work_with_cogs('load', bot, cog_list())
asyncio.run(work_with_cogs('load', bot, asyncio.run(cog_list())))
@bot.event
async def on_ready():
@bot.event logger.info('Bot started')
async def on_ready(): logger.info(f'Disnake version {__version__}')
logger.info('Bot started') logger.info(f'We have logged in as {bot.user}')
logger.info(f'Disnake version {__version__}')
logger.info(f'We have logged in as {bot.user}')
logger.info(f'Version of bot is - v{ver}') @bot.slash_command(
name='cog',
options=[
@bot.slash_command( Option(
name='cog', name=Localized('cog', key="COG".lower()),
options=[ description=Localized("cog file", key="COG_FILE"),
Option( type=OptionType.string
name=Localized('cog', key="COG".lower()), )
description=Localized("cog file", key="COG_FILE"), ]
type=OptionType.string )
) @is_owner()
] async def slash_cogs(inter: ApplicationCommandInteraction):
) """
@is_owner() Working with cogs (modules) {{SLASH_COG}}
async def slash_cogs(inter: ApplicationCommandInteraction):
""" Parameters
Working with cogs (modules) {{SLASH_COG}} ----------
:param inter:
Parameters """
---------- pass
:param inter:
"""
pass @slash_cogs.sub_command(description=Localized("Enables Cog", key="ENABLE_COG"))
async def enable(inter: ApplicationCommandInteraction, cog: str):
"""
@slash_cogs.sub_command(description=Localized("Enables Cog", key="ENABLE_COG"))
async def enable(inter: ApplicationCommandInteraction, cog: str): Parameters
""" ----------
:param inter:
Parameters :param cog: Select Cogfile {{COG_FILE}}
---------- """
:param inter: await work_with_cogs('enable', bot, cog)
:param cog: Select Cogfile {{COG_FILE}} await inter.response.send_message(f'Cog {cog} is enabled', ephemeral=True)
"""
await work_with_cogs('enable', bot, cog)
await inter.response.send_message(f'Cog {cog} is enabled', ephemeral=True) @slash_cogs.sub_command(description=Localized("Disables Cog", key="DISABLE_COG"))
async def disable(inter: ApplicationCommandInteraction, cog: str):
"""
@slash_cogs.sub_command(description=Localized("Disables Cog", key="DISABLE_COG"))
async def disable(inter: ApplicationCommandInteraction, cog: str): Parameters
""" ----------
:param inter:
Parameters :param cog: Select Cogfile {{COG_FILE}}
---------- """
:param inter: await work_with_cogs('disable', bot, cog)
:param cog: Select Cogfile {{COG_FILE}} await inter.response.send_message(f'Cog {cog} is disabled', ephemeral=True)
"""
await work_with_cogs('disable', bot, cog)
await inter.response.send_message(f'Cog {cog} is disabled', ephemeral=True) @slash_cogs.sub_command(description=Localized("Loads Cog", key="LOAD_COG"))
async def load(inter: ApplicationCommandInteraction, cog: str):
"""
@slash_cogs.sub_command(description=Localized("Loads Cog", key="LOAD_COG"))
async def load(inter: ApplicationCommandInteraction, cog: str): Parameters
""" ----------
:param inter:
Parameters :param cog: Select Cogfile {{COG_FILE}}
---------- """
:param inter: await work_with_cogs('load', bot, cog)
:param cog: Select Cogfile {{COG_FILE}} await inter.response.send_message(f'Cog {cog} is loaded', ephemeral=True)
"""
await work_with_cogs('load', bot, cog)
await inter.response.send_message(f'Cog {cog} is loaded', ephemeral=True) @slash_cogs.sub_command(description=Localized("Unload Cog", key="UNLOAD_COG"))
async def unload(inter: ApplicationCommandInteraction, cog: str):
"""
@slash_cogs.sub_command(description=Localized("Unload Cog", key="UNLOAD_COG"))
async def unload(inter: ApplicationCommandInteraction, cog: str): Parameters
""" ----------
:param inter:
Parameters :param cog: Select Cogfile {{COG_FILE}}
---------- """
:param inter: await work_with_cogs('unload', bot, cog)
:param cog: Select Cogfile {{COG_FILE}} await inter.response.send_message(f'Cog {cog} is unload', ephemeral=True)
"""
await work_with_cogs('unload', bot, cog)
await inter.response.send_message(f'Cog {cog} is unload', ephemeral=True) @slash_cogs.sub_command(description=Localized("Reloads Cog", key="RELOAD_COG"))
async def reload(inter: ApplicationCommandInteraction, cog: str):
"""
@slash_cogs.sub_command(description=Localized("Reloads Cog", key="RELOAD_COG"))
async def reload(inter: ApplicationCommandInteraction, cog: str): Parameters
""" ----------
:param inter:
Parameters :param cog: Select Cogfile {{COG_FILE}}
---------- """
:param inter: await work_with_cogs('reload', bot, cog)
:param cog: Select Cogfile {{COG_FILE}} await inter.response.send_message(f'Cog {cog} is reloaded', ephemeral=True)
"""
await work_with_cogs('reload', bot, cog)
await inter.response.send_message(f'Cog {cog} is reloaded', ephemeral=True) @disable.autocomplete('cog')
@unload.autocomplete('cog')
@load.autocomplete('cog')
@disable.autocomplete('cog') @reload.autocomplete('cog')
@unload.autocomplete('cog') async def _cog_opt(inter: ApplicationCommandInteraction, current: str):
@load.autocomplete('cog') current = current.lower()
@reload.autocomplete('cog') _list = cog_list(fold='./cogs/')
async def _cog_opt(inter: ApplicationCommandInteraction, current: str): return [choice for choice in _list if current in choice.lower()]
current = current.lower()
_list = await cog_list(fold='./cogs/')
return [choice for choice in _list if current in choice.lower()] @enable.autocomplete('cog')
async def _cog_opt(inter: ApplicationCommandInteraction, current: str):
current = current.lower()
@enable.autocomplete('cog') _list = cog_list(fold='./cogs/disabled/')
async def _cog_opt(inter: ApplicationCommandInteraction, current: str): return [choice for choice in _list if current in choice.lower()]
current = current.lower()
_list = await cog_list(fold='./cogs/disabled/')
return [choice for choice in _list if current in choice.lower()] @slash_cogs.error
async def cogs_error(inter: ApplicationCommandInteraction):
await inter.response.send_message(Localized("Error", key="EROR"), ephemeral=True)
@slash_cogs.error logger.error(f'User {inter.author} tries to use cogs func')
async def cogs_error(inter: ApplicationCommandInteraction):
await inter.response.send_message(Localized("Error", key="EROR"), ephemeral=True)
logger.error(f'User {inter.author} tries to use cogs func') bot.run(getenv('TOKEN'))
bot.run(getenv('TOKEN'))

View File

@@ -1,151 +1,148 @@
from asyncio import sleep from asyncio import sleep
import disnake import disnake
from disnake import Option, OptionType, Localized from disnake import Option, OptionType, Localized
from disnake.ext import commands, tasks from disnake.ext import tasks
from loguru import logger
from integral_lib.Comands import *
from lib.Comands import read_json, write_json from integral_lib.DB_Worker import fill_bd, prepare_db, work_with_db
from lib.DB_Worker import fill_bd, prepare_db, work_with_db from integral_lib.Logger import logger
class Admin(commands.Cog, name='Admin'): class Admin(commands.Cog, name='Admin'):
def __init__(self, bot: commands.Bot): def __init__(self, bot: commands.Bot):
self.bot = bot # a defining bot as global var in class self.bot = bot # a defining src as global var in class
@commands.Cog.listener() # this is a decorator for events/listeners @commands.Cog.listener() # this is a decorator for events/listeners
async def on_ready(self): async def on_ready(self):
for g in self.bot.get_all_members(): for g in self.bot.get_all_members():
await prepare_db(g.guild.id) await prepare_db(g.guild.id)
for g in self.bot.get_all_members(): for g in self.bot.get_all_members():
await fill_bd(g.name, g.id, g.bot, g.nick, g.guild.id) await fill_bd(g.name, g.id, g.bot, g.nick, g.guild.id)
self.activity.start() self.activity.start()
logger.info(f'Cog {__name__.split(".")[1]} is ready!.') logger.info(f'Cog {__name__.split(".")[1]} is ready!.')
@tasks.loop(seconds=20) @tasks.loop(seconds=20)
async def activity(self): async def activity(self):
await self.bot.change_presence( await self.bot.change_presence(
activity=disnake.Activity( activity=disnake.Activity(
name=f'at users: {str(len(self.bot.users))}', name=f'at users: {str(len(self.bot.users))}',
type=3 type=3
) )
) )
await sleep(10) await sleep(10)
await self.bot.change_presence( await self.bot.change_presence(
activity=disnake.Activity( activity=disnake.Activity(
name=f'at servers: {str(len(self.bot.guilds))}', name=f'at servers: {str(len(self.bot.guilds))}',
type=3 type=3
) )
) )
@commands.Cog.listener() @commands.Cog.listener()
async def on_member_update(self, before: disnake.Member, after: disnake.Member): async def on_member_update(self, before: disnake.Member, after: disnake.Member):
sql_update_query = f"""UPDATE "{after.guild.id}" set nick = ? where userid = ?""" sql_update_query = f"""UPDATE "{after.guild.id}" set nick = ? where userid = ?"""
data_tuple = (after.nick, before.id) data_tuple = (after.nick, before.id)
await work_with_db(sql_update_query, data_tuple) await work_with_db(sql_update_query, data_tuple)
@commands.Cog.listener() @commands.Cog.listener()
async def on_guild_join(self, guild): async def on_guild_join(self, guild):
for g in guild.members: for g in guild.members:
await fill_bd(g.name, g.id, g.bot, g.nick, guild.id) await fill_bd(g.name, g.id, g.bot, g.nick, guild.id)
@commands.Cog.listener() @commands.Cog.listener()
async def on_member_join(self, member): async def on_member_join(self, member):
await fill_bd(member.name, member.id, member.bot, member.nick, member.guild.id) await fill_bd(member.name, member.id, member.bot, member.nick, member.guild.id)
bot_role = read_json(member.guild.id, 'bot_role') # Get bot role bot_role = read_json(member.guild.id, 'bot_role') # Get src role
guest_role = read_json(member.guild.id, 'guest_role') # Get guest role guest_role = read_json(member.guild.id, 'guest_role') # Get guest role
logger.info(f"Bot role: {bot_role} | Guest role: {guest_role}") if bot_role or guest_role:
logger.info(f'type bot_role: {type(bot_role)} | type guest_role: {type(guest_role)}') if member.bot == 0:
if bot_role or guest_role: role = disnake.utils.get(member.guild.roles, id=guest_role)
if member.bot == 0: else:
role = disnake.utils.get(member.guild.roles, id=guest_role) role = disnake.utils.get(member.guild.roles, id=bot_role)
else: logger.info(f"Adding to {member} role {role}")
role = disnake.utils.get(member.guild.roles, id=bot_role) await member.add_roles(role)
logger.info(f"Adding to {member} role {role}")
await member.add_roles(role) @commands.slash_command(
name="set_default_role",
@commands.slash_command( description=Localized("Set Default src role", key="DEF_ROLE"),
name="set_default_role", options=[
description=Localized("Set Default bot role", key="DEF_ROLE"), Option("role",
options=[ "Specify role",
Option("role", OptionType.role,
"Specify role", required=True),
OptionType.role, ]
required=True), )
] @commands.has_permissions(administrator=True)
) async def set_guest_role(self, inter: disnake.ApplicationCommandInteraction, role):
@commands.has_permissions(administrator=True) await write_json(inter.guild.id, "guest_role", role.id)
async def set_guest_role(self, inter: disnake.ApplicationCommandInteraction, role): await inter.response.send_message(f"Set up src role to: `{role.name}`", ephemeral=True)
print(type(role.id))
await write_json(inter.guild.id, "guest_role", role.id) @commands.command(name="set_prefix")
await inter.response.send_message(f"Set up bot role to: `{role.name}`", ephemeral=True) @commands.has_permissions(administrator=True)
async def command_set_prefix(self, ctx, prefix: str):
@commands.command(name="set_prefix") await write_json(ctx.guild.id, "prefix", prefix)
@commands.has_permissions(administrator=True) await ctx.reply(f"Prefix set to: `{prefix}`")
async def command_set_prefix(self, ctx, prefix: str):
await write_json(ctx.guild.id, "prefix", prefix) @commands.guild_only()
await ctx.reply(f"Prefix set to: `{prefix}`") @commands.slash_command(
name="set_prefix",
@commands.guild_only() description="Setting up src prefix",
@commands.slash_command( options=[
name="set_prefix", Option("prefix",
description="Setting up bot prefix", "Specify prefix",
options=[ OptionType.string,
Option("prefix", required=True),
"Specify prefix", ]
OptionType.string, )
required=True), @commands.has_permissions(administrator=True)
] async def slash_set_prefix(self, inter: disnake.ApplicationCommandInteraction, prefix: str):
) await write_json(inter.guild.id, "prefix", prefix)
@commands.has_permissions(administrator=True) await inter.response.send_message(f"Prefix set to: `{prefix}`", ephemeral=True)
async def slash_set_prefix(self, inter: disnake.ApplicationCommandInteraction, prefix: str):
await write_json(inter.guild.id, "prefix", prefix) @commands.guild_only()
await inter.response.send_message(f"Prefix set to: `{prefix}`", ephemeral=True) @commands.has_permissions(administrator=True)
@commands.slash_command(
@commands.guild_only() name="set_trigger_role",
@commands.has_permissions(administrator=True) description=Localized("Setting up role to trigger src", key="KEY_ROLE"),
@commands.slash_command( options=[
name="set_trigger_role", Option("role",
description=Localized("Setting up role to trigger bot", key="KEY_ROLE"), Localized("Specify role", key="SETUP_ROLE"),
options=[ OptionType.role,
Option("role", required=True),
Localized("Specify role", key="SETUP_ROLE"), ]
OptionType.role, )
required=True), async def set_trigger_role(self, inter: disnake.ApplicationCommandInteraction, role):
] await write_json(inter.guild.id, "tigger_role", role.id)
) await inter.response.send_message(f"Role set to: `{role.name}`", ephemeral=True)
async def set_trigger_role(self, inter: disnake.ApplicationCommandInteraction, role):
await write_json(inter.guild.id, "tigger_role", role.id) @commands.slash_command(
await inter.response.send_message(f"Role set to: `{role.name}`", ephemeral=True) name="set_bot_role",
description=Localized("Set src role", key="BOT_ROLE"),
@commands.slash_command( options=[
name="set_bot_role", Option("role",
description=Localized("Set bot role", key="BOT_ROLE"), Localized("Specify role", key="SETUP_ROLE"),
options=[ OptionType.role,
Option("role", required=True)
Localized("Specify role", key="SETUP_ROLE"), ]
OptionType.role, )
required=True) @commands.guild_only()
] @commands.has_permissions(administrator=True)
) async def set_bot_role(self, ctx, role):
@commands.guild_only() await write_json(ctx.guild.id,
@commands.has_permissions(administrator=True) "bot_role",
async def set_bot_role(self, ctx, role): role.id)
await write_json(ctx.guild.id, await ctx.send(f"Set up src role to: `{role.name}`", ephemeral=True)
"bot_role",
role.id) @set_bot_role.error
await ctx.send(f"Set up bot role to: `{role.name}`", ephemeral=True) @set_trigger_role.error
@slash_set_prefix.error
@set_bot_role.error async def set_prefix_error(self, inter: disnake.ApplicationCommandInteraction, prefix):
@set_trigger_role.error await inter.response.send_message("You don`t have permissions", ephemeral=True)
@slash_set_prefix.error logger.error(prefix)
async def set_prefix_error(self, inter: disnake.ApplicationCommandInteraction, prefix):
await inter.response.send_message("You don`t have permissions", ephemeral=True)
logger.error(prefix) def setup(bot): # an extension must have a setup function
bot.add_cog(Admin(bot)) # adding a cog
def setup(bot): # an extension must have a setup function
bot.add_cog(Admin(bot)) # adding a cog

View File

@@ -1,96 +1,84 @@
import random import random
import disnake import disnake
from disnake import OptionChoice, Option, OptionType, Member, VoiceState from disnake import OptionChoice, Option, OptionType, Member, VoiceState, ApplicationCommandInteraction
from disnake.ext import commands from disnake.ext import commands
from disnake.utils import get
from loguru import logger from integral_lib.ListGenerator import ListGenerator
from integral_lib.Logger import logger
from lib.ListGenerator import ListGenerator from integral_lib.Player import play_audio
from lib.Player import play_audio
class Audio(commands.Cog, name='Audio'):
class Audio(commands.Cog, name='Audio'): def __init__(self, bot: commands.Bot):
def __init__(self, bot: commands.Bot): self.bot = bot
self.bot = bot
@commands.Cog.listener()
@commands.Cog.listener() async def on_ready(self):
async def on_ready(self): logger.info(f'Cog {__name__.split(".")[1]} is ready!.')
logger.info(f'Cog {__name__.split(".")[1]} is ready!.')
@commands.Cog.listener()
@commands.Cog.listener() async def on_voice_state_update(self, member: Member,
async def on_voice_state_update(self, member: Member, before: VoiceState,
before: VoiceState, after: VoiceState):
after: VoiceState): if before.channel is None and not member.bot:
if before.channel is None and not member.bot: logger.info(f'Coneccted {member.name} to {after.channel.name}')
logger.info(f'Coneccted {member.name} to {after.channel.name}') if any('Escape from Tarkov' in str(user.activity) for user in after.channel.members):
if any('Escape from Tarkov' in str(user.activity) for user in after.channel.members): logger.info('Skip playing by Game')
logger.info('Skip playing by Game') else:
else: # Prepare list of audio
# Prepare list of audio from integral_lib.Comands import read_json
from lib.Comands import read_json _role = await read_json(member.guild.id, 'tigger_role')
_role = get(member.guild.roles, id=read_json(member.guild.id, 'tigger_role')) audio: list = []
audio: list = [] for _a in ListGenerator('audio'):
for _a in ListGenerator('audio'): audio.append(_a.name)
audio.append(_a.name)
if len(member.roles) == 1 or _role is None:
if len(member.roles) == 1 or _role is None: logger.info('Skip playing by role')
logger.info('Skip playing by role') elif any(str(role.id) in _role for role in member.roles):
elif _role in member.roles: logger.info('Play audio from list by role')
logger.info('Play audio from list by role') await play_audio(f'audio/{random.choice(audio)}', self.bot, after.channel)
await play_audio(f'audio/{random.choice(audio)}', self.bot, after.channel) else:
else: logger.info('Skip playing by any else')
logger.info('Skip playing by any else')
@commands.slash_command(name="play_audio",
@commands.slash_command(name="play_audio", description="Make possible playing audio by command",
description="Make possible playing audio by command", options=[
options=[ Option(name="audio",
Option(name="audio", type=OptionType.string,
type=OptionType.string, required=True
required=True )
) ])
]) async def playaudio(self, inter: disnake.ApplicationCommandInteraction,
async def playaudio(self, inter: disnake.ApplicationCommandInteraction, audio: str
audio: str ):
): if inter.author.voice is not None:
if inter.author.voice is not None: await inter.response.send_message(f'Played {audio}', ephemeral=True)
await inter.response.send_message(f'Played {audio}', ephemeral=True) await play_audio(audio, self.bot, inter.author.voice.channel)
else:
await play_audio(audio, self.bot, inter.author.voice.channel) await inter.response.send_message('You`re not in voice', ephemeral=True)
else:
await inter.response.send_message('You`re not in voice', ephemeral=True) @playaudio.autocomplete('audio')
async def list_to_play(self, inter: ApplicationCommandInteraction, current: str):
@commands.slash_command(name="play_random", """
description="Make possible playing audio by command", Asynchronously generates a list of OptionChoices for the given audio files based on the user input.
options=[ Parameters:
Option(name="num", - inter: disnake.ApplicationCommandInteraction - The interaction context for the command.
type=OptionType.integer, - current: str - The current user input to filter the audio file choices.
) Returns:
]) - list[OptionChoice] - A list of OptionChoice objects representing the available audio file choices.
async def playrandom(self, inter: disnake.ApplicationCommandInteraction, :param current:
num: int :param inter: ApplicationCommandInteraction
): """
if inter.author.voice is not None: current = current.lower()
audio: list = [] _dict: dict = {}
for _a in ListGenerator('audio'): for f in ListGenerator('audio'):
audio.append(_a.name) _dict[f.name] = f'{f.path}/{f.name}'
for i in range(num): return [
logger.info(f'Played {i+1} times') OptionChoice(name=choice, value=f'{_dict[choice]}')
await play_audio(f'audio/{random.choice(audio)}', self.bot, inter.author.voice.channel) for choice in _dict if current in choice.lower()
else: ]
await inter.response.send_message('You`re not in voice', ephemeral=True)
@playaudio.autocomplete('audio') def setup(bot): # an extension must have a setup function
async def list_to_play(self, inter: disnake.ApplicationCommandInteraction, current: str): bot.add_cog(Audio(bot)) # adding a cog
current = current.lower()
_dict: dict = {}
for f in ListGenerator('audio'):
_dict[f.name] = f'{f.path}/{f.name}'
return [
OptionChoice(name=choice, value=f'{_dict[choice]}')
for choice in _dict if current in choice.lower()
]
def setup(bot): # an extension must have a setup function
bot.add_cog(Audio(bot)) # adding a cog

View File

@@ -1,43 +1,43 @@
from typing import List from typing import List
import disnake import disnake
from disnake import OptionChoice from disnake import OptionChoice
from disnake.ext import commands from disnake.ext import commands
from loguru import logger
from integral_lib.Comands import write_json
from lib.Comands import write_json from integral_lib.Logger import logger
class Fun(commands.Cog, name='Fun'): class Fun(commands.Cog, name='Fun'):
def __init__(self, bot: commands.Bot): def __init__(self, bot: commands.Bot):
self.bot = bot # defining bot as global var in class self.bot = bot # defining src as global var in class
@commands.Cog.listener() # this is a decorator for events/listeners @commands.Cog.listener() # this is a decorator for events/listeners
async def on_ready(self): async def on_ready(self):
logger.info(f'Cog {__name__.split(".")[1]} is ready!.') logger.info(f'Cog {__name__.split(".")[1]} is ready!.')
@commands.has_permissions(administrator=True) @commands.has_permissions(administrator=True)
@commands.slash_command( @commands.slash_command(
name="set_bot_channel", name="set_bot_channel",
description="Set channel which iterate with bot", description="Set channel which iterate with src",
) )
async def set_bot_channel(self, inter: disnake.ApplicationCommandInteraction, channel: str): async def set_bot_channel(self, inter: disnake.ApplicationCommandInteraction, channel: str):
await write_json(inter.guild.id, await write_json(inter.guild.id,
"channel", "channel",
disnake.utils.find(lambda d: d.name == channel, inter.guild.channels).id) disnake.utils.find(lambda d: d.name == channel, inter.guild.channels).id)
await inter.response.send_message(f"Channel set up to {channel}", ephemeral=True) await inter.response.send_message(f"Channel set up to {channel}", ephemeral=True)
@set_bot_channel.autocomplete('channel') @set_bot_channel.autocomplete('channel')
async def _list_text_channels(self, async def _list_text_channels(self,
inter: disnake.ApplicationCommandInteraction, inter: disnake.ApplicationCommandInteraction,
current: str) -> List[OptionChoice]: current: str) -> List[OptionChoice]:
_list = [r.name for r in inter.guild.text_channels] _list = [r.name for r in inter.guild.text_channels]
return [ return [
OptionChoice(name=choice, value=choice) OptionChoice(name=choice, value=choice)
for choice in _list if current in choice for choice in _list if current in choice
] ]
def setup(bot): # an extension must have a setup function def setup(bot): # an extension must have a setup function
bot.add_cog(Fun(bot)) # adding a cog bot.add_cog(Fun(bot)) # adding a cog

View File

@@ -1,29 +1,29 @@
import disnake import disnake
from disnake import Option from disnake import Option
from disnake.ext import commands from disnake.ext import commands
from loguru import logger
from integral_lib import YandexPlayer
from lib import YandexPlayer from integral_lib.Logger import logger
class Testing(commands.Cog, name='Testing'): class Testing(commands.Cog, name='Testing'):
def __init__(self, bot: commands.Bot): def __init__(self, bot: commands.Bot):
self.bot = bot # defining bot as global var in class self.bot = bot # defining src as global var in class
@commands.Cog.listener() # this is a decorator for events/listeners @commands.Cog.listener() # this is a decorator for events/listeners
async def on_ready(self): async def on_ready(self):
logger.info(f'Cog {__name__.split(".")[1]} is ready!.') logger.info(f'Cog {__name__.split(".")[1]} is ready!.')
@commands.slash_command(name='play', description='play audio test from yandex.music', options=[ @commands.slash_command(name='play', description='play audio test from yandex.music', options=[
Option(name='search', Option(name='search',
description='seach track/artist', description='seach track/artist',
required=True), required=True),
]) ])
async def play(self, inter: disnake.ApplicationCommandInteraction, search: str): async def play(self, inter: disnake.ApplicationCommandInteraction, search: str):
# TODO add yandex_music player with queue, playlists # TODO add yandex_music player with queue, playlists
result = YandexPlayer.search(search) result = YandexPlayer.search(search)
await inter.response.send_message(result, ephemeral=True) await inter.response.send_message(result, ephemeral=True)
def setup(bot): # an extension must have a setup function def setup(bot): # an extension must have a setup function
bot.add_cog(Testing(bot)) # adding a cog bot.add_cog(Testing(bot)) # adding a cog

View File

@@ -1,60 +1,59 @@
import disnake import disnake
from disnake import Option, OptionType, Colour from disnake import Option, OptionType, Colour
from disnake.ext import commands from disnake.ext import commands
# from lib.Logger import logger from integral_lib.Logger import logger
from loguru import logger
class General(commands.Cog):
class General(commands.Cog): def __init__(self, bot: commands.Bot):
def __init__(self, bot: commands.Bot): self.bot = bot # defining src as global var in class
self.bot = bot # defining bot as global var in class
@commands.Cog.listener() # this is a decorator for events/listeners
@commands.Cog.listener() # this is a decorator for events/listeners async def on_ready(self):
async def on_ready(self): logger.info(f'Cog {__name__.split(".")[1]} is ready!.')
logger.info(f'Cog {__name__.split(".")[1]} is ready!.')
@commands.slash_command(
@commands.slash_command( name="info",
name="info", options=[
options=[ Option("user",
Option("user", "Specify any user",
"Specify any user", OptionType.user),
OptionType.user), ]
] )
) async def info(self, inter: disnake.ApplicationCommandInteraction, user=None):
async def info(self, inter: disnake.ApplicationCommandInteraction, user=None): """
""" Shows user info {{SLASH_INFO}}
Shows user info {{SLASH_INFO}}
Parameters
Parameters ----------
---------- :param inter:
:param inter: :param user:
:param user: :return:
:return: """
""" user = user or inter.author
user = user or inter.author
rolelist = [r.mention for r in user.roles if r != inter.guild.default_role]
rolelist = [r.mention for r in user.roles if r != inter.guild.default_role] if rolelist:
if rolelist: roles = "\n".join(rolelist)
roles = "\n".join(rolelist) else:
else: roles = "Not added any role"
roles = "Not added any role"
emb = disnake.Embed(
emb = disnake.Embed( title="General information",
title="General information", description=f"General information on server about {user}",
description=f"General information on server about {user}", color=Colour.random()
color=Colour.random() )
) emb.set_thumbnail(url=user.display_avatar)
emb.set_thumbnail(url=user.display_avatar) emb.add_field(name="General info",
emb.add_field(name="General info", value=f"Username: {user}\n"
value=f"Username: {user}\n" f"Nickname: {user.nick}\n"
f"Nickname: {user.nick}\n" f"Joined at: {user.joined_at.strftime('%A, %B %d %Y @ %H:%M:%S')}", inline=False)
f"Joined at: {user.joined_at.strftime('%A, %B %d %Y @ %H:%M:%S')}", inline=False) emb.add_field(name="Roles list", value=f"{roles}")
emb.add_field(name="Roles list", value=f"{roles}") emb.set_footer(text=f"Information requested by: {inter.author.display_name}")
emb.set_footer(text=f"Information requested by: {inter.author.display_name}")
await inter.response.send_message(embed=emb, ephemeral=True)
await inter.response.send_message(embed=emb, ephemeral=True)
def setup(bot): # an extension must have a setup function
def setup(bot): # an extension must have a setup function bot.add_cog(General(bot)) # adding a cog
bot.add_cog(General(bot)) # adding a cog

View File

@@ -1,45 +1,44 @@
import os import os
import disnake import disnake
import psutil import psutil
from disnake.ext import commands from disnake import ApplicationCommandInteraction
from loguru import logger from disnake.ext import commands
from __init__ import version_info as ver from __init__ import version_info as ver
from lib.Comands import determine_prefix from integral_lib.Comands import determine_prefix
from integral_lib.Logger import logger
# from lib.Logger import logger
class BotInfo(commands.Cog, name='Bot Info'):
class BotInfo(commands.Cog, name='Bot Info'): def __init__(self, bot: commands.Bot):
def __init__(self, bot: commands.Bot): self.bot = bot # defining src as global var in class
self.bot = bot # defining bot as global var in class
@commands.Cog.listener() # this is a decorator for events/listeners
@commands.Cog.listener() # this is a decorator for events/listeners async def on_ready(self):
async def on_ready(self): logger.info(f'Cog {__name__.split(".")[1]} is ready!.')
logger.info(f'Cog {__name__.split(".")[1]} is ready!.')
@commands.slash_command(name="info_bot",
@commands.slash_command(name="info_bot", description='Shows general info about src') # this is for making a command
description='Shows general info about bot') # this is for making a command async def info_bot(self, inter: ApplicationCommandInteraction):
async def info_bot(self, inter: disnake.ApplicationCommandInteraction): _pid = os.getpid()
_pid = os.getpid() _process = psutil.Process(_pid)
_process = psutil.Process(_pid) emb = disnake.Embed(
emb = disnake.Embed( title="General information",
title="General information", description="General information on about src",
description="General information on about bot", )
) emb.set_thumbnail(self.bot.user.avatar.url)
emb.set_thumbnail(self.bot.user.avatar.url) emb.add_field(name="System info:", value=f"Memory Usage: {round(_process.memory_info().rss / 2 ** 20, 2)} Mb\n"
emb.add_field(name="System info:", value=f"Memory Usage: {round(_process.memory_info().rss / 2 ** 20, 2)} Mb\n" f"CPU Usage: {_process.cpu_percent()}%\n"
f"CPU Usage: {_process.cpu_percent()}%\n" f'Bot ping: {round(self.bot.latency * 1000)}\n'
f'Bot ping: {round(self.bot.latency * 1000)}\n' f'Prefix: `{determine_prefix(self.bot, inter)}\n`'
f'Prefix: `{determine_prefix(self.bot, inter)}\n`' )
) emb.add_field(name="Bot info:", value="Bot owner: <@386629192743256065>\n"
emb.add_field(name="Bot info:", value="Bot owner: <@386629192743256065>\n" f"Bot version: {ver.major}.{ver.minor}.{ver.micro}-{ver.releaselevel}")
f"Bot version: {ver.major}.{ver.minor}.{ver.micro}-{ver.releaselevel}") emb.set_footer(text=f"Information requested by: {inter.author.display_name}")
emb.set_footer(text=f"Information requested by: {inter.author.display_name}")
await inter.response.send_message(embed=emb, ephemeral=True)
await inter.response.send_message(embed=emb, ephemeral=True)
def setup(bot): # an extension must have a setup function
def setup(bot): # an extension must have a setup function bot.add_cog(BotInfo(bot)) # adding a cog
bot.add_cog(BotInfo(bot)) # adding a cog

View File

@@ -0,0 +1,78 @@
"""
integral_lib.CogsPrepare
~~~~~~~~~~~~~
Loads, unloads Cogs files
cog_list: return list of cog filenames
work_with_cogs: loads, reloads and unloads cogs files
"""
from os import listdir, rename
from typing import List
from disnake.ext.commands.interaction_bot_base import InteractionBotBase
from .Logger import logger
def cog_list(fold: str = './cogs') -> List[str]:
"""
A function that generates a list of cog names based on the files present in a specified folder.
Parameters:
- fold (str): The directory path where the cog files are located. Defaults to './cogs'.
Returns:
- List[str]: A list of cog names without the '.py' extension.
"""
cogs_list = []
for _filename in listdir(fold):
if _filename.endswith('.py'):
cogs_list.append(_filename[:-3])
return cogs_list
def work_with_cogs(what_do: str,
bot: InteractionBotBase,
cog: str | list):
"""
Perform the specified action on the given cog or list of cogs.
Args:
what_do (str): The action to perform (load, unload, reload, disable, enable).
src (InteractionBotBase): The src instance to work with.
cog (str | list): The name of the cog or a list of cogs to work with.
Raises:
ValueError: If the action is not recognized.
Returns:
None
--------
:param cog: str | list
:param bot: InteractionBotBase
:param what_do: str = ['load', 'unload', 'reload', 'disable', 'enable']
"""
if isinstance(cog, str):
cog = cog.split()
for _filename in cog:
if _filename.endswith('.py'):
_filename = _filename.split('.')[0]
if what_do == "load":
bot.load_extension(f'cogs.{_filename}')
logger.info(f'Cog {_filename} loaded')
elif what_do == 'unload':
bot.unload_extension(f'cogs.{_filename}')
logger.info(f'Cog {_filename} unloaded')
elif what_do == 'reload':
bot.reload_extension(f'cogs.{_filename}')
logger.info(f'Cog {_filename} reloaded')
elif what_do == 'disable':
bot.unload_extension(f'cogs.{_filename}')
rename(f'cogs/{_filename}.py',
f'cogs/disabled/{_filename}.py')
logger.info(f'Cog {_filename} stopped and disabled')
elif what_do == 'enable':
rename(f'cogs/disabled/{_filename}.py',
f'cogs/{_filename}.py')
bot.load_extension(f'cogs.{_filename}')
logger.info(f'Cog {_filename} started and enabled')
else:
raise ValueError(f"Unrecognized action: {what_do}")

View File

@@ -1,73 +1,86 @@
""" """
lib.Commands integral_lib.Commands
~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~
Some prepare for commands Some prepare for commands
"""
from json import load, decoder, dump, JSONDecodeError
from os import getenv """
from json import load, decoder, dump, JSONDecodeError
from disnake.ext import commands from os import getenv
from disnake.ext import commands
def read_json(guild: int, _param: str):
"""
Reads Json file to determite config strings async def read_json(guild: int, _param: str):
:param guild: ID of Guild """
:param _param: Parameter in json file Reads Json file to determite config strings
:return: value of parameter. :param guild: ID of Guild
""" :param _param: Parameter in json file
parameter = None :return: value of parameter.
with open(getenv('CONF_FILE'), encoding='utf-8') as f: # Open the JSON """
try: parameter = None
_json = load(f) # Load the custom prefixes with open(getenv('CONF_FILE'), encoding='utf-8') as f: # Open the JSON
except decoder.JSONDecodeError: try:
_json = {} _json = load(f) # Load the custom prefixes
if guild: # If the guild exists except decoder.JSONDecodeError:
try: _json = {}
guild_conf = _json[f"{guild}"] if guild: # If the guild exists
try: try:
parameter = guild_conf[f"{_param}"] guild_conf = _json[f"{guild}"]
except KeyError: try:
pass parameter = guild_conf[f"{_param}"]
except KeyError: except KeyError:
pass pass
return parameter except KeyError:
pass
return parameter
async def write_json(guild: int, param_name: str, param: str or int):
print(type(param))
with open(getenv('CONF_FILE'), encoding='utf-8') as f: async def write_json(guild: int, param_name: str, param: str or int):
try: """
_json = load(f) A function to write JSON data to a file after updating or adding a parameter value.
except decoder.JSONDecodeError:
_json = {} Parameters:
try:
_guild = _json[f'{guild}'] - guild: an integer representing the guild ID
except KeyError: - param_name: a string representing the parameter name
_json.update({f'{guild}': {}}) - param: a string or integer representing the parameter value
_guild = _json[f'{guild}']
_guild.update({f'{param_name}': param}) Returns:
_json.update({f'{guild}': _guild}) This function does not return anything.
with open(getenv('CONF_FILE'), 'w', encoding='utf-8') as f: """
dump(_json, f, indent=4) with open(getenv('CONF_FILE'), encoding='utf-8') as f:
try:
_json = load(f)
def determine_prefix(bot: commands.Bot, msg): except decoder.JSONDecodeError:
""" _json = {}
Determite per-server bot prefix try:
:param bot: Disnake Bot object _guild = _json[f'{guild}']
:param msg: Disnake msg object except KeyError:
:return: prefix for server, default is $ _json.update({f'{guild}': {}})
""" _guild = _json[f'{guild}']
parameter = '$' _guild.update({f'{param_name}': f'{param}'})
with open(getenv('CONF_FILE'), encoding='utf-8') as f: # Open the JSON with open(getenv('CONF_FILE'), 'w', encoding='utf-8') as f:
try: dump(_json, f, indent=4)
_json = load(f) # Load the custom prefixes
except JSONDecodeError:
_json = {} def determine_prefix(bot: commands.Bot, msg):
try: """
parameter = _json[f"{msg.guild.id}"]["prefix"] # Read prefix from json if is setted up Determine the per-server src prefix based on the given message object.
except KeyError: :param bot: Disnake Bot object
pass :param msg: Disnake msg object
return parameter :return: prefix for server, default is $
"""
parameter = '$'
with open(getenv('CONF_FILE'), encoding='utf-8') as f: # Open the JSON
try:
_json = load(f) # Load the custom prefixes
except JSONDecodeError:
_json = {}
try:
parameter = _json[f"{msg.guild.id}"]["prefix"] # Read prefix from json if is setted up
except KeyError:
pass
return parameter

View File

@@ -1,136 +1,134 @@
from sqlite3 import connect, Error from sqlite3 import connect, Error
# from lib.Logger import logger from .Logger import logger
from loguru import logger
class DBReader:
class DBReader:
def __init__(self, guildid: int = None):
def __init__(self, guildid: int = None): self._guildid = guildid
self._guildid = guildid self.list = self._read_db(self._guildid)
self.list = self._read_db(self._guildid) self._current_index = 0
self._current_index = 0
def __str__(self) -> str:
def __str__(self) -> str: return str(self._guildid)
return str(self._guildid)
@classmethod
@classmethod def _read_db(cls, guildid: int) -> list:
def _read_db(cls, guildid: int) -> list: try:
try: sql_con = connect("user.db")
sql_con = connect("user.db") cursor = sql_con.cursor()
cursor = sql_con.cursor() cursor.execute(f"""SELECT * FROM "{guildid}" """)
cursor.execute("""SELECT * FROM "(guildid)" """, record = cursor.fetchall()
{'guildid': guildid}) return record
record = cursor.fetchall() except Error as _e:
return record logger.info(f'Error reading DB\n{_e}')
except Error as _e:
logger.info(f'Error reading DB\n{_e}') def __iter__(self):
return _ListGenerationIter(self)
def __iter__(self):
return _ListGenerationIter(self)
class _DBAttrs:
def __init__(self,
class _DBAttrs: userid: int,
def __init__(self, username: str,
userid: int, nick: str,
username: str, isbot: bool,
nick: str, defaulttracks: None or list,
isbot: bool, usertracks: None or list):
defaulttracks: None or list, self.userid = userid
usertracks: None or list): self.username = username
self.userid = userid self.nick = nick
self.username = username self.isbot = isbot
self.nick = nick self.defaulttracks = defaulttracks
self.isbot = isbot self.usertracks = usertracks
self.defaulttracks = defaulttracks
self.usertracks = usertracks def __str__(self):
return self.username
def __str__(self):
return self.username def __repr__(self):
return f'<File attrs userid={self.userid} username={self.username} nick={self.nick} ' \
def __repr__(self): f'isbot={self.isbot} defaulttracks={self.defaulttracks} usertracks={self.usertracks}>'
return f'<File attrs userid={self.userid} username={self.username} nick={self.nick} ' \
f'isbot={self.isbot} defaulttracks={self.defaulttracks} usertracks={self.usertracks}>'
class _ListGenerationIter:
def __init__(self, user_class):
class _ListGenerationIter: self._current_index = 0
def __init__(self, user_class): self._list = user_class.list
self._current_index = 0
self._list = user_class.list self._size = len(self._list)
self._size = len(self._list) def __iter__(self):
return self
def __iter__(self):
return self def __next__(self):
if self._current_index < self._size:
def __next__(self): _userid = self._list[self._current_index][0]
if self._current_index < self._size: _username = self._list[self._current_index][1]
_userid = self._list[self._current_index][0] _nick = self._list[self._current_index][2]
_username = self._list[self._current_index][1] _isbot = bool(self._list[self._current_index][3])
_nick = self._list[self._current_index][2] _defaulttracks = self._list[self._current_index][4]
_isbot = bool(self._list[self._current_index][3]) _usertracks = self._list[self._current_index][5]
_defaulttracks = self._list[self._current_index][4]
_usertracks = self._list[self._current_index][5] self._current_index += 1
memb = _DBAttrs(_userid,
self._current_index += 1 _username,
memb = _DBAttrs(_userid, _nick,
_username, _isbot,
_nick, _defaulttracks,
_isbot, _usertracks)
_defaulttracks, return memb
_usertracks) raise StopIteration
return memb
raise StopIteration
async def prepare_db(guild: int):
try:
async def prepare_db(guild: int): _connect = connect('user.db')
try: cursor = _connect.cursor()
_connect = connect('user.db') cursor.execute(f'CREATE TABLE IF NOT EXISTS "{guild}"\n'
cursor = _connect.cursor() f' ([userid] INTEGER PRIMARY KEY, [username] TEXT,\n'
cursor.execute(f'''CREATE TABLE IF NOT EXISTS "{guild}" f' [nick] TEXT, [isbot] BOOL, [defaulttracks] TEXT, [usertracks] TEXT)')
([userid] INTEGER PRIMARY KEY, [username] TEXT, cursor.close()
[nick] TEXT, [isbot] BOOL, [defaulttracks] TEXT, [usertracks] TEXT)''') except Error as _error:
cursor.close() logger.info(_error)
except Error as _error:
logger.info(_error)
async def work_with_db(db_func: str, data_turple: tuple):
"""
async def work_with_db(db_func: str, data_turple: tuple): Writing to db per server userinfo
""" :param db_func:
Writing to db per server userinfo :param data_turple:
:param db_func: """
:param data_turple: try:
""" _connect = connect('user.db')
try: cursor = _connect.cursor()
_connect = connect('user.db') cursor.execute(db_func, data_turple)
cursor = _connect.cursor() _connect.commit()
cursor.execute(db_func, data_turple) cursor.close()
_connect.commit() except Error as _error:
cursor.close() logger.critical(_error)
except Error as _error:
logger.critical(_error)
async def fill_bd(name: str, userid: int, isbot: bool, nick: str, guild: int):
sqlite_insert_with_param = (f"""INSERT OR IGNORE INTO '{guild}'
async def fill_bd(name: str, userid: int, isbot: bool, nick: str, guild: int): (username, userid, nick, isbot)
sqlite_insert_with_param = (f"""INSERT OR IGNORE INTO "{guild}" VALUES (?, ?, ?, ?)""")
(username, userid, nick, isbot) data_tuple: tuple[str, int, str, bool] = (name, userid, nick, isbot)
VALUES (?, ?, ?, ?)""") await work_with_db(sqlite_insert_with_param, data_tuple)
data_tuple: tuple[str, int, str, bool] = (name, userid, nick, isbot)
await work_with_db(sqlite_insert_with_param, data_tuple)
async def read_db(guild: int, user: int, column: str):
_col_dict = {'userid': 0,
async def read_db(guild: int, user: int, column: str): 'username': 1,
_col_dict = {'userid': 0, 'nick': 2,
'username': 1, 'isbot': 3,
'nick': 2, 'defaulttracks': 4,
'isbot': 3, 'usertracks': 5}
'defaulttracks': 4, try:
'usertracks': 5} sql_con = connect("user.db")
try: cursor = sql_con.cursor()
sql_con = connect("user.db") cursor.execute(f"""SELECT * FROM "{guild}" where userid = {user}""")
cursor = sql_con.cursor() record = cursor.fetchone()
cursor.execute(f"""SELECT * FROM "{guild}" where userid = {user}""") return record[_col_dict[column]]
record = cursor.fetchone() except Error as _error:
return record[_col_dict[column]] logger.critical(_error)
except Error as _error:
logger.critical(_error)

View File

@@ -1,86 +1,86 @@
from mimetypes import guess_type from mimetypes import guess_type
from os import walk from os import walk
class ListGenerator: class ListGenerator:
def __init__(self, path: str = None): def __init__(self, path: str = None):
self.path = path self.path = path
self.list: list = self._lister(self.path) self.list: list = self._lister(self.path)
try: try:
self._size = len(self.list) self._size = len(self.list)
except TypeError: except TypeError:
pass pass
self._current_index = 0 self._current_index = 0
def __str__(self) -> str: def __str__(self) -> str:
return 'Audio iter generator' return 'Audio iter generator'
@classmethod @classmethod
def _lister(cls, path) -> list: def _lister(cls, path) -> list:
_list: list = [] _list: list = []
try: try:
for f in walk(path): for f in walk(path):
_list.extend(f) _list.extend(f)
break break
return sorted(_list[2]) return sorted(_list[2])
except TypeError: except TypeError:
pass pass
def __iter__(self): def __iter__(self):
return _ListGenerationIter(self) return _ListGenerationIter(self)
def __next__(self): def __next__(self):
if self._current_index < self._size: if self._current_index < self._size:
self._current_index += 1 self._current_index += 1
class _FileAttrs: class _FileAttrs:
def __init__(self, name, path, mimetype, exc): def __init__(self, name, path, mimetype, exc):
self.name = name self.name = name
self.path = path self.path = path
self.mimetype = mimetype self.mimetype = mimetype
self.exc = exc self.exc = exc
def __str__(self): def __str__(self):
return self.name return self.name
def __repr__(self): def __repr__(self):
return f'<File attrs name={self.name} path={self.path} exc={self.exc} type=<{self.mimetype}> >' return f'<File attrs name={self.name} path={self.path} exc={self.exc} type=<{self.mimetype}> >'
class _ListGenerationIter: class _ListGenerationIter:
def __init__(self, list_class): def __init__(self, list_class):
self._current_index = 0 self._current_index = 0
self._list = list_class.list self._list = list_class.list
self._name = self._list[self._current_index] self._name = self._list[self._current_index]
self._path = list_class.path self._path = list_class.path
self._size = len(self._list) self._size = len(self._list)
def __iter__(self): def __iter__(self):
return self return self
@property @property
def type(self) -> str: def type(self) -> str:
guess = guess_type(f'{self._path}/{self._list[self._current_index]}')[0] guess = guess_type(f'{self._path}/{self._list[self._current_index]}')[0]
return guess return guess
@property @property
def _exc(self) -> str: def _exc(self) -> str:
try: try:
_ret = self._list[self._current_index].split('.')[-1] _ret = self._list[self._current_index].split('.')[-1]
except AttributeError: except AttributeError:
_ret = None _ret = None
return _ret return _ret
def __next__(self): def __next__(self):
if self._current_index < self._size: if self._current_index < self._size:
_name = self._list[self._current_index] _name = self._list[self._current_index]
_path = self._path _path = self._path
_type = self.type _type = self.type
_exc = self._exc _exc = self._exc
self._current_index += 1 self._current_index += 1
_memb = _FileAttrs(_name, _path, _type, _exc) _memb = _FileAttrs(_name, _path, _type, _exc)
return _memb return _memb
raise StopIteration raise StopIteration

View File

@@ -0,0 +1,52 @@
import logging
class _CustomFormatter(logging.Formatter):
grey = "\x1b[38;20m"
yellow = "\x1b[33;20m"
red = "\x1b[31;20m"
bold_red = "\x1b[31;1m"
reset = "\x1b[0m"
fmt = "%(asctime)s - [%(levelname)s] -%(module)s- %(message)s"
FORMATS = {
logging.DEBUG: grey + fmt + reset,
logging.INFO: grey + fmt + reset,
logging.WARNING: yellow + fmt + reset,
logging.ERROR: red + fmt + reset,
logging.CRITICAL: bold_red + fmt + reset
}
old_factory = logging.getLogRecordFactory()
def _record_factory(*args, **kwargs):
record = _CustomFormatter.old_factory(*args, **kwargs)
_module = record.module
_levelname = record.levelname
if len(_module) % 2 == 0 and len(_module) < 12:
_module = ' ' * ((12 - len(_module)) // 2) + _module + ' ' * ((12 - len(_module)) // 2)
elif len(_module) % 2 == 1 and len(_module) < 12:
_module = ' ' * ((12 - len(_module)) // 2) + record.module + ' ' * ((12 - len(_module)) // 2 + 1)
if len(_levelname) % 2 == 0 and len(_levelname) < 8:
_levelname = ' ' * ((8 - len(_levelname)) // 2) + _levelname + ' ' * ((8 - len(_levelname)) // 2)
elif len(record.levelname) % 2 == 1 and len(record.module) < 8:
_levelname = ' ' * ((8 - len(_levelname)) // 2) + _levelname + ' ' * ((8 - len(_levelname)) // 2 + 1)
record.module = _module
record.levelname = _levelname
return record
logging.setLogRecordFactory(_record_factory)
def format(self, record):
log_fmt = self.FORMATS.get(record.levelno)
formatter = logging.Formatter(log_fmt, "%d-%m-%Y %H:%M:%S")
return formatter.format(record)
logger = logging.getLogger('Pisya_Bot')
logger.setLevel(logging.DEBUG)
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
ch.setFormatter(_CustomFormatter())
logger.addHandler(ch)

View File

@@ -1,20 +1,17 @@
from asyncio import sleep from asyncio import sleep
from disnake import FFmpegOpusAudio from disnake import FFmpegPCMAudio
from loguru import logger
from .Logger import logger
# from .Logger import logger
async def play_audio(audio, bot, vc):
if not bot.voice_clients:
@logger.catch logger.error(f'Playing: {audio}')
async def play_audio(audio, bot, vc): vp = await vc.connect()
if not bot.voice_clients: if not vp.is_playing():
logger.error(f'Playing: {audio}') vp.play(FFmpegPCMAudio(f'{audio}', ))
vp = await vc.connect() while vp.is_playing():
if not vp.is_playing(): await sleep(0.5)
vp.play(FFmpegOpusAudio(f'{audio}', executable='ffmpeg', options='-nostats -loglevel 0')) await sleep(1)
while vp.is_playing(): await vp.disconnect()
await sleep(0.5)
await sleep(1)
await vp.disconnect()

View File

@@ -0,0 +1,5 @@
"""
integral_lib
~~~~~~~~~~~~~
Some libs for the src which help him
"""

BIN
tests/requirements.txt Normal file

Binary file not shown.

41
tests/test_bot.py Normal file
View File

@@ -0,0 +1,41 @@
from disnake import Intents
from disnake.ext import commands
intents = Intents(messages=True,
message_content=True,
)
class Cog(commands.Cog):
@commands.command()
async def my_cmd(self, ctx):
pass
class CogTwo(commands.Cog):
async def bot_check(self, ctx) -> bool:
pass
class CogThree(commands.Cog):
async def bot_check_once(self, ctx) -> bool:
pass
class CogFour(commands.Cog):
async def bot_slash_command_check(self, ctx) -> bool:
pass
class CogFive(commands.Cog):
async def can_run(self, ctx) -> bool:
pass
def test_bot():
bot = commands.Bot(command_prefix='$', intents=intents)
bot.add_cog(Cog())
bot.add_cog(CogTwo())
bot.add_cog(CogThree())
bot.add_cog(CogFour())
bot.add_cog(CogFive())

31
tests/test_lib_Cog.py Normal file
View File

@@ -0,0 +1,31 @@
import sys
import pytest
from disnake.ext.commands.common_bot_base import CommonBotBase
from mock import mock
sys.path.append('src')
from integral_lib import CogsPrep
def test_cog_list():
with mock.patch('integral_lib.CogsPrep.listdir') as MockClass:
MockClass.return_value = ['cog1.py', 'cog2.py']
result = CogsPrep.cog_list()
assert result == ['cog1', 'cog2']
@pytest.mark.parametrize("cog", ["cog1.py", "cog2"])
@pytest.mark.parametrize("what_do", ['load', 'unload', 'reload', 'disable', 'enable'])
def test_work_with_cogs(what_do, cog):
with mock.patch('integral_lib.CogsPrep.rename') as mock_rename:
mock_rename.return_value = None
mock_bot = mock.MagicMock(spec=CommonBotBase)
result = CogsPrep.work_with_cogs(what_do, mock_bot, cog)
if what_do in ['load', 'enable']:
assert mock_bot.load_extension.called
elif what_do in ['unload', 'disable']:
assert mock_bot.unload_extension.called
elif what_do == 'reload':
assert mock_bot.reload_extension.called