mirror of
https://github.com/Cog-Creators/Red-DiscordBot.git
synced 2025-11-06 03:08:55 -05:00
[V3 Everything] Package bot and write setup scripts (#964)
Ya'll are gonna hate me. * Initial modifications * Add initial setup.py * working setup py help * Modify setup file to package stuff * Move a bunch of shit and fix imports * Fix or skip tests * Must add init files for find_packages to work * Move main to scripts folder and rename * Add shebangs * Copy over translation files * WORKING PIP INSTALL * add dependency information * Hardcoded version for now, will need to figure out a better way to do this * OKAY ITS FINALLY FUCKING WORKING * Add this guy * Fix stuff * Change readme to rst * Remove double sentry opt in * Oopsie * Fix this thing * Aaaand fix test * Aaaand fix test * Fix core cog importing and default cog install path * Adjust readme * change instance name from optional to required * Ayyy let's do more dependency injection
This commit is contained in:
parent
6b1fc786ee
commit
d69fd63da7
@ -4,9 +4,9 @@ python:
|
||||
- "3.5.3"
|
||||
- "3.6.1"
|
||||
install:
|
||||
- pip install -r requirements.txt
|
||||
- pip install --process-dependency-links -e .[test]
|
||||
script:
|
||||
- python -m compileall ./cogs
|
||||
- python -m compileall ./redbot/cogs
|
||||
- python -m pytest
|
||||
cache: pip
|
||||
notifications:
|
||||
|
||||
4
MANIFEST.in
Normal file
4
MANIFEST.in
Normal file
@ -0,0 +1,4 @@
|
||||
include README.rst
|
||||
include LICENSE
|
||||
include requirements.txt
|
||||
include discord/bin/*.dll
|
||||
@ -3,4 +3,12 @@
|
||||
## Red - Discord Bot v3
|
||||
|
||||
**This is alpha and very much a work in progress. Regular use is not recommended.
|
||||
There will not be any effort not to break current installations.**
|
||||
There will not be any effort not to break current installations.**
|
||||
|
||||
### How to install
|
||||
|
||||
Using python3 pip::
|
||||
|
||||
pip install --process-dependency-links -U git+https://github.com/Cog-Creators/Red-DiscordBot@V3/develop
|
||||
redbot-setup
|
||||
redbot <name>
|
||||
@ -1,40 +0,0 @@
|
||||
from core.config import Config
|
||||
from subprocess import run, PIPE
|
||||
from collections import namedtuple
|
||||
from main import determine_main_folder
|
||||
|
||||
__all__ = ["Config", "__version__"]
|
||||
version_info = namedtuple("VersionInfo", "major minor patch")
|
||||
|
||||
BASE_VERSION = version_info(3, 0, 0)
|
||||
|
||||
|
||||
def get_latest_version():
|
||||
main_folder = determine_main_folder()
|
||||
try:
|
||||
p = run(
|
||||
"git describe --abbrev=0 --tags".split(),
|
||||
stdout=PIPE,
|
||||
cwd=str(main_folder)
|
||||
)
|
||||
except FileNotFoundError:
|
||||
# No git
|
||||
return BASE_VERSION
|
||||
|
||||
if p.returncode != 0:
|
||||
return BASE_VERSION
|
||||
|
||||
stdout = p.stdout.strip().decode()
|
||||
if stdout.startswith("v"):
|
||||
numbers = stdout[1:].split('.')
|
||||
args = [0, 0, 0]
|
||||
for i in range(3):
|
||||
try:
|
||||
args[i] = int(numbers[i])
|
||||
except (IndexError, ValueError):
|
||||
args[i] = 0
|
||||
return version_info(*args)
|
||||
return BASE_VERSION
|
||||
|
||||
__version__ = get_latest_version()
|
||||
|
||||
@ -1,29 +1,31 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Discord Version check
|
||||
|
||||
import discord
|
||||
import sys
|
||||
|
||||
import discord
|
||||
|
||||
if discord.version_info.major < 1:
|
||||
print("You are not running the rewritten version of discord.py.\n\n"
|
||||
"In order to use Red v3 you MUST be running d.py version"
|
||||
" >= 1.0.0.")
|
||||
sys.exit(1)
|
||||
|
||||
from core.bot import Red, ExitCodes
|
||||
from core.cog_manager import CogManagerUI
|
||||
from core.data_manager import load_basic_configuration
|
||||
from core.global_checks import init_global_checks
|
||||
from core.events import init_events
|
||||
from core.sentry_setup import init_sentry_logging
|
||||
from core.cli import interactive_config, confirm, parse_cli_flags, ask_sentry
|
||||
from core.core_commands import Core
|
||||
from core.dev_commands import Dev
|
||||
from redbot.core.bot import Red, ExitCodes
|
||||
from redbot.core.cog_manager import CogManagerUI
|
||||
from redbot.core.data_manager import load_basic_configuration
|
||||
from redbot.core.global_checks import init_global_checks
|
||||
from redbot.core.events import init_events
|
||||
from redbot.core.sentry_setup import init_sentry_logging
|
||||
from redbot.core.cli import interactive_config, confirm, parse_cli_flags, ask_sentry
|
||||
from redbot.core.core_commands import Core
|
||||
from redbot.core.dev_commands import Dev
|
||||
import asyncio
|
||||
import logging.handlers
|
||||
import logging
|
||||
import os
|
||||
from pathlib import Path
|
||||
from warnings import warn
|
||||
|
||||
|
||||
#
|
||||
# Red - Discord Bot v3
|
||||
@ -58,7 +60,7 @@ def init_loggers(cli_flags):
|
||||
else:
|
||||
logger.setLevel(logging.WARNING)
|
||||
|
||||
from core.data_manager import core_data_path
|
||||
from redbot.core.data_manager import core_data_path
|
||||
logfile_path = core_data_path() / 'red.log'
|
||||
fhandler = logging.handlers.RotatingFileHandler(
|
||||
filename=str(logfile_path), encoding='utf-8', mode='a',
|
||||
@ -75,10 +77,6 @@ def init_loggers(cli_flags):
|
||||
return logger, sentry_logger
|
||||
|
||||
|
||||
def determine_main_folder() -> Path:
|
||||
return Path(os.path.dirname(__file__)).resolve()
|
||||
|
||||
|
||||
async def _get_prefix_and_token(red, indict):
|
||||
"""
|
||||
Again, please blame <@269933075037814786> for this.
|
||||
@ -90,48 +88,23 @@ async def _get_prefix_and_token(red, indict):
|
||||
indict['enable_sentry'] = await red.db.enable_sentry()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
cli_flags = parse_cli_flags()
|
||||
|
||||
if cli_flags.config:
|
||||
load_basic_configuration(Path(cli_flags.config).resolve())
|
||||
else:
|
||||
warn("Soon you will need to change the way you load the bot."
|
||||
" The new method of loading has yet to be decided upon but"
|
||||
" will be made clear in announcements from the support server"
|
||||
" and from documentation. Please see issue #938 for further"
|
||||
" discussion on this topic.",
|
||||
category=FutureWarning)
|
||||
import core.data_manager
|
||||
defaults = core.data_manager.basic_config_default.copy()
|
||||
defaults['DATA_PATH'] = str(determine_main_folder())
|
||||
defaults['CORE_PATH_APPEND'] = 'core/.data'
|
||||
defaults['COG_PATH_APPEND'] = 'cogs/.data'
|
||||
|
||||
core.data_manager.basic_config = defaults
|
||||
|
||||
def main():
|
||||
cli_flags = parse_cli_flags(sys.argv[1:])
|
||||
load_basic_configuration(cli_flags.instance_name)
|
||||
log, sentry_log = init_loggers(cli_flags)
|
||||
description = "Red v3 - Alpha"
|
||||
bot_dir = determine_main_folder()
|
||||
red = Red(cli_flags, description=description, pm_help=None,
|
||||
bot_dir=bot_dir)
|
||||
red = Red(cli_flags, description=description, pm_help=None)
|
||||
init_global_checks(red)
|
||||
init_events(red, cli_flags)
|
||||
|
||||
red.add_cog(Core())
|
||||
red.add_cog(CogManagerUI())
|
||||
|
||||
if cli_flags.dev:
|
||||
red.add_cog(Dev())
|
||||
|
||||
loop = asyncio.get_event_loop()
|
||||
tmp_data = {}
|
||||
loop.run_until_complete(_get_prefix_and_token(red, tmp_data))
|
||||
|
||||
token = os.environ.get("RED_TOKEN", tmp_data['token'])
|
||||
prefix = cli_flags.prefix or tmp_data['prefix']
|
||||
enable_sentry = tmp_data['enable_sentry']
|
||||
|
||||
if token is None or not prefix:
|
||||
if cli_flags.no_prompt is False:
|
||||
new_token = interactive_config(red, token_set=bool(token),
|
||||
@ -141,17 +114,10 @@ if __name__ == '__main__':
|
||||
else:
|
||||
log.critical("Token and prefix must be set in order to login.")
|
||||
sys.exit(1)
|
||||
|
||||
if enable_sentry is None:
|
||||
ask_sentry(red)
|
||||
|
||||
loop.run_until_complete(_get_prefix_and_token(red, tmp_data))
|
||||
|
||||
if tmp_data['enable_sentry']:
|
||||
init_sentry_logging(red, sentry_log)
|
||||
|
||||
init_sentry_logging(sentry_log)
|
||||
cleanup_tasks = True
|
||||
|
||||
try:
|
||||
loop.run_until_complete(red.start(token, bot=not cli_flags.not_bot))
|
||||
except discord.LoginFailure:
|
||||
@ -183,3 +149,7 @@ if __name__ == '__main__':
|
||||
gathered.exception()
|
||||
|
||||
sys.exit(red._shutdown_mode.value)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@ -1,12 +1,13 @@
|
||||
import discord
|
||||
from copy import copy
|
||||
from typing import Generator, Tuple, Iterable
|
||||
|
||||
import discord
|
||||
from redbot.core import Config
|
||||
from redbot.core.i18n import CogI18n
|
||||
from redbot.core.utils.chat_formatting import box
|
||||
from discord.ext import commands
|
||||
|
||||
from typing import Generator, Tuple, Iterable
|
||||
from core import Config
|
||||
from core.bot import Red
|
||||
from core.utils.chat_formatting import box
|
||||
from core.i18n import CogI18n
|
||||
from redbot.core.bot import Red
|
||||
from .alias_entry import AliasEntry
|
||||
|
||||
_ = CogI18n("Alias", __file__)
|
||||
@ -1,8 +1,8 @@
|
||||
from redbot.core import checks, bank
|
||||
from redbot.core.i18n import CogI18n
|
||||
from discord.ext import commands
|
||||
|
||||
from core import checks, bank
|
||||
from core.bot import Red # Only used for type hints
|
||||
from core.i18n import CogI18n
|
||||
from redbot.core.bot import Red # Only used for type hints
|
||||
|
||||
_ = CogI18n('Bank', __file__)
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
from core.bot import Red
|
||||
from redbot.core.bot import Red
|
||||
from .downloader import Downloader
|
||||
|
||||
|
||||
@ -1,24 +1,23 @@
|
||||
import os
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
from sys import path as syspath
|
||||
from typing import Tuple, Union
|
||||
|
||||
import discord
|
||||
from redbot.core import Config
|
||||
from redbot.core import checks
|
||||
from redbot.core.i18n import CogI18n
|
||||
from redbot.core.utils.chat_formatting import box
|
||||
from discord.ext import commands
|
||||
from pathlib import Path
|
||||
from sys import path as syspath
|
||||
|
||||
from core import Config
|
||||
from core.bot import Red
|
||||
from core import checks
|
||||
from core.utils.chat_formatting import box
|
||||
from core.i18n import CogI18n
|
||||
|
||||
from .repo_manager import RepoManager, Repo
|
||||
from .installable import Installable
|
||||
from .converters import RepoName, InstalledCog
|
||||
from .log import log
|
||||
from .errors import CloningError, ExistingGitRepo
|
||||
from redbot.core.bot import Red
|
||||
from .checks import install_agreement
|
||||
from .converters import RepoName, InstalledCog
|
||||
from .errors import CloningError, ExistingGitRepo
|
||||
from .installable import Installable
|
||||
from .log import log
|
||||
from .repo_manager import RepoManager, Repo
|
||||
|
||||
_ = CogI18n('Downloader', __file__)
|
||||
|
||||
@ -1,23 +1,22 @@
|
||||
import asyncio
|
||||
import json
|
||||
import functools
|
||||
import os
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
from pathlib import Path
|
||||
from typing import Tuple, MutableMapping, Union
|
||||
from subprocess import run as sp_run, PIPE
|
||||
from sys import executable
|
||||
import pkgutil
|
||||
import shutil
|
||||
import functools
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
from pathlib import Path
|
||||
from subprocess import run as sp_run, PIPE
|
||||
from sys import executable
|
||||
from typing import Tuple, MutableMapping, Union
|
||||
|
||||
from discord.ext import commands
|
||||
|
||||
from core import Config
|
||||
from core import data_manager
|
||||
from redbot.core import Config
|
||||
from redbot.core import data_manager
|
||||
from .errors import *
|
||||
from .installable import Installable, InstallableType
|
||||
from .log import log
|
||||
from .json_mixins import RepoJSONMixin
|
||||
from .log import log
|
||||
|
||||
|
||||
class Repo(RepoJSONMixin):
|
||||
@ -1,5 +1,5 @@
|
||||
from redbot.core.bot import Red
|
||||
from .economy import Economy
|
||||
from core.bot import Red
|
||||
|
||||
|
||||
def setup(bot: Red):
|
||||
@ -5,12 +5,14 @@ from collections import defaultdict, deque
|
||||
from enum import Enum
|
||||
|
||||
import discord
|
||||
|
||||
from redbot.cogs.bank import check_global_setting_guildowner, check_global_setting_admin
|
||||
from redbot.core import Config, bank
|
||||
from redbot.core.i18n import CogI18n
|
||||
from redbot.core.utils.chat_formatting import pagify, box
|
||||
from discord.ext import commands
|
||||
from core import checks, Config, bank
|
||||
from core.utils.chat_formatting import pagify, box
|
||||
from core.bot import Red
|
||||
from cogs.bank import check_global_setting_guildowner, check_global_setting_admin
|
||||
from core.i18n import CogI18n
|
||||
|
||||
from redbot.core.bot import Red
|
||||
|
||||
_ = CogI18n("Economy", __file__)
|
||||
|
||||
@ -1,13 +1,15 @@
|
||||
from discord.ext import commands
|
||||
from core.utils.chat_formatting import escape, italics, pagify
|
||||
from core.i18n import CogI18n
|
||||
from random import randint, choice
|
||||
from enum import Enum
|
||||
from urllib.parse import quote_plus
|
||||
import discord
|
||||
import datetime
|
||||
import time
|
||||
from enum import Enum
|
||||
from random import randint, choice
|
||||
from urllib.parse import quote_plus
|
||||
|
||||
import aiohttp
|
||||
import discord
|
||||
from redbot.core.i18n import CogI18n
|
||||
from discord.ext import commands
|
||||
|
||||
from redbot.core.utils.chat_formatting import escape, italics, pagify
|
||||
|
||||
_ = CogI18n("General", __file__)
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
from discord.ext import commands
|
||||
from random import shuffle
|
||||
import aiohttp
|
||||
|
||||
from core import checks, Config
|
||||
from core.i18n import CogI18n
|
||||
import aiohttp
|
||||
from discord.ext import commands
|
||||
|
||||
from redbot.core.i18n import CogI18n
|
||||
from redbot.core import checks, Config
|
||||
|
||||
_ = CogI18n("Image", __file__)
|
||||
|
||||
7
redbot/core/__init__.py
Normal file
7
redbot/core/__init__.py
Normal file
@ -0,0 +1,7 @@
|
||||
import pkg_resources
|
||||
|
||||
from .config import Config
|
||||
|
||||
__all__ = ["Config", "__version__"]
|
||||
|
||||
__version__ = version = pkg_resources.require("Red-DiscordBot")[0].version
|
||||
@ -1,10 +1,10 @@
|
||||
import datetime
|
||||
from typing import Union, List
|
||||
import os
|
||||
from typing import Union, List
|
||||
|
||||
import discord
|
||||
|
||||
from core import Config
|
||||
from redbot.core import Config
|
||||
|
||||
__all__ = ["Account", "get_balance", "set_balance", "withdraw_credits", "deposit_credits",
|
||||
"can_spend", "transfer_credits", "wipe_bank", "get_guild_accounts",
|
||||
@ -1,19 +1,17 @@
|
||||
import asyncio
|
||||
import os
|
||||
from collections import Counter
|
||||
from enum import Enum
|
||||
from importlib.machinery import ModuleSpec
|
||||
from pathlib import Path
|
||||
|
||||
import discord
|
||||
from discord.ext import commands
|
||||
from collections import Counter
|
||||
|
||||
from discord.ext.commands import GroupMixin
|
||||
from pathlib import Path
|
||||
|
||||
from core import Config
|
||||
from enum import Enum
|
||||
import os
|
||||
|
||||
from core.cog_manager import CogManager
|
||||
from core import i18n
|
||||
from .cog_manager import CogManager
|
||||
from . import Config
|
||||
from . import i18n
|
||||
|
||||
|
||||
class Red(commands.Bot):
|
||||
@ -66,8 +64,7 @@ class Red(commands.Bot):
|
||||
|
||||
self.main_dir = bot_dir
|
||||
|
||||
self.cog_mgr = CogManager(paths=(str(self.main_dir / 'cogs'),),
|
||||
bot_dir=self.main_dir)
|
||||
self.cog_mgr = CogManager(paths=(str(self.main_dir / 'cogs'),))
|
||||
|
||||
super().__init__(**kwargs)
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import argparse
|
||||
import asyncio
|
||||
|
||||
from core.bot import Red
|
||||
from redbot.core.bot import Red
|
||||
|
||||
|
||||
def confirm(m=""):
|
||||
@ -61,7 +61,7 @@ def ask_sentry(red: Red):
|
||||
print("\nThank you for helping us with the development process!")
|
||||
|
||||
|
||||
def parse_cli_flags():
|
||||
def parse_cli_flags(args):
|
||||
parser = argparse.ArgumentParser(description="Red - Discord Bot")
|
||||
parser.add_argument("--owner", type=int,
|
||||
help="ID of the owner. Only who hosts "
|
||||
@ -102,11 +102,10 @@ def parse_cli_flags():
|
||||
parser.add_argument("--dev",
|
||||
action="store_true",
|
||||
help="Enables developer mode")
|
||||
parser.add_argument("config",
|
||||
nargs='?',
|
||||
help="Path to config generated on initial setup.")
|
||||
parser.add_argument("instance_name",
|
||||
help="Name of the bot instance created during `redbot-setup`.")
|
||||
|
||||
args = parser.parse_args()
|
||||
args = parser.parse_args(args)
|
||||
|
||||
if args.prefix:
|
||||
args.prefix = sorted(args.prefix, reverse=True)
|
||||
@ -1,15 +1,16 @@
|
||||
import pkgutil
|
||||
from importlib import invalidate_caches
|
||||
from importlib.machinery import ModuleSpec
|
||||
from typing import Tuple, Union, List
|
||||
from pathlib import Path
|
||||
from typing import Tuple, Union, List
|
||||
|
||||
from . import checks
|
||||
from .config import Config
|
||||
from .i18n import CogI18n
|
||||
from .data_manager import cog_data_path
|
||||
from discord.ext import commands
|
||||
|
||||
from core import checks
|
||||
from core.config import Config
|
||||
from core.utils.chat_formatting import box
|
||||
from core.i18n import CogI18n
|
||||
from .utils.chat_formatting import box
|
||||
|
||||
__all__ = ["CogManager"]
|
||||
|
||||
@ -20,11 +21,13 @@ class CogManager:
|
||||
directory. You may also set a directory for downloader to install new cogs to, the default
|
||||
being the :code:`cogs/` folder in the root bot directory.
|
||||
"""
|
||||
def __init__(self, paths: Tuple[str]=(), bot_dir: Path=Path.cwd()):
|
||||
def __init__(self, paths: Tuple[str]=()):
|
||||
self.conf = Config.get_conf(self, 2938473984732, True)
|
||||
tmp_cog_install_path = cog_data_path(self) / "cogs"
|
||||
tmp_cog_install_path.mkdir(parents=True, exist_ok=True)
|
||||
self.conf.register_global(
|
||||
paths=(),
|
||||
install_path=str(bot_dir.resolve() / "cogs")
|
||||
install_path=str(tmp_cog_install_path)
|
||||
)
|
||||
|
||||
self._paths = list(paths)
|
||||
@ -1,14 +1,11 @@
|
||||
import logging
|
||||
|
||||
from copy import deepcopy
|
||||
from typing import Callable, Union, Tuple
|
||||
|
||||
import discord
|
||||
from copy import deepcopy
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from .data_manager import cog_data_path, core_data_path
|
||||
from .drivers.red_json import JSON as JSONDriver
|
||||
from core.data_manager import cog_data_path, core_data_path
|
||||
|
||||
log = logging.getLogger("red.config")
|
||||
|
||||
@ -1,16 +1,20 @@
|
||||
import itertools
|
||||
from discord.ext import commands
|
||||
from core import checks
|
||||
from core import i18n
|
||||
from string import ascii_letters, digits
|
||||
from random import SystemRandom
|
||||
from collections import namedtuple
|
||||
import logging
|
||||
import importlib
|
||||
import sys
|
||||
import discord
|
||||
import aiohttp
|
||||
import asyncio
|
||||
import importlib
|
||||
import itertools
|
||||
import logging
|
||||
import sys
|
||||
from collections import namedtuple
|
||||
from random import SystemRandom
|
||||
from string import ascii_letters, digits
|
||||
|
||||
import aiohttp
|
||||
import discord
|
||||
from discord.ext import commands
|
||||
|
||||
from redbot.core import checks
|
||||
from redbot.core import i18n
|
||||
|
||||
import redbot.cogs # Don't remove this line or core cogs won't load
|
||||
|
||||
log = logging.getLogger("red")
|
||||
|
||||
@ -32,9 +36,14 @@ class Core:
|
||||
try:
|
||||
spec = await ctx.bot.cog_mgr.find_cog(cog_name)
|
||||
except RuntimeError:
|
||||
await ctx.send(_("No module by that name was found in any"
|
||||
" cog path."))
|
||||
return
|
||||
real_name = ".{}".format(cog_name)
|
||||
try:
|
||||
mod = importlib.import_module(real_name, package='redbot.cogs')
|
||||
except ImportError as e:
|
||||
await ctx.send(_("No module by that name was found in any"
|
||||
" cog path."))
|
||||
return
|
||||
spec = mod.__spec__
|
||||
|
||||
try:
|
||||
ctx.bot.load_extension(spec)
|
||||
@ -335,7 +344,8 @@ class Core:
|
||||
# Since it can also be set through cli flags, bot.db is not a reliable
|
||||
# source. So we'll just mock a DM message instead.
|
||||
fake_message = namedtuple('Message', 'guild')
|
||||
prefix = ctx.bot.command_prefix(ctx.bot, fake_message(guild=None))[0]
|
||||
prefixes = await ctx.bot.command_prefix(ctx.bot, fake_message(guild=None))
|
||||
prefix = prefixes[0]
|
||||
|
||||
content = _("Use `{}dm {} <text>` to reply to this user"
|
||||
"").format(prefix, author.id)
|
||||
@ -384,7 +394,8 @@ class Core:
|
||||
e = discord.Embed(colour=discord.Colour.red(), description=message)
|
||||
description = _("Owner of %s") % ctx.bot.user
|
||||
fake_message = namedtuple('Message', 'guild')
|
||||
prefix = ctx.bot.command_prefix(ctx.bot, fake_message(guild=None))[0]
|
||||
prefixes = await ctx.bot.command_prefix(ctx.bot, fake_message(guild=None))
|
||||
prefix = prefixes[0]
|
||||
e.set_footer(text=_("You can reply to this message with %scontact"
|
||||
"") % prefix)
|
||||
if ctx.bot.user.avatar_url:
|
||||
@ -1,6 +1,9 @@
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
from core.json_io import JsonIO
|
||||
import appdirs
|
||||
|
||||
from .json_io import JsonIO
|
||||
|
||||
jsonio = None
|
||||
basic_config = None
|
||||
@ -11,13 +14,23 @@ basic_config_default = {
|
||||
"CORE_PATH_APPEND": "core"
|
||||
}
|
||||
|
||||
config_dir = Path(appdirs.AppDirs("Red-DiscordBot").user_config_dir)
|
||||
config_file = config_dir / 'config.json'
|
||||
|
||||
def load_basic_configuration(path: Path):
|
||||
|
||||
def load_basic_configuration(instance_name: str):
|
||||
global jsonio
|
||||
global basic_config
|
||||
|
||||
jsonio = JsonIO(path)
|
||||
basic_config = jsonio._load_json()
|
||||
jsonio = JsonIO(config_file)
|
||||
|
||||
try:
|
||||
config = jsonio._load_json()
|
||||
basic_config = config[instance_name]
|
||||
except (FileNotFoundError, KeyError):
|
||||
print("You need to configure the bot instance using `redbot-setup`"
|
||||
" prior to running the bot.")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def _base_data_path() -> Path:
|
||||
@ -1,15 +1,16 @@
|
||||
from discord.ext import commands
|
||||
from core.utils.chat_formatting import box, pagify
|
||||
from core import checks
|
||||
from core.i18n import CogI18n
|
||||
import asyncio
|
||||
import discord
|
||||
import traceback
|
||||
import inspect
|
||||
import textwrap
|
||||
from contextlib import redirect_stdout
|
||||
import io
|
||||
import textwrap
|
||||
import traceback
|
||||
from contextlib import redirect_stdout
|
||||
|
||||
import discord
|
||||
from . import checks
|
||||
from .i18n import CogI18n
|
||||
from discord.ext import commands
|
||||
|
||||
from .utils.chat_formatting import box, pagify
|
||||
|
||||
"""
|
||||
Notice:
|
||||
@ -1,9 +1,9 @@
|
||||
from pathlib import Path
|
||||
from typing import Tuple
|
||||
|
||||
from core.drivers.red_base import BaseDriver
|
||||
from core.json_io import JsonIO
|
||||
from ..json_io import JsonIO
|
||||
|
||||
from pathlib import Path
|
||||
from .red_base import BaseDriver
|
||||
|
||||
|
||||
class JSON(BaseDriver):
|
||||
@ -1,10 +1,12 @@
|
||||
import discord
|
||||
import traceback
|
||||
import datetime
|
||||
import logging
|
||||
import traceback
|
||||
|
||||
import discord
|
||||
from .sentry_setup import should_log
|
||||
from discord.ext import commands
|
||||
from core.utils.chat_formatting import inline
|
||||
from core.sentry_setup import should_log
|
||||
|
||||
from .utils.chat_formatting import inline
|
||||
|
||||
log = logging.getLogger("red")
|
||||
sentry_log = logging.getLogger("red.sentry")
|
||||
0
redbot/core/locales/__init__.py
Normal file
0
redbot/core/locales/__init__.py
Normal file
@ -1,9 +1,7 @@
|
||||
from raven import Client, breadcrumbs
|
||||
from raven.versioning import fetch_git_sha
|
||||
from raven.conf import setup_logging
|
||||
from raven.handlers.logging import SentryHandler
|
||||
|
||||
from pathlib import Path
|
||||
from redbot.core import __version__
|
||||
|
||||
__all__ = ("init_sentry_logging", "should_log")
|
||||
|
||||
@ -27,12 +25,12 @@ include_paths = (
|
||||
client = None
|
||||
|
||||
|
||||
def init_sentry_logging(bot, logger):
|
||||
def init_sentry_logging(logger):
|
||||
global client
|
||||
client = Client(
|
||||
dsn=("https://27f3915ba0144725a53ea5a99c9ae6f3:87913fb5d0894251821dcf06e5e9cfe6@"
|
||||
"sentry.telemetry.red/19?verify_ssl=0"),
|
||||
release=fetch_git_sha(str(bot.main_dir))
|
||||
release=__version__
|
||||
)
|
||||
|
||||
breadcrumbs.ignore_logger("websockets")
|
||||
0
redbot/core/utils/__init__.py
Normal file
0
redbot/core/utils/__init__.py
Normal file
107
redbot/setup.py
Normal file
107
redbot/setup.py
Normal file
@ -0,0 +1,107 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
from copy import deepcopy
|
||||
from pathlib import Path
|
||||
|
||||
import appdirs
|
||||
|
||||
from redbot.core.json_io import JsonIO
|
||||
from redbot.core.data_manager import basic_config_default
|
||||
from redbot.core.cli import confirm
|
||||
|
||||
appdir = appdirs.AppDirs("Red-DiscordBot")
|
||||
config_dir = Path(appdir.user_config_dir)
|
||||
config_dir.mkdir(parents=True, exist_ok=True)
|
||||
config_file = config_dir / 'config.json'
|
||||
|
||||
|
||||
def load_existing_config():
|
||||
if not config_file.exists():
|
||||
return {}
|
||||
|
||||
return JsonIO(config_file)._load_json()
|
||||
|
||||
|
||||
def save_config(name, data):
|
||||
config = load_existing_config()
|
||||
config[name] = data
|
||||
JsonIO(config_file)._save_json(config)
|
||||
|
||||
|
||||
def basic_setup():
|
||||
"""
|
||||
Creates the data storage folder.
|
||||
:return:
|
||||
"""
|
||||
|
||||
default_data_dir = Path(appdir.user_data_dir)
|
||||
|
||||
print("Hello! Before we begin the full configuration process we need to"
|
||||
" gather some initial information about where you'd like us"
|
||||
" to store your bot's data. We've attempted to figure out a"
|
||||
" sane default data location which is printed below. If you don't"
|
||||
" want to change this default please press [ENTER], otherwise"
|
||||
" input your desired data location.")
|
||||
print()
|
||||
print("Default: {}".format(default_data_dir))
|
||||
|
||||
new_path = input('> ')
|
||||
|
||||
if new_path != '':
|
||||
new_path = Path(new_path)
|
||||
default_data_dir = new_path
|
||||
|
||||
if not default_data_dir.exists():
|
||||
try:
|
||||
default_data_dir.mkdir(parents=True, exist_ok=True)
|
||||
except OSError:
|
||||
print("We were unable to create your chosen directory."
|
||||
" You may need to restart this process with admin"
|
||||
" privileges.")
|
||||
sys.exit(1)
|
||||
|
||||
print("You have chosen {} to be your data directory."
|
||||
"".format(default_data_dir))
|
||||
if not confirm("Please confirm (y/n):"):
|
||||
print("Please start the process over.")
|
||||
sys.exit(0)
|
||||
|
||||
default_dirs = deepcopy(basic_config_default)
|
||||
default_dirs['DATA_PATH'] = str(default_data_dir.resolve())
|
||||
|
||||
storage_dict = {
|
||||
1: "JSON",
|
||||
2: "MongoDB"
|
||||
}
|
||||
storage = None
|
||||
while storage is None:
|
||||
print()
|
||||
print("Please choose your storage backend (if you're unsure, choose 1).")
|
||||
print("1. JSON (file storage, requires no database).")
|
||||
print("2. MongoDB")
|
||||
storage = input("> ")
|
||||
try:
|
||||
storage = int(storage)
|
||||
except ValueError:
|
||||
storage = None
|
||||
else:
|
||||
if storage not in storage_dict:
|
||||
storage = None
|
||||
|
||||
default_dirs['STORAGE_TYPE'] = storage_dict[storage]
|
||||
|
||||
name = ""
|
||||
while len(name) == 0:
|
||||
print()
|
||||
print("Please enter a name for your instance, this name cannot include spaces"
|
||||
" and it will be used to run your bot from here on out.")
|
||||
name = input("> ")
|
||||
if " " in name:
|
||||
name = ""
|
||||
|
||||
save_config(name, default_dirs)
|
||||
|
||||
print()
|
||||
print("Your basic configuration has been saved. Please run `redbot <name>` to"
|
||||
" continue your setup process and to run the bot.")
|
||||
@ -1,6 +1,4 @@
|
||||
git+https://github.com/Rapptz/discord.py@rewrite#egg=discord.py[voice]
|
||||
appdirs
|
||||
discord.py>=1.0.0a0
|
||||
youtube_dl
|
||||
pytest
|
||||
git+https://github.com/pytest-dev/pytest-asyncio
|
||||
pymongo
|
||||
git+https://github.com/getsentry/raven-python
|
||||
raven
|
||||
111
setup.py
Normal file
111
setup.py
Normal file
@ -0,0 +1,111 @@
|
||||
from distutils.core import setup
|
||||
from pathlib import Path
|
||||
from subprocess import run, PIPE
|
||||
|
||||
from setuptools import find_packages
|
||||
|
||||
|
||||
def get_package_list():
|
||||
core = find_packages(include=['redbot', 'redbot.*'])
|
||||
return core
|
||||
|
||||
|
||||
def get_requirements():
|
||||
with open('requirements.txt') as f:
|
||||
requirements = f.read().splitlines()
|
||||
return requirements
|
||||
|
||||
|
||||
def get_version():
|
||||
try:
|
||||
p = run(
|
||||
"git describe --abbrev=0 --tags".split(),
|
||||
stdout=PIPE
|
||||
)
|
||||
except FileNotFoundError:
|
||||
# No git
|
||||
return 3, 0, 0
|
||||
|
||||
if p.returncode != 0:
|
||||
return 3, 0, 0
|
||||
|
||||
stdout = p.stdout.strip().decode()
|
||||
if stdout.startswith("v"):
|
||||
numbers = stdout[1:].split('.')
|
||||
args = [0, 0, 0]
|
||||
for i in range(3):
|
||||
try:
|
||||
args[i] = int(numbers[i])
|
||||
except (IndexError, ValueError):
|
||||
args[i] = 0
|
||||
return args
|
||||
return 3, 0, 0
|
||||
|
||||
|
||||
def find_locale_folders():
|
||||
"""
|
||||
Ignore this tomfoolery in the desire for automation. It works, that's
|
||||
all you gotta know. Don't fuck with this unless you really know what
|
||||
you're doing, otherwise we lose all translations.
|
||||
"""
|
||||
def glob_locale_files(path: Path):
|
||||
msgs = path.glob("*.po")
|
||||
|
||||
parents = path.parents
|
||||
|
||||
return [str(m.relative_to(parents[0])) for m in msgs]
|
||||
|
||||
ret = {
|
||||
'redbot.core': glob_locale_files(Path('redbot/core/locales'))
|
||||
}
|
||||
|
||||
cogs_path = Path('redbot/cogs')
|
||||
|
||||
for cog_folder in cogs_path.iterdir():
|
||||
locales_folder = cog_folder / 'locales'
|
||||
if not locales_folder.is_dir():
|
||||
continue
|
||||
|
||||
pkg_name = str(cog_folder).replace('/', '.')
|
||||
ret[pkg_name] = glob_locale_files(locales_folder)
|
||||
|
||||
return ret
|
||||
|
||||
setup(
|
||||
name='Red-DiscordBot',
|
||||
version="{}.{}.{}a13".format(*get_version()),
|
||||
packages=get_package_list(),
|
||||
package_data=find_locale_folders(),
|
||||
url='https://github.com/Cog-Creators/Red-DiscordBot',
|
||||
license='GPLv3',
|
||||
author='Cog-Creators',
|
||||
author_email='',
|
||||
description='A highly customizable Discord bot',
|
||||
classifiers=[
|
||||
'Development Status :: 4 - Beta',
|
||||
'Framework :: AsyncIO',
|
||||
'Intended Audience :: Developers',
|
||||
'License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)',
|
||||
'Operating System :: OS Independent',
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Topic :: Communications :: Chat',
|
||||
'Topic :: Documentation :: Sphinx'
|
||||
],
|
||||
entry_points={
|
||||
'console_scripts': [
|
||||
'redbot=redbot.__main__:main',
|
||||
'redbot-setup=redbot.setup:basic_setup']
|
||||
},
|
||||
python_requires='>=3.5',
|
||||
setup_requires=get_requirements(),
|
||||
install_requires=get_requirements(),
|
||||
dependency_links=[
|
||||
'https://github.com/Rapptz/discord.py/tarball/rewrite#egg=discord.py-1.0'
|
||||
],
|
||||
extras_require={
|
||||
'test': ['pytest>=3', 'pytest-asyncio'],
|
||||
'mongo': ['pymongo', 'motor'],
|
||||
'docs': ['sphinx', 'sphinxcontrib-asyncio', 'sphinx_rtd_theme']
|
||||
}
|
||||
)
|
||||
@ -1,9 +1,10 @@
|
||||
from collections import namedtuple
|
||||
from raven.versioning import fetch_git_sha
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
from cogs.downloader.repo_manager import RepoManager, Repo
|
||||
from pathlib import Path
|
||||
from raven.versioning import fetch_git_sha
|
||||
|
||||
from redbot.cogs.downloader.repo_manager import RepoManager, Repo
|
||||
|
||||
|
||||
async def fake_run(*args, **kwargs):
|
||||
@ -37,8 +38,6 @@ def repo_manager(tmpdir_factory, config):
|
||||
|
||||
@pytest.fixture
|
||||
def repo(tmpdir):
|
||||
from cogs.downloader.repo_manager import Repo
|
||||
|
||||
repo_folder = Path(str(tmpdir)) / 'repos' / 'squid'
|
||||
repo_folder.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
@ -69,8 +68,6 @@ def bot_repo(event_loop):
|
||||
|
||||
|
||||
def test_existing_git_repo(tmpdir):
|
||||
from cogs.downloader.repo_manager import Repo
|
||||
|
||||
repo_folder = Path(str(tmpdir)) / 'repos' / 'squid' / '.git'
|
||||
repo_folder.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
@ -103,7 +100,7 @@ async def test_clone_repo(repo_norun, capsys):
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_add_repo(monkeypatch, repo_manager):
|
||||
monkeypatch.setattr("cogs.downloader.repo_manager.Repo._run",
|
||||
monkeypatch.setattr("redbot.cogs.downloader.repo_manager.Repo._run",
|
||||
fake_run_noprint)
|
||||
|
||||
squid = await repo_manager.add_repo(
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
import pytest
|
||||
import json
|
||||
|
||||
from cogs.downloader.installable import Installable, InstallableType
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from redbot.cogs.downloader.installable import Installable, InstallableType
|
||||
|
||||
INFO_JSON = {
|
||||
"author": (
|
||||
"tekulvw",
|
||||
|
||||
@ -1,12 +1,13 @@
|
||||
from cogs.alias import Alias
|
||||
import pytest
|
||||
|
||||
from redbot.cogs.alias import Alias
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def alias(config):
|
||||
import cogs.alias.alias
|
||||
import redbot.cogs.alias.alias
|
||||
|
||||
cogs.alias.alias.Config.get_conf = lambda *args, **kwargs: config
|
||||
redbot.cogs.alias.alias.Config.get_conf = lambda *args, **kwargs: config
|
||||
|
||||
return Alias(None)
|
||||
|
||||
|
||||
@ -3,10 +3,10 @@ import pytest
|
||||
|
||||
@pytest.fixture()
|
||||
def bank(config):
|
||||
from core import Config
|
||||
from redbot.core import Config
|
||||
Config.get_conf = lambda *args, **kwargs: config
|
||||
|
||||
from core import bank
|
||||
from redbot.core import bank
|
||||
bank._register_defaults()
|
||||
return bank
|
||||
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
import random
|
||||
from collections import namedtuple
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
import random
|
||||
|
||||
from core.bot import Red
|
||||
from _pytest.monkeypatch import MonkeyPatch
|
||||
from core.drivers import red_json
|
||||
from core import Config
|
||||
from redbot.core import Config
|
||||
from redbot.core.bot import Red
|
||||
|
||||
from redbot.core.drivers import red_json
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
@ -19,7 +19,7 @@ def monkeysession(request):
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def override_data_path(tmpdir):
|
||||
from core import data_manager
|
||||
from redbot.core import data_manager
|
||||
data_manager.basic_config = data_manager.basic_config_default
|
||||
data_manager.basic_config['DATA_PATH'] = str(tmpdir)
|
||||
|
||||
@ -145,8 +145,8 @@ def ctx(empty_member, empty_channel, red):
|
||||
#region Red Mock
|
||||
@pytest.fixture()
|
||||
def red(config_fr):
|
||||
from core.cli import parse_cli_flags
|
||||
cli_flags = parse_cli_flags()
|
||||
from redbot.core.cli import parse_cli_flags
|
||||
cli_flags = parse_cli_flags(["ignore_me"])
|
||||
|
||||
description = "Red v3 - Alpha"
|
||||
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
from core import cog_manager
|
||||
|
||||
from redbot.core import cog_manager
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
@ -14,9 +15,10 @@ def default_dir(red):
|
||||
return red.main_dir
|
||||
|
||||
|
||||
@pytest.mark.skip
|
||||
@pytest.mark.asyncio
|
||||
async def test_ensure_cogs_in_paths(cog_mgr, default_dir):
|
||||
cogs_dir = default_dir / 'cogs'
|
||||
cogs_dir = default_dir / 'redbot' / 'cogs'
|
||||
assert cogs_dir in await cog_mgr.paths()
|
||||
|
||||
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
from core import data_manager
|
||||
import pytest
|
||||
|
||||
from redbot.core import data_manager
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def cleanup_datamanager():
|
||||
@ -32,6 +33,7 @@ def test_no_basic(cog_instance):
|
||||
data_manager.cog_data_path(cog_instance)
|
||||
|
||||
|
||||
@pytest.mark.skip
|
||||
def test_core_path(data_mgr_config, tmpdir):
|
||||
conf_path = tmpdir.join('config.json')
|
||||
conf_path.write(json.dumps(data_mgr_config))
|
||||
|
||||
@ -1,10 +1,11 @@
|
||||
from core import sentry_setup
|
||||
import logging
|
||||
|
||||
from redbot.core import sentry_setup
|
||||
|
||||
|
||||
def test_sentry_capture(red):
|
||||
log = logging.getLogger(__name__)
|
||||
sentry_setup.init_sentry_logging(red, log)
|
||||
sentry_setup.init_sentry_logging(log)
|
||||
|
||||
assert sentry_setup.client is not None
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import core
|
||||
from redbot import core
|
||||
|
||||
|
||||
def test_version_working():
|
||||
assert hasattr(core, '__version__')
|
||||
assert core.__version__ >= (3, 0, 0)
|
||||
assert core.__version__[0] == "3"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user