Compare commits
1 Commits
master
...
flag_devel
Author | SHA1 | Date | |
---|---|---|---|
![]() |
af10493e81 |
@ -3,7 +3,6 @@ import logging
|
||||
import re
|
||||
|
||||
import discord
|
||||
from discord.ext.commands import RoleConverter, Greedy, CommandError, ArgumentParsingError
|
||||
from discord.ext.commands.view import StringView
|
||||
from redbot.core import Config, checks, commands
|
||||
from redbot.core.bot import Red
|
||||
@ -14,38 +13,15 @@ log = logging.getLogger("red.fox_v3.ccrole")
|
||||
|
||||
|
||||
async def _get_roles_from_content(ctx, content):
|
||||
# greedy = Greedy[RoleConverter]
|
||||
view = StringView(content)
|
||||
rc = RoleConverter()
|
||||
|
||||
# "Borrowed" from discord.ext.commands.Command._transform_greedy_pos
|
||||
result = []
|
||||
while not view.eof:
|
||||
# for use with a manual undo
|
||||
previous = view.index
|
||||
|
||||
view.skip_ws()
|
||||
try:
|
||||
argument = view.get_quoted_word()
|
||||
value = await rc.convert(ctx, argument)
|
||||
except (CommandError, ArgumentParsingError):
|
||||
view.index = previous
|
||||
break
|
||||
else:
|
||||
result.append(value)
|
||||
|
||||
return [r.id for r in result]
|
||||
|
||||
# Old method
|
||||
# content_list = content.split(",")
|
||||
# try:
|
||||
# role_list = [
|
||||
# discord.utils.get(ctx.guild.roles, name=role.strip(" ")).id for role in content_list
|
||||
# ]
|
||||
# except (discord.HTTPException, AttributeError): # None.id is attribute error
|
||||
# return None
|
||||
# else:
|
||||
# return role_list
|
||||
content_list = content.split(",")
|
||||
try:
|
||||
role_list = [
|
||||
discord.utils.get(ctx.guild.roles, name=role.strip(" ")).id for role in content_list
|
||||
]
|
||||
except (discord.HTTPException, AttributeError): # None.id is attribute error
|
||||
return None
|
||||
else:
|
||||
return role_list
|
||||
|
||||
|
||||
class CCRole(commands.Cog):
|
||||
@ -108,7 +84,7 @@ class CCRole(commands.Cog):
|
||||
|
||||
# Roles to add
|
||||
await ctx.send(
|
||||
"What roles should it add?\n"
|
||||
"What roles should it add? (Must be **comma separated**)\n"
|
||||
"Say `None` to skip adding roles"
|
||||
)
|
||||
|
||||
@ -130,7 +106,7 @@ class CCRole(commands.Cog):
|
||||
|
||||
# Roles to remove
|
||||
await ctx.send(
|
||||
"What roles should it remove?\n"
|
||||
"What roles should it remove? (Must be comma separated)\n"
|
||||
"Say `None` to skip removing roles"
|
||||
)
|
||||
try:
|
||||
@ -148,7 +124,7 @@ class CCRole(commands.Cog):
|
||||
|
||||
# Roles to use
|
||||
await ctx.send(
|
||||
"What roles are allowed to use this command?\n"
|
||||
"What roles are allowed to use this command? (Must be comma separated)\n"
|
||||
"Say `None` to allow all roles"
|
||||
)
|
||||
|
||||
|
@ -74,18 +74,12 @@ If you get an error at this step, stop and skip to one of the manual methods bel
|
||||
|
||||
#### Step 2: Install additional dependencies
|
||||
|
||||
Here you need to decide which training models you want to have available to you.
|
||||
Assuming the previous commands had no error, you can now use `pipinstall` to add the remaining dependencies.
|
||||
|
||||
Shutdown the bot and run any number of these in the console:
|
||||
NOTE: This method is not the intended use case for `pipinstall` and may stop working in the future.
|
||||
|
||||
```
|
||||
python -m spacy download en_core_web_sm # ~15 MB
|
||||
|
||||
python -m spacy download en_core_web_md # ~50 MB
|
||||
|
||||
python -m spacy download en_core_web_lg # ~750 MB (CPU Optimized)
|
||||
|
||||
python -m spacy download en_core_web_trf # ~500 MB (GPU Optimized)
|
||||
[p]pipinstall --no-deps chatterbot>=1.1
|
||||
```
|
||||
|
||||
#### Step 3: Load the cog and get started
|
||||
@ -95,14 +89,62 @@ python -m spacy download en_core_web_trf # ~500 MB (GPU Optimized)
|
||||
```
|
||||
|
||||
### Windows - Manually
|
||||
Deprecated
|
||||
#### Step 1: Built-in Downloader
|
||||
|
||||
You need to get a copy of the requirements.txt provided with chatter, I recommend this method.
|
||||
|
||||
```
|
||||
[p]repo add Fox https://github.com/bobloy/Fox-V3
|
||||
```
|
||||
|
||||
#### Step 2: Install Requirements
|
||||
|
||||
Make sure you have your virtual environment that you installed Red on activated before starting this step. See the Red Docs for details on how.
|
||||
|
||||
In a terminal running as an admin, navigate to the directory containing this repo.
|
||||
|
||||
I've used my install directory as an example.
|
||||
|
||||
```
|
||||
cd C:\Users\Bobloy\AppData\Local\Red-DiscordBot\Red-DiscordBot\data\bobbot\cogs\RepoManager\repos\Fox\chatter
|
||||
pip install -r requirements.txt
|
||||
pip install --no-deps "chatterbot>=1.1"
|
||||
```
|
||||
|
||||
#### Step 3: Load Chatter
|
||||
|
||||
```
|
||||
[p]repo add Fox https://github.com/bobloy/Fox-V3 # If you didn't already do this in step 1
|
||||
[p]cog install Fox chatter
|
||||
[p]load chatter
|
||||
```
|
||||
|
||||
### Linux - Manually
|
||||
Deprecated
|
||||
|
||||
#### Step 1: Built-in Downloader
|
||||
|
||||
```
|
||||
[p]repo add Fox https://github.com/bobloy/Fox-V3
|
||||
[p]cog install Fox chatter
|
||||
```
|
||||
|
||||
#### Step 2: Install Requirements
|
||||
|
||||
In your console with your virtual environment activated:
|
||||
|
||||
```
|
||||
pip install --no-deps "chatterbot>=1.1"
|
||||
```
|
||||
|
||||
### Step 3: Load Chatter
|
||||
|
||||
```
|
||||
[p]load chatter
|
||||
```
|
||||
|
||||
# Configuration
|
||||
|
||||
Chatter works out the box without any training by learning as it goes,
|
||||
Chatter works out the the box without any training by learning as it goes,
|
||||
but will have very poor and repetitive responses at first.
|
||||
|
||||
Initial training is recommended to speed up its learning.
|
||||
|
@ -1,10 +1,8 @@
|
||||
from .chat import Chatter
|
||||
|
||||
|
||||
async def setup(bot):
|
||||
cog = Chatter(bot)
|
||||
await cog.initialize()
|
||||
bot.add_cog(cog)
|
||||
def setup(bot):
|
||||
bot.add_cog(Chatter(bot))
|
||||
|
||||
|
||||
# __all__ = (
|
||||
|
@ -19,7 +19,6 @@ from redbot.core.utils.predicates import MessagePredicate
|
||||
|
||||
from chatter.trainers import MovieTrainer, TwitterCorpusTrainer, UbuntuCorpusTrainer2
|
||||
|
||||
chatterbot_log = logging.getLogger("red.fox_v3.chatterbot")
|
||||
log = logging.getLogger("red.fox_v3.chatter")
|
||||
|
||||
|
||||
@ -30,12 +29,6 @@ def my_local_get_prefix(prefixes, content):
|
||||
return None
|
||||
|
||||
|
||||
class ENG_TRF:
|
||||
ISO_639_1 = "en_core_web_trf"
|
||||
ISO_639 = "eng"
|
||||
ENGLISH_NAME = "English"
|
||||
|
||||
|
||||
class ENG_LG:
|
||||
ISO_639_1 = "en_core_web_lg"
|
||||
ISO_639 = "eng"
|
||||
@ -59,15 +52,12 @@ class Chatter(Cog):
|
||||
This cog trains a chatbot that will talk like members of your Guild
|
||||
"""
|
||||
|
||||
models = [ENG_SM, ENG_MD, ENG_LG, ENG_TRF]
|
||||
algos = [SpacySimilarity, JaccardSimilarity, LevenshteinDistance]
|
||||
|
||||
def __init__(self, bot):
|
||||
super().__init__()
|
||||
self.bot = bot
|
||||
self.config = Config.get_conf(self, identifier=6710497116116101114)
|
||||
default_global = {"learning": True, "model_number": 0, "algo_number": 0, "threshold": 0.90}
|
||||
self.default_guild = {
|
||||
default_global = {"learning": True}
|
||||
default_guild = {
|
||||
"whitelist": None,
|
||||
"days": 1,
|
||||
"convo_delta": 15,
|
||||
@ -80,16 +70,16 @@ class Chatter(Cog):
|
||||
# TODO: Move training_model and similarity_algo to config
|
||||
# TODO: Add an option to see current settings
|
||||
|
||||
self.tagger_language = ENG_SM
|
||||
self.tagger_language = ENG_MD
|
||||
self.similarity_algo = SpacySimilarity
|
||||
self.similarity_threshold = 0.90
|
||||
self.chatbot = None
|
||||
self.chatbot = self._create_chatbot()
|
||||
# self.chatbot.set_trainer(ListTrainer)
|
||||
|
||||
# self.trainer = ListTrainer(self.chatbot)
|
||||
|
||||
self.config.register_global(**default_global)
|
||||
self.config.register_guild(**self.default_guild)
|
||||
self.config.register_guild(**default_guild)
|
||||
|
||||
self.loop = asyncio.get_event_loop()
|
||||
|
||||
@ -102,18 +92,6 @@ class Chatter(Cog):
|
||||
"""Nothing to delete"""
|
||||
return
|
||||
|
||||
async def initialize(self):
|
||||
all_config = dict(self.config.defaults["GLOBAL"])
|
||||
all_config.update(await self.config.all())
|
||||
model_number = all_config["model_number"]
|
||||
algo_number = all_config["algo_number"]
|
||||
threshold = all_config["threshold"]
|
||||
|
||||
self.tagger_language = self.models[model_number]
|
||||
self.similarity_algo = self.algos[algo_number]
|
||||
self.similarity_threshold = threshold
|
||||
self.chatbot = self._create_chatbot()
|
||||
|
||||
def _create_chatbot(self):
|
||||
|
||||
return ChatBot(
|
||||
@ -126,7 +104,7 @@ class Chatter(Cog):
|
||||
logic_adapters=["chatterbot.logic.BestMatch"],
|
||||
maximum_similarity_threshold=self.similarity_threshold,
|
||||
tagger_language=self.tagger_language,
|
||||
logger=chatterbot_log,
|
||||
logger=log,
|
||||
)
|
||||
|
||||
async def _get_conversation(self, ctx, in_channels: List[discord.TextChannel]):
|
||||
@ -350,12 +328,15 @@ class Chatter(Cog):
|
||||
self, ctx: commands.Context, algo_number: int, threshold: float = None
|
||||
):
|
||||
"""
|
||||
Switch the active logic algorithm to one of the three. Default is Spacy
|
||||
Switch the active logic algorithm to one of the three. Default after reload is Spacy
|
||||
|
||||
0: Spacy
|
||||
1: Jaccard
|
||||
2: Levenshtein
|
||||
"""
|
||||
|
||||
algos = [SpacySimilarity, JaccardSimilarity, LevenshteinDistance]
|
||||
|
||||
if algo_number < 0 or algo_number > 2:
|
||||
await ctx.send_help()
|
||||
return
|
||||
@ -368,11 +349,8 @@ class Chatter(Cog):
|
||||
return
|
||||
else:
|
||||
self.similarity_threshold = threshold
|
||||
await self.config.threshold.set(self.similarity_threshold)
|
||||
|
||||
self.similarity_algo = self.algos[algo_number]
|
||||
await self.config.algo_number.set(algo_number)
|
||||
|
||||
self.similarity_algo = algos[algo_number]
|
||||
async with ctx.typing():
|
||||
self.chatbot = self._create_chatbot()
|
||||
|
||||
@ -382,18 +360,20 @@ class Chatter(Cog):
|
||||
@chatter.command(name="model")
|
||||
async def chatter_model(self, ctx: commands.Context, model_number: int):
|
||||
"""
|
||||
Switch the active model to one of the three. Default is Small
|
||||
Switch the active model to one of the three. Default after reload is Medium
|
||||
|
||||
0: Small
|
||||
1: Medium (Requires additional setup)
|
||||
1: Medium
|
||||
2: Large (Requires additional setup)
|
||||
3. Accurate (Requires additional setup)
|
||||
"""
|
||||
if model_number < 0 or model_number > 3:
|
||||
|
||||
models = [ENG_SM, ENG_MD, ENG_LG]
|
||||
|
||||
if model_number < 0 or model_number > 2:
|
||||
await ctx.send_help()
|
||||
return
|
||||
|
||||
if model_number >= 0:
|
||||
if model_number == 2:
|
||||
await ctx.maybe_send_embed(
|
||||
"Additional requirements needed. See guide before continuing.\n" "Continue?"
|
||||
)
|
||||
@ -406,8 +386,7 @@ class Chatter(Cog):
|
||||
if not pred.result:
|
||||
return
|
||||
|
||||
self.tagger_language = self.models[model_number]
|
||||
await self.config.model_number.set(model_number)
|
||||
self.tagger_language = models[model_number]
|
||||
async with ctx.typing():
|
||||
self.chatbot = self._create_chatbot()
|
||||
|
||||
@ -416,13 +395,7 @@ class Chatter(Cog):
|
||||
)
|
||||
|
||||
@commands.is_owner()
|
||||
@chatter.group(name="trainset")
|
||||
async def chatter_trainset(self, ctx: commands.Context):
|
||||
"""Commands for configuring training"""
|
||||
pass
|
||||
|
||||
@commands.is_owner()
|
||||
@chatter_trainset.command(name="minutes")
|
||||
@chatter.command(name="minutes")
|
||||
async def minutes(self, ctx: commands.Context, minutes: int):
|
||||
"""
|
||||
Sets the number of minutes the bot will consider a break in a conversation during training
|
||||
@ -438,7 +411,7 @@ class Chatter(Cog):
|
||||
await ctx.tick()
|
||||
|
||||
@commands.is_owner()
|
||||
@chatter_trainset.command(name="age")
|
||||
@chatter.command(name="age")
|
||||
async def age(self, ctx: commands.Context, days: int):
|
||||
"""
|
||||
Sets the number of days to look back
|
||||
@ -657,7 +630,7 @@ class Chatter(Cog):
|
||||
|
||||
guild: discord.Guild = getattr(message, "guild", None)
|
||||
|
||||
if guild is None or await self.bot.cog_disabled_in_guild(self, guild):
|
||||
if await self.bot.cog_disabled_in_guild(self, guild):
|
||||
return
|
||||
|
||||
ctx: commands.Context = await self.bot.get_context(message)
|
||||
@ -732,9 +705,7 @@ class Chatter(Cog):
|
||||
)
|
||||
|
||||
replying = None
|
||||
if (
|
||||
"reply" not in self._guild_cache[guild.id] and self.default_guild["reply"]
|
||||
) or self._guild_cache[guild.id]["reply"]:
|
||||
if self._guild_cache[guild.id]["reply"]:
|
||||
if message != ctx.channel.last_message:
|
||||
replying = message
|
||||
|
||||
|
@ -7,10 +7,18 @@
|
||||
"hidden": false,
|
||||
"install_msg": "Thank you for installing Chatter! Please make sure you check the install instructions at https://github.com/bobloy/Fox-V3/blob/master/chatter/README.md\nAfter that, get started ith `[p]load chatter` and `[p]help Chatter`",
|
||||
"requirements": [
|
||||
"git+git://github.com/bobloy/ChatterBot@fox#egg=ChatterBot>=1.1.0.dev4",
|
||||
"kaggle",
|
||||
"https://github.com/explosion/spacy-models/releases/download/en_core_web_sm-3.1.0/en_core_web_sm-3.1.0.tar.gz#egg=en_core_web_sm",
|
||||
"https://github.com/explosion/spacy-models/releases/download/en_core_web_md-3.1.0/en_core_web_md-3.1.0.tar.gz#egg=en_core_web_md"
|
||||
"git+git://github.com/gunthercox/chatterbot-corpus@master#egg=chatterbot_corpus",
|
||||
"mathparse>=0.1,<0.2",
|
||||
"nltk>=3.2,<4.0",
|
||||
"pint>=0.8.1",
|
||||
"python-dateutil>=2.8,<2.9",
|
||||
"pyyaml>=5.3,<5.4",
|
||||
"sqlalchemy>=1.3,<1.4",
|
||||
"pytz",
|
||||
"https://github.com/explosion/spacy-models/releases/download/en_core_web_sm-2.3.1/en_core_web_sm-2.3.1.tar.gz#egg=en_core_web_sm",
|
||||
"https://github.com/explosion/spacy-models/releases/download/en_core_web_md-2.3.1/en_core_web_md-2.3.1.tar.gz#egg=en_core_web_md",
|
||||
"spacy>=2.3,<2.4",
|
||||
"kaggle"
|
||||
],
|
||||
"short": "Local Chatbot run on machine learning",
|
||||
"end_user_data_statement": "This cog only stores anonymous conversations data; no End User Data is stored.",
|
||||
|
12
chatter/requirements.txt
Normal file
12
chatter/requirements.txt
Normal file
@ -0,0 +1,12 @@
|
||||
git+git://github.com/gunthercox/chatterbot-corpus@master#egg=chatterbot_corpus
|
||||
mathparse>=0.1,<0.2
|
||||
nltk>=3.2,<4.0
|
||||
pint>=0.8.1
|
||||
python-dateutil>=2.8,<2.9
|
||||
pyyaml>=5.3,<5.4
|
||||
sqlalchemy>=1.3,<1.4
|
||||
pytz
|
||||
spacy>=2.3,<2.4
|
||||
https://github.com/explosion/spacy-models/releases/download/en_core_web_sm-2.3.1/en_core_web_sm-2.3.1.tar.gz#egg=en_core_web_sm
|
||||
https://github.com/explosion/spacy-models/releases/download/en_core_web_md-2.3.1/en_core_web_md-2.3.1.tar.gz#egg=en_core_web_md
|
||||
# https://github.com/explosion/spacy-models/releases/download/en_core_web_lg-2.3.1/en_core_web_lg-2.3.1.tar.gz#egg=en_core_web_lg
|
@ -5,7 +5,7 @@ class MyDumbSQLStorageAdapter(SQLStorageAdapter):
|
||||
def __init__(self, **kwargs):
|
||||
super(SQLStorageAdapter, self).__init__(**kwargs)
|
||||
|
||||
from sqlalchemy import create_engine, inspect
|
||||
from sqlalchemy import create_engine
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
|
||||
self.database_uri = kwargs.get("database_uri", False)
|
||||
@ -18,7 +18,9 @@ class MyDumbSQLStorageAdapter(SQLStorageAdapter):
|
||||
if not self.database_uri:
|
||||
self.database_uri = "sqlite:///db.sqlite3"
|
||||
|
||||
self.engine = create_engine(self.database_uri, connect_args={"check_same_thread": False})
|
||||
self.engine = create_engine(
|
||||
self.database_uri, convert_unicode=True, connect_args={"check_same_thread": False}
|
||||
)
|
||||
|
||||
if self.database_uri.startswith("sqlite://"):
|
||||
from sqlalchemy.engine import Engine
|
||||
@ -29,7 +31,7 @@ class MyDumbSQLStorageAdapter(SQLStorageAdapter):
|
||||
dbapi_connection.execute("PRAGMA journal_mode=WAL")
|
||||
dbapi_connection.execute("PRAGMA synchronous=NORMAL")
|
||||
|
||||
if not inspect(self.engine).has_table("Statement"):
|
||||
if not self.engine.dialect.has_table(self.engine, "Statement"):
|
||||
self.create_database()
|
||||
|
||||
self.Session = sessionmaker(bind=self.engine, expire_on_commit=True)
|
||||
|
@ -1,6 +1,5 @@
|
||||
import asyncio
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import pathlib
|
||||
from abc import ABC
|
||||
@ -14,8 +13,6 @@ from redbot.core import Config, commands
|
||||
from redbot.core.bot import Red
|
||||
from redbot.core.data_manager import bundled_data_path, cog_data_path
|
||||
|
||||
log = logging.getLogger("red.fox_v3.conquest")
|
||||
|
||||
|
||||
class Conquest(commands.Cog):
|
||||
"""
|
||||
@ -56,20 +53,14 @@ class Conquest(commands.Cog):
|
||||
self.current_map = await self.config.current_map()
|
||||
|
||||
if self.current_map:
|
||||
if not await self.current_map_load():
|
||||
await self.config.current_map.clear()
|
||||
await self.current_map_load()
|
||||
|
||||
async def current_map_load(self):
|
||||
map_data_path = self.asset_path / self.current_map / "data.json"
|
||||
if not map_data_path.exists():
|
||||
log.warning(f"{map_data_path} does not exist. Clearing current map")
|
||||
return False
|
||||
|
||||
with map_data_path.open() as mapdata:
|
||||
self.map_data: dict = json.load(mapdata)
|
||||
self.ext = self.map_data["extension"]
|
||||
self.ext_format = "JPEG" if self.ext.upper() == "JPG" else self.ext.upper()
|
||||
return True
|
||||
|
||||
@commands.group()
|
||||
async def conquest(self, ctx: commands.Context):
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"maps": [
|
||||
"simple",
|
||||
"ck2",
|
||||
"HoI"
|
||||
"simple_blank_map",
|
||||
"test",
|
||||
"test2"
|
||||
]
|
||||
}
|
@ -441,7 +441,6 @@ class FIFO(commands.Cog):
|
||||
self.scheduler.print_jobs(out=cp)
|
||||
|
||||
out = cp.string
|
||||
out=out.replace("*","\*")
|
||||
|
||||
if out:
|
||||
if len(out) > 2000:
|
||||
|
@ -90,7 +90,6 @@ things_for_fakemessage_to_steal = [
|
||||
"content",
|
||||
"nonce",
|
||||
"reference",
|
||||
"_edited_timestamp" # New 7/23/21
|
||||
]
|
||||
|
||||
things_fakemessage_sets_by_default = {
|
||||
@ -143,7 +142,7 @@ class FakeMessage(discord.Message):
|
||||
self._update(
|
||||
{
|
||||
"mention_roles": self.raw_role_mentions,
|
||||
"mentions": [{"id": _id} for _id in self.raw_mentions],
|
||||
"mentions": self.raw_mentions,
|
||||
}
|
||||
)
|
||||
|
||||
|
51
flag/flag.py
51
flag/flag.py
@ -1,13 +1,17 @@
|
||||
import logging
|
||||
from datetime import date, timedelta
|
||||
from typing import Literal
|
||||
from typing import Literal, Optional
|
||||
|
||||
import discord
|
||||
from redbot.cogs.mutes import Mutes
|
||||
from redbot.core import Config, checks, commands
|
||||
from redbot.core.bot import Red
|
||||
from redbot.core.commands import Cog
|
||||
from redbot.core.utils import AsyncIter
|
||||
from redbot.core.utils.chat_formatting import pagify
|
||||
|
||||
log = logging.getLogger("red.fox_v3.flag")
|
||||
|
||||
|
||||
class Flag(Cog):
|
||||
"""
|
||||
@ -19,7 +23,7 @@ class Flag(Cog):
|
||||
self.bot = bot
|
||||
self.config = Config.get_conf(self, identifier=9811198108111121, force_registration=True)
|
||||
default_global = {}
|
||||
default_guild = {"days": 31, "dm": True, "flags": {}}
|
||||
default_guild = {"days": 31, "dm": True, "flags": {}, "mutethreshold": 0}
|
||||
|
||||
self.config.register_global(**default_global)
|
||||
self.config.register_guild(**default_guild)
|
||||
@ -78,6 +82,29 @@ class Flag(Cog):
|
||||
"DM-ing members when they get a flag is now set to **{}**".format(not dm)
|
||||
)
|
||||
|
||||
@checks.admin_or_permissions(manage_guild=True)
|
||||
@flagset.command(name="mute")
|
||||
async def flagset_mute(self, ctx: commands.Context, count: int):
|
||||
"""
|
||||
Sets the threshold for flags to mute the user.
|
||||
|
||||
Only works when the core mute cog is configured properly.
|
||||
|
||||
Set to zero to disable.
|
||||
"""
|
||||
if count < 0:
|
||||
await ctx.send_help()
|
||||
return
|
||||
|
||||
await self.config.guild(ctx.guild).mutethreshold.set(count)
|
||||
|
||||
if count:
|
||||
await ctx.maybe_send_embed(
|
||||
"Will now attempt to mute people after **{}** flags".format(count)
|
||||
)
|
||||
else:
|
||||
await ctx.maybe_send_embed("Muting disabled.")
|
||||
|
||||
@staticmethod
|
||||
def _flag_template():
|
||||
return {"reason": "", "expireyear": 0, "expiremonth": 0, "expireday": 0}
|
||||
@ -91,7 +118,8 @@ class Flag(Cog):
|
||||
await self._check_flags(guild)
|
||||
|
||||
flag = self._flag_template()
|
||||
expire_date = date.today() + timedelta(days=await self.config.guild(guild).days())
|
||||
mute_days = await self.config.guild(guild).days()
|
||||
expire_date = date.today() + timedelta(mute_days)
|
||||
|
||||
flag["reason"] = reason
|
||||
flag["expireyear"] = expire_date.year
|
||||
@ -106,6 +134,12 @@ class Flag(Cog):
|
||||
if str(member.id) not in flags:
|
||||
flags[str(member.id)] = []
|
||||
flags[str(member.id)].append(flag)
|
||||
flag_count = len(flags[str(member.id)])
|
||||
|
||||
mute_threshold = await self.config.guild(guild).mutethreshold()
|
||||
if 0 < mute_threshold <= flag_count:
|
||||
able_to_mute = await self._attempt_mute(ctx, member, mute_days)
|
||||
log.debug(f"Mute attempt: {able_to_mute}")
|
||||
|
||||
outembed = await self._list_flags(member)
|
||||
|
||||
@ -166,6 +200,17 @@ class Flag(Cog):
|
||||
for page in pagify(out):
|
||||
await ctx.send(page)
|
||||
|
||||
async def _attempt_mute(self, ctx, member: discord.Member, days):
|
||||
mutes: Optional[Mutes] = self.bot.get_cog("Mutes")
|
||||
if mutes is None:
|
||||
log.info("Mutes cog not loaded, cannot mute")
|
||||
return False
|
||||
|
||||
return await mutes.mute(ctx, member, f'{days} days [Flag] Exceeded mute threshold')
|
||||
# return await mutes.mute_user(
|
||||
# member.guild, author, member, until, "[Flag] Exceeded mute threshold"
|
||||
# )
|
||||
|
||||
async def _list_flags(self, member: discord.Member):
|
||||
"""Returns a pretty embed of flags on a member"""
|
||||
flags = await self.config.guild(member.guild).flags.get_raw(str(member.id), default=[])
|
||||
|
@ -28,12 +28,9 @@ async def get_channel_counts(category, guild):
|
||||
online_num = members - offline_num
|
||||
# Gets count of actual users
|
||||
human_num = members - bot_num
|
||||
# count amount of premium subs/nitro subs.
|
||||
boosters = guild.premium_subscription_count
|
||||
return {
|
||||
"members": members,
|
||||
"humans": human_num,
|
||||
"boosters": boosters,
|
||||
"bots": bot_num,
|
||||
"roles": roles_num,
|
||||
"channels": channels_num,
|
||||
@ -61,7 +58,6 @@ class InfoChannel(Cog):
|
||||
self.default_channel_names = {
|
||||
"members": "Members: {count}",
|
||||
"humans": "Humans: {count}",
|
||||
"boosters": "Boosters: {count}",
|
||||
"bots": "Bots: {count}",
|
||||
"roles": "Roles: {count}",
|
||||
"channels": "Channels: {count}",
|
||||
@ -174,7 +170,6 @@ class InfoChannel(Cog):
|
||||
Valid Types are:
|
||||
- `members`: Total members on the server
|
||||
- `humans`: Total members that aren't bots
|
||||
- `boosters`: Total amount of boosters
|
||||
- `bots`: Total bots
|
||||
- `roles`: Total number of roles
|
||||
- `channels`: Total number of channels excluding infochannels,
|
||||
@ -229,7 +224,6 @@ class InfoChannel(Cog):
|
||||
Valid Types are:
|
||||
- `members`: Total members on the server
|
||||
- `humans`: Total members that aren't bots
|
||||
- `boosters`: Total amount of boosters
|
||||
- `bots`: Total bots
|
||||
- `roles`: Total number of roles
|
||||
- `channels`: Total number of channels excluding infochannels
|
||||
@ -447,7 +441,6 @@ class InfoChannel(Cog):
|
||||
guild,
|
||||
members=True,
|
||||
humans=True,
|
||||
boosters=True,
|
||||
bots=True,
|
||||
roles=True,
|
||||
channels=True,
|
||||
@ -504,16 +497,14 @@ class InfoChannel(Cog):
|
||||
guild_data = await self.config.guild(guild).all()
|
||||
|
||||
to_update = (
|
||||
kwargs.keys() & [key for key, value in guild_data["enabled_channels"].items() if value]
|
||||
kwargs.keys() & guild_data["enabled_channels"].keys()
|
||||
) # Value in kwargs doesn't matter
|
||||
|
||||
if to_update or extra_roles:
|
||||
log.debug(f"{to_update=}\n"
|
||||
f"{extra_roles=}")
|
||||
log.debug(f"{to_update=}")
|
||||
|
||||
if to_update or extra_roles:
|
||||
category = guild.get_channel(guild_data["category_id"])
|
||||
if category is None:
|
||||
log.debug('Channel category is missing, updating must be off')
|
||||
return # Nothing to update, must be off
|
||||
|
||||
channel_data = await get_channel_counts(category, guild)
|
||||
|
@ -40,20 +40,16 @@ class LoveCalculator(Cog):
|
||||
log.debug(f"{resp=}")
|
||||
soup_object = BeautifulSoup(resp, "html.parser")
|
||||
|
||||
description = soup_object.find("div", class_="result__score")
|
||||
description = soup_object.find("div", class_="result__score").get_text()
|
||||
|
||||
if description is None:
|
||||
description = "Dr. Love is busy right now"
|
||||
else:
|
||||
description = description.get_text().strip()
|
||||
description = description.strip()
|
||||
|
||||
result_image = soup_object.find("img", class_="result__image").get("src")
|
||||
|
||||
result_text = soup_object.find("div", class_="result-text")
|
||||
if result_text is None:
|
||||
result_text = f"{x} and {y} aren't compatible 😔"
|
||||
else:
|
||||
result_text = result_text.get_text()
|
||||
result_text = soup_object.find("div", class_="result-text").get_text()
|
||||
result_text = " ".join(result_text.split())
|
||||
|
||||
try:
|
||||
|
@ -77,13 +77,11 @@ class LastSeen(Cog):
|
||||
return
|
||||
last_seen = self.get_date_time(last_seen)
|
||||
|
||||
embed = discord.Embed(
|
||||
description="{} was last seen at this date and time".format(member.display_name),
|
||||
timestamp=last_seen,
|
||||
color=await self.bot.get_embed_color(ctx),
|
||||
)
|
||||
# embed = discord.Embed(
|
||||
# description="{} was last seen at this date and time".format(member.display_name),
|
||||
# timestamp=last_seen)
|
||||
|
||||
# embed = discord.Embed(timestamp=last_seen, color=await self.bot.get_embed_color(ctx))
|
||||
embed = discord.Embed(timestamp=last_seen, color=await self.bot.get_embed_color(ctx))
|
||||
await ctx.send(embed=embed)
|
||||
|
||||
@commands.Cog.listener()
|
||||
|
@ -32,7 +32,6 @@ class RecyclingPlant(Cog):
|
||||
|
||||
x = 0
|
||||
reward = 0
|
||||
timeoutcount = 0
|
||||
await ctx.send(
|
||||
"{0} has signed up for a shift at the Recycling Plant! Type ``exit`` to terminate it early.".format(
|
||||
ctx.author.display_name
|
||||
@ -54,25 +53,14 @@ class RecyclingPlant(Cog):
|
||||
return m.author == ctx.author and m.channel == ctx.channel
|
||||
|
||||
try:
|
||||
answer = await self.bot.wait_for("message", timeout=20, check=check)
|
||||
answer = await self.bot.wait_for("message", timeout=120, check=check)
|
||||
except asyncio.TimeoutError:
|
||||
answer = None
|
||||
|
||||
if answer is None:
|
||||
if timeoutcount == 2:
|
||||
await ctx.send(
|
||||
"{} slacked off at work, so they were sacked with no pay.".format(
|
||||
ctx.author.display_name
|
||||
)
|
||||
)
|
||||
break
|
||||
else:
|
||||
await ctx.send(
|
||||
"{} is slacking, and if they carry on not working, they'll be fired.".format(
|
||||
ctx.author.display_name
|
||||
)
|
||||
)
|
||||
timeoutcount += 1
|
||||
await ctx.send(
|
||||
"``{}`` fell down the conveyor belt to be sorted again!".format(used["object"])
|
||||
)
|
||||
elif answer.content.lower().strip() == used["action"]:
|
||||
await ctx.send(
|
||||
"Congratulations! You put ``{}`` down the correct chute! (**+50**)".format(
|
||||
|
@ -177,3 +177,7 @@ class SCP(Cog):
|
||||
|
||||
msg = "http://www.scp-wiki.net/log-of-unexplained-locations"
|
||||
await ctx.maybe_send_embed(msg)
|
||||
|
||||
|
||||
def setup(bot):
|
||||
bot.add_cog(SCP(bot))
|
||||
|
@ -6,7 +6,6 @@ import discord
|
||||
from redbot.core import Config, checks, commands
|
||||
from redbot.core.bot import Red
|
||||
from redbot.core.commands import Cog
|
||||
from redbot.core.utils.chat_formatting import pagify
|
||||
|
||||
log = logging.getLogger("red.fox_v3.stealemoji")
|
||||
# Replaced with discord.Asset.read()
|
||||
@ -100,8 +99,7 @@ class StealEmoji(Cog):
|
||||
await ctx.maybe_send_embed("No stolen emojis yet")
|
||||
return
|
||||
|
||||
for page in pagify(emoj, delims=[" "]):
|
||||
await ctx.maybe_send_embed(page)
|
||||
await ctx.maybe_send_embed(emoj)
|
||||
|
||||
@checks.is_owner()
|
||||
@stealemoji.command(name="notify")
|
||||
|
@ -37,7 +37,7 @@ class Timerole(Cog):
|
||||
self.bot = bot
|
||||
self.config = Config.get_conf(self, identifier=9811198108111121, force_registration=True)
|
||||
default_global = {}
|
||||
default_guild = {"announce": None, "reapply": True, "roles": {}, "skipbots": True}
|
||||
default_guild = {"announce": None, "reapply": True, "roles": {}}
|
||||
default_rolemember = {"had_role": False, "check_again_time": None}
|
||||
|
||||
self.config.register_global(**default_global)
|
||||
@ -92,9 +92,6 @@ class Timerole(Cog):
|
||||
await ctx.maybe_send_embed("Error: Invalid time string.")
|
||||
return
|
||||
|
||||
if parsed_time is None:
|
||||
return await ctx.maybe_send_embed("Error: Invalid time string.")
|
||||
|
||||
days = parsed_time.days
|
||||
hours = parsed_time.seconds // 60 // 60
|
||||
|
||||
@ -154,14 +151,6 @@ class Timerole(Cog):
|
||||
await self.config.guild(guild).reapply.set(not current_setting)
|
||||
await ctx.maybe_send_embed(f"Reapplying roles is now set to: {not current_setting}")
|
||||
|
||||
@timerole.command()
|
||||
async def skipbots(self, ctx: commands.Context):
|
||||
"""Toggle skipping bots when adding/removing roles. Defaults to True"""
|
||||
guild = ctx.guild
|
||||
current_setting = await self.config.guild(guild).skipbots()
|
||||
await self.config.guild(guild).skipbots.set(not current_setting)
|
||||
await ctx.maybe_send_embed(f"Skipping bots is now set to: {not current_setting}")
|
||||
|
||||
@timerole.command()
|
||||
async def delrole(self, ctx: commands.Context, role: discord.Role):
|
||||
"""Deletes a role from being added/removed after specified time"""
|
||||
@ -210,7 +199,6 @@ class Timerole(Cog):
|
||||
remove_results = ""
|
||||
reapply = all_guilds[guild_id]["reapply"]
|
||||
role_dict = all_guilds[guild_id]["roles"]
|
||||
skipbots = all_guilds[guild_id]["skipbots"]
|
||||
|
||||
if not any(role_dict.values()): # No roles
|
||||
log.debug(f"No roles are configured for guild: {guild}")
|
||||
@ -220,10 +208,6 @@ class Timerole(Cog):
|
||||
# log.debug(f"{all_mr=}")
|
||||
|
||||
async for member in AsyncIter(guild.members, steps=10):
|
||||
|
||||
if member.bot and skipbots:
|
||||
continue
|
||||
|
||||
addlist = []
|
||||
removelist = []
|
||||
|
||||
@ -311,11 +295,8 @@ class Timerole(Cog):
|
||||
log.exception("Failed Adding Roles")
|
||||
add_results += f"{member.display_name} : **(Failed Adding Roles)**\n"
|
||||
else:
|
||||
add_results += (
|
||||
" \n".join(
|
||||
f"{member.display_name} : {role.name}" for role in add_roles
|
||||
)
|
||||
+ "\n"
|
||||
add_results += " \n".join(
|
||||
f"{member.display_name} : {role.name}" for role in add_roles
|
||||
)
|
||||
for role_id in addlist:
|
||||
await self.config.custom(
|
||||
@ -329,11 +310,8 @@ class Timerole(Cog):
|
||||
log.exception("Failed Removing Roles")
|
||||
remove_results += f"{member.display_name} : **(Failed Removing Roles)**\n"
|
||||
else:
|
||||
remove_results += (
|
||||
" \n".join(
|
||||
f"{member.display_name} : {role.name}" for role in remove_roles
|
||||
)
|
||||
+ "\n"
|
||||
remove_results += " \n".join(
|
||||
f"{member.display_name} : {role.name}" for role in remove_roles
|
||||
)
|
||||
for role_id in removelist:
|
||||
await self.config.custom(
|
||||
|
46
tts/tts.py
46
tts/tts.py
@ -1,35 +1,11 @@
|
||||
import io
|
||||
import logging
|
||||
from typing import Optional, TYPE_CHECKING
|
||||
|
||||
import discord
|
||||
from discord.ext.commands import BadArgument, Converter
|
||||
from gtts import gTTS
|
||||
from gtts.lang import _fallback_deprecated_lang, tts_langs
|
||||
from redbot.core import Config, commands
|
||||
from redbot.core.bot import Red
|
||||
from redbot.core.commands import Cog
|
||||
|
||||
log = logging.getLogger("red.fox_v3.tts")
|
||||
|
||||
if TYPE_CHECKING:
|
||||
ISO639Converter = str
|
||||
else:
|
||||
|
||||
class ISO639Converter(Converter):
|
||||
async def convert(self, ctx, argument) -> str:
|
||||
lang = _fallback_deprecated_lang(argument)
|
||||
|
||||
try:
|
||||
langs = tts_langs()
|
||||
if lang not in langs:
|
||||
raise BadArgument("Language not supported: %s" % lang)
|
||||
except RuntimeError as e:
|
||||
log.debug(str(e), exc_info=True)
|
||||
log.warning(str(e))
|
||||
|
||||
return lang
|
||||
|
||||
|
||||
class TTS(Cog):
|
||||
"""
|
||||
@ -42,7 +18,7 @@ class TTS(Cog):
|
||||
|
||||
self.config = Config.get_conf(self, identifier=9811198108111121, force_registration=True)
|
||||
default_global = {}
|
||||
default_guild = {"language": "en"}
|
||||
default_guild = {}
|
||||
|
||||
self.config.register_global(**default_global)
|
||||
self.config.register_guild(**default_guild)
|
||||
@ -51,29 +27,13 @@ class TTS(Cog):
|
||||
"""Nothing to delete"""
|
||||
return
|
||||
|
||||
@commands.mod()
|
||||
@commands.command()
|
||||
async def ttslang(self, ctx: commands.Context, lang: ISO639Converter):
|
||||
"""
|
||||
Sets the default language for TTS in this guild.
|
||||
|
||||
Default is `en` for English
|
||||
"""
|
||||
await self.config.guild(ctx.guild).language.set(lang)
|
||||
await ctx.send(f"Default tts language set to {lang}")
|
||||
|
||||
@commands.command(aliases=["t2s", "text2"])
|
||||
async def tts(
|
||||
self, ctx: commands.Context, lang: Optional[ISO639Converter] = None, *, text: str
|
||||
):
|
||||
async def tts(self, ctx: commands.Context, *, text: str):
|
||||
"""
|
||||
Send Text to speech messages as an mp3
|
||||
"""
|
||||
if lang is None:
|
||||
lang = await self.config.guild(ctx.guild).language()
|
||||
|
||||
mp3_fp = io.BytesIO()
|
||||
tts = gTTS(text, lang=lang)
|
||||
tts = gTTS(text, lang="en")
|
||||
tts.write_to_fp(mp3_fp)
|
||||
mp3_fp.seek(0)
|
||||
await ctx.send(file=discord.File(mp3_fp, "text.mp3"))
|
||||
|
Loading…
x
Reference in New Issue
Block a user