mirror of
https://github.com/Cog-Creators/Red-DiscordBot.git
synced 2025-11-09 04:38:55 -05:00
Merge changes for RC1 into V3/develop
This commit is contained in:
commit
748847d5bf
@ -28,7 +28,7 @@ jobs:
|
|||||||
- python: 3.6.6
|
- python: 3.6.6
|
||||||
env: TOXENV=style
|
env: TOXENV=style
|
||||||
|
|
||||||
# These jobs only occur on tag creation for V3/develop if the prior ones succeed
|
# These jobs only occur on tag creation if the prior ones succeed
|
||||||
- stage: PyPi Deployment
|
- stage: PyPi Deployment
|
||||||
if: tag IS present
|
if: tag IS present
|
||||||
python: 3.6.6
|
python: 3.6.6
|
||||||
@ -42,7 +42,6 @@ jobs:
|
|||||||
skip_cleanup: true
|
skip_cleanup: true
|
||||||
on:
|
on:
|
||||||
repo: Cog-Creators/Red-DiscordBot
|
repo: Cog-Creators/Red-DiscordBot
|
||||||
branch: V3/develop
|
|
||||||
python: 3.6.6
|
python: 3.6.6
|
||||||
tags: true
|
tags: true
|
||||||
- stage: Crowdin Deployment
|
- stage: Crowdin Deployment
|
||||||
@ -62,6 +61,5 @@ jobs:
|
|||||||
skip_cleanup: true
|
skip_cleanup: true
|
||||||
on:
|
on:
|
||||||
repo: Cog-Creators/Red-DiscordBot
|
repo: Cog-Creators/Red-DiscordBot
|
||||||
branch: V3/develop
|
|
||||||
python: 3.6.6
|
python: 3.6.6
|
||||||
tags: true
|
tags: true
|
||||||
|
|||||||
@ -359,7 +359,7 @@ class Admin(commands.Cog):
|
|||||||
selfroles = await self._valid_selfroles(ctx.guild)
|
selfroles = await self._valid_selfroles(ctx.guild)
|
||||||
fmt_selfroles = "\n".join(["+ " + r.name for r in selfroles])
|
fmt_selfroles = "\n".join(["+ " + r.name for r in selfroles])
|
||||||
|
|
||||||
msg = _("Available Selfroles: {selfroles}").format(selfroles=fmt_selfroles)
|
msg = _("Available Selfroles:\n{selfroles}").format(selfroles=fmt_selfroles)
|
||||||
await ctx.send(box(msg, "diff"))
|
await ctx.send(box(msg, "diff"))
|
||||||
|
|
||||||
async def _serverlock_check(self, guild: discord.Guild) -> bool:
|
async def _serverlock_check(self, guild: discord.Guild) -> bool:
|
||||||
|
|||||||
@ -34,7 +34,7 @@ async def download_lavalink(session):
|
|||||||
|
|
||||||
async def maybe_download_lavalink(loop, cog):
|
async def maybe_download_lavalink(loop, cog):
|
||||||
jar_exists = LAVALINK_JAR_FILE.exists()
|
jar_exists = LAVALINK_JAR_FILE.exists()
|
||||||
current_build = redbot.core.VersionInfo(*await cog.config.current_build())
|
current_build = redbot.core.VersionInfo.from_json(await cog.config.current_build())
|
||||||
|
|
||||||
if not jar_exists or current_build < redbot.core.version_info:
|
if not jar_exists or current_build < redbot.core.version_info:
|
||||||
log.info("Downloading Lavalink.jar")
|
log.info("Downloading Lavalink.jar")
|
||||||
|
|||||||
@ -253,7 +253,9 @@ class Audio(commands.Cog):
|
|||||||
|
|
||||||
dj_enabled = await self.config.guild(ctx.guild).dj_enabled()
|
dj_enabled = await self.config.guild(ctx.guild).dj_enabled()
|
||||||
await self.config.guild(ctx.guild).dj_enabled.set(not dj_enabled)
|
await self.config.guild(ctx.guild).dj_enabled.set(not dj_enabled)
|
||||||
await self._embed_msg(ctx, "DJ role enabled: {}.".format(not dj_enabled))
|
await self._embed_msg(
|
||||||
|
ctx, _("DJ role enabled: {true_or_false}.".format(true_or_false=not dj_enabled))
|
||||||
|
)
|
||||||
|
|
||||||
@audioset.command()
|
@audioset.command()
|
||||||
@checks.mod_or_permissions(administrator=True)
|
@checks.mod_or_permissions(administrator=True)
|
||||||
@ -332,7 +334,7 @@ class Audio(commands.Cog):
|
|||||||
jarbuild = redbot.core.__version__
|
jarbuild = redbot.core.__version__
|
||||||
|
|
||||||
vote_percent = data["vote_percent"]
|
vote_percent = data["vote_percent"]
|
||||||
msg = "----" + _("Server Settings") + "----"
|
msg = "----" + _("Server Settings") + "----\n"
|
||||||
if emptydc_enabled:
|
if emptydc_enabled:
|
||||||
msg += _("Disconnect timer: [{num_seconds}]\n").format(
|
msg += _("Disconnect timer: [{num_seconds}]\n").format(
|
||||||
num_seconds=self._dynamic_time(emptydc_timer)
|
num_seconds=self._dynamic_time(emptydc_timer)
|
||||||
@ -370,7 +372,9 @@ class Audio(commands.Cog):
|
|||||||
"""Toggle displaying a thumbnail on audio messages."""
|
"""Toggle displaying a thumbnail on audio messages."""
|
||||||
thumbnail = await self.config.guild(ctx.guild).thumbnail()
|
thumbnail = await self.config.guild(ctx.guild).thumbnail()
|
||||||
await self.config.guild(ctx.guild).thumbnail.set(not thumbnail)
|
await self.config.guild(ctx.guild).thumbnail.set(not thumbnail)
|
||||||
await self._embed_msg(ctx, _("Thumbnail display: {}.").format(not thumbnail))
|
await self._embed_msg(
|
||||||
|
ctx, _("Thumbnail display: {true_or_false}.").format(true_or_false=not thumbnail)
|
||||||
|
)
|
||||||
|
|
||||||
@audioset.command()
|
@audioset.command()
|
||||||
@checks.mod_or_permissions(administrator=True)
|
@checks.mod_or_permissions(administrator=True)
|
||||||
@ -565,6 +569,8 @@ class Audio(commands.Cog):
|
|||||||
if dj_enabled:
|
if dj_enabled:
|
||||||
if not await self._can_instaskip(ctx, ctx.author):
|
if not await self._can_instaskip(ctx, ctx.author):
|
||||||
return await menu(ctx, folder_page_list, DEFAULT_CONTROLS)
|
return await menu(ctx, folder_page_list, DEFAULT_CONTROLS)
|
||||||
|
else:
|
||||||
|
await menu(ctx, folder_page_list, LOCAL_FOLDER_CONTROLS)
|
||||||
else:
|
else:
|
||||||
await menu(ctx, folder_page_list, LOCAL_FOLDER_CONTROLS)
|
await menu(ctx, folder_page_list, LOCAL_FOLDER_CONTROLS)
|
||||||
|
|
||||||
@ -1097,7 +1103,7 @@ class Audio(commands.Cog):
|
|||||||
(
|
(
|
||||||
bold(playlist_name),
|
bold(playlist_name),
|
||||||
_("Tracks: {num}").format(num=len(tracks)),
|
_("Tracks: {num}").format(num=len(tracks)),
|
||||||
_("Author: {name}").format(self.bot.get_user(author)),
|
_("Author: {name}\n").format(name=self.bot.get_user(author)),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -1533,9 +1539,9 @@ class Audio(commands.Cog):
|
|||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
queue_list += _("Playing: ")
|
queue_list += _("Playing: ")
|
||||||
queue_list += "**[{current.title}]({current.uri})**\n".format(current=player.current)
|
queue_list += "**[{current.title}]({current.uri})**\n".format(current=player.current)
|
||||||
queue_list += _("Requested by: **{user}**").format(user=player.current.requester)
|
queue_list += _("Requested by: **{user}**").format(user=player.current.requester)
|
||||||
queue_list += f"\n\n{arrow}`{pos}`/`{dur}`\n\n"
|
queue_list += f"\n\n{arrow}`{pos}`/`{dur}`\n\n"
|
||||||
|
|
||||||
for i, track in enumerate(
|
for i, track in enumerate(
|
||||||
player.queue[queue_idx_start:queue_idx_end], start=queue_idx_start
|
player.queue[queue_idx_start:queue_idx_end], start=queue_idx_start
|
||||||
@ -2360,7 +2366,7 @@ class Audio(commands.Cog):
|
|||||||
if await self._check_external():
|
if await self._check_external():
|
||||||
embed = discord.Embed(
|
embed = discord.Embed(
|
||||||
colour=await ctx.embed_colour(),
|
colour=await ctx.embed_colour(),
|
||||||
title=_("Websocket port set to {}.").format(ws_port),
|
title=_("Websocket port set to {port}.").format(port=ws_port),
|
||||||
)
|
)
|
||||||
embed.set_footer(text=_("External lavalink server set to True."))
|
embed.set_footer(text=_("External lavalink server set to True."))
|
||||||
await ctx.send(embed=embed)
|
await ctx.send(embed=embed)
|
||||||
|
|||||||
@ -94,7 +94,7 @@ class Cleanup(commands.Cog):
|
|||||||
):
|
):
|
||||||
if message.created_at < two_weeks_ago:
|
if message.created_at < two_weeks_ago:
|
||||||
break
|
break
|
||||||
if check(message):
|
if message_filter(message):
|
||||||
collected.append(message)
|
collected.append(message)
|
||||||
if number and number <= len(collected):
|
if number and number <= len(collected):
|
||||||
break
|
break
|
||||||
|
|||||||
@ -218,7 +218,7 @@ class Economy(commands.Cog):
|
|||||||
else:
|
else:
|
||||||
await bank.set_balance(to, creds.sum)
|
await bank.set_balance(to, creds.sum)
|
||||||
await ctx.send(
|
await ctx.send(
|
||||||
_("{author} set {users}'s account balance to {num} {currency}.").format(
|
_("{author} set {user}'s account balance to {num} {currency}.").format(
|
||||||
author=author.display_name,
|
author=author.display_name,
|
||||||
num=creds.sum,
|
num=creds.sum,
|
||||||
currency=currency,
|
currency=currency,
|
||||||
|
|||||||
@ -748,7 +748,8 @@ class Mod(commands.Cog):
|
|||||||
to send the newly unbanned user
|
to send the newly unbanned user
|
||||||
:returns: :class:`Invite`"""
|
:returns: :class:`Invite`"""
|
||||||
guild = ctx.guild
|
guild = ctx.guild
|
||||||
if guild.me.permissions.manage_guild:
|
my_perms: discord.Permissions = guild.me.guild_permissions
|
||||||
|
if my_perms.manage_guild or my_perms.administrator:
|
||||||
if "VANITY_URL" in guild.features:
|
if "VANITY_URL" in guild.features:
|
||||||
# guild has a vanity url so use it as the one to send
|
# guild has a vanity url so use it as the one to send
|
||||||
return await guild.vanity_invite()
|
return await guild.vanity_invite()
|
||||||
|
|||||||
@ -1,40 +1,152 @@
|
|||||||
|
import re as _re
|
||||||
|
from math import inf as _inf
|
||||||
|
from typing import (
|
||||||
|
Any as _Any,
|
||||||
|
ClassVar as _ClassVar,
|
||||||
|
Dict as _Dict,
|
||||||
|
List as _List,
|
||||||
|
Optional as _Optional,
|
||||||
|
Pattern as _Pattern,
|
||||||
|
Tuple as _Tuple,
|
||||||
|
Union as _Union,
|
||||||
|
)
|
||||||
|
|
||||||
from .config import Config
|
from .config import Config
|
||||||
|
|
||||||
__all__ = ["Config", "__version__"]
|
__all__ = ["Config", "__version__", "version_info", "VersionInfo"]
|
||||||
|
|
||||||
|
|
||||||
class VersionInfo:
|
class VersionInfo:
|
||||||
def __init__(self, major, minor, micro, releaselevel, serial):
|
ALPHA = "alpha"
|
||||||
self._levels = ["alpha", "beta", "final"]
|
BETA = "beta"
|
||||||
self.major = major
|
RELEASE_CANDIDATE = "release candidate"
|
||||||
self.minor = minor
|
FINAL = "final"
|
||||||
self.micro = micro
|
|
||||||
|
|
||||||
if releaselevel not in self._levels:
|
_VERSION_STR_PATTERN: _ClassVar[_Pattern[str]] = _re.compile(
|
||||||
raise TypeError("'releaselevel' must be one of: {}".format(", ".join(self._levels)))
|
r"^"
|
||||||
|
r"(?P<major>0|[1-9]\d*)\.(?P<minor>0|[1-9]\d*)\.(?P<micro>0|[1-9]\d*)"
|
||||||
|
r"(?:(?P<releaselevel>a|b|rc)(?P<serial>0|[1-9]\d*))?"
|
||||||
|
r"(?:\.post(?P<post_release>0|[1-9]\d*))?"
|
||||||
|
r"(?:\.dev(?P<dev_release>0|[1-9]\d*))?"
|
||||||
|
r"$",
|
||||||
|
flags=_re.IGNORECASE,
|
||||||
|
)
|
||||||
|
_RELEASE_LEVELS: _ClassVar[_List[str]] = [ALPHA, BETA, RELEASE_CANDIDATE, FINAL]
|
||||||
|
_SHORT_RELEASE_LEVELS: _ClassVar[_Dict[str, str]] = {
|
||||||
|
"a": ALPHA,
|
||||||
|
"b": BETA,
|
||||||
|
"rc": RELEASE_CANDIDATE,
|
||||||
|
}
|
||||||
|
|
||||||
self.releaselevel = releaselevel
|
def __init__(
|
||||||
self.serial = serial
|
self,
|
||||||
|
major: int,
|
||||||
|
minor: int,
|
||||||
|
micro: int,
|
||||||
|
releaselevel: str,
|
||||||
|
serial: _Optional[int] = None,
|
||||||
|
post_release: _Optional[int] = None,
|
||||||
|
dev_release: _Optional[int] = None,
|
||||||
|
) -> None:
|
||||||
|
self.major: int = major
|
||||||
|
self.minor: int = minor
|
||||||
|
self.micro: int = micro
|
||||||
|
|
||||||
def __lt__(self, other):
|
if releaselevel not in self._RELEASE_LEVELS:
|
||||||
my_index = self._levels.index(self.releaselevel)
|
raise TypeError(f"'releaselevel' must be one of: {', '.join(self._RELEASE_LEVELS)}")
|
||||||
other_index = self._levels.index(other.releaselevel)
|
|
||||||
return (self.major, self.minor, self.micro, my_index, self.serial) < (
|
self.releaselevel: str = releaselevel
|
||||||
other.major,
|
self.serial: _Optional[int] = serial
|
||||||
other.minor,
|
self.post_release: _Optional[int] = post_release
|
||||||
other.micro,
|
self.dev_release: _Optional[int] = dev_release
|
||||||
other_index,
|
|
||||||
other.serial,
|
@classmethod
|
||||||
|
def from_str(cls, version_str: str) -> "VersionInfo":
|
||||||
|
"""Parse a string into a VersionInfo object.
|
||||||
|
|
||||||
|
Raises
|
||||||
|
------
|
||||||
|
ValueError
|
||||||
|
If the version info string is invalid.
|
||||||
|
|
||||||
|
"""
|
||||||
|
match = cls._VERSION_STR_PATTERN.match(version_str)
|
||||||
|
if not match:
|
||||||
|
raise ValueError(f"Invalid version string: {version_str}")
|
||||||
|
|
||||||
|
kwargs: _Dict[str, _Union[str, int]] = {}
|
||||||
|
for key in ("major", "minor", "micro"):
|
||||||
|
kwargs[key] = int(match[key])
|
||||||
|
releaselevel = match["releaselevel"]
|
||||||
|
if releaselevel is not None:
|
||||||
|
kwargs["releaselevel"] = cls._SHORT_RELEASE_LEVELS[releaselevel]
|
||||||
|
else:
|
||||||
|
kwargs["releaselevel"] = cls.FINAL
|
||||||
|
for key in ("serial", "post_release", "dev_release"):
|
||||||
|
if match[key] is not None:
|
||||||
|
kwargs[key] = int(match[key])
|
||||||
|
return cls(**kwargs)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_json(
|
||||||
|
cls, data: _Union[_Dict[str, _Union[int, str]], _List[_Union[int, str]]]
|
||||||
|
) -> "VersionInfo":
|
||||||
|
if isinstance(data, _List):
|
||||||
|
# For old versions, data was stored as a list:
|
||||||
|
# [MAJOR, MINOR, MICRO, RELEASELEVEL, SERIAL]
|
||||||
|
return cls(*data)
|
||||||
|
else:
|
||||||
|
return cls(**data)
|
||||||
|
|
||||||
|
def to_json(self) -> _Dict[str, _Union[int, str]]:
|
||||||
|
return {
|
||||||
|
"major": self.major,
|
||||||
|
"minor": self.minor,
|
||||||
|
"micro": self.micro,
|
||||||
|
"releaselevel": self.releaselevel,
|
||||||
|
"serial": self.serial,
|
||||||
|
"post_release": self.post_release,
|
||||||
|
"dev_release": self.dev_release,
|
||||||
|
}
|
||||||
|
|
||||||
|
def __lt__(self, other: _Any) -> bool:
|
||||||
|
if not isinstance(other, VersionInfo):
|
||||||
|
return NotImplemented
|
||||||
|
tups: _List[_Tuple[int, int, int, int, int, int, int]] = []
|
||||||
|
for obj in (self, other):
|
||||||
|
tups.append(
|
||||||
|
(
|
||||||
|
obj.major,
|
||||||
|
obj.minor,
|
||||||
|
obj.micro,
|
||||||
|
obj._RELEASE_LEVELS.index(obj.releaselevel),
|
||||||
|
obj.serial if obj.serial is not None else _inf,
|
||||||
|
obj.post_release if obj.post_release is not None else -_inf,
|
||||||
|
obj.dev_release if obj.dev_release is not None else _inf,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return tups[0] < tups[1]
|
||||||
|
|
||||||
|
def __str__(self) -> str:
|
||||||
|
ret = f"{self.major}.{self.minor}.{self.micro}"
|
||||||
|
if self.releaselevel != self.FINAL:
|
||||||
|
short = next(
|
||||||
|
k for k, v in self._SHORT_RELEASE_LEVELS.items() if v == self.releaselevel
|
||||||
|
)
|
||||||
|
ret += f"{short}{self.serial}"
|
||||||
|
if self.post_release is not None:
|
||||||
|
ret += f".post{self.post_release}"
|
||||||
|
if self.dev_release is not None:
|
||||||
|
ret += f".dev{self.dev_release}"
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def __repr__(self) -> str:
|
||||||
|
return (
|
||||||
|
"VersionInfo(major={major}, minor={minor}, micro={micro}, "
|
||||||
|
"releaselevel={releaselevel}, serial={serial}, post={post_release}, "
|
||||||
|
"dev={dev_release})".format(**self.to_json())
|
||||||
)
|
)
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return "VersionInfo(major={}, minor={}, micro={}, releaselevel={}, serial={})".format(
|
|
||||||
self.major, self.minor, self.micro, self.releaselevel, self.serial
|
|
||||||
)
|
|
||||||
|
|
||||||
def to_json(self):
|
__version__ = "3.0.0rc1.post1"
|
||||||
return [self.major, self.minor, self.micro, self.releaselevel, self.serial]
|
version_info = VersionInfo.from_str(__version__)
|
||||||
|
|
||||||
|
|
||||||
__version__ = "3.0.0b21"
|
|
||||||
version_info = VersionInfo(3, 0, 0, "beta", 21)
|
|
||||||
|
|||||||
@ -50,12 +50,10 @@ def interactive_config(red, token_set, prefix_set):
|
|||||||
def ask_sentry(red: Red):
|
def ask_sentry(red: Red):
|
||||||
loop = asyncio.get_event_loop()
|
loop = asyncio.get_event_loop()
|
||||||
print(
|
print(
|
||||||
"\nThank you for installing Red V3 beta! The current version\n"
|
"\nThank you for installing Red V3! Red is constantly undergoing\n"
|
||||||
" is not suited for production use and is aimed at testing\n"
|
" improvements, and we would like ask if you are comfortable with\n"
|
||||||
" the current and upcoming featureset, that's why we will\n"
|
" the bot automatically submitting fatal error logs to the development\n"
|
||||||
" also collect the fatal error logs to help us fix any new\n"
|
' team. If you wish to opt into the process please type "yes":\n'
|
||||||
" found issues in a timely manner. If you wish to opt in\n"
|
|
||||||
' the process please type "yes":\n'
|
|
||||||
)
|
)
|
||||||
if not confirm("> "):
|
if not confirm("> "):
|
||||||
loop.run_until_complete(red.db.enable_sentry.set(False))
|
loop.run_until_complete(red.db.enable_sentry.set(False))
|
||||||
|
|||||||
@ -13,17 +13,20 @@ from collections import namedtuple
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from random import SystemRandom
|
from random import SystemRandom
|
||||||
from string import ascii_letters, digits
|
from string import ascii_letters, digits
|
||||||
from distutils.version import StrictVersion
|
|
||||||
from typing import TYPE_CHECKING, Union
|
from typing import TYPE_CHECKING, Union
|
||||||
|
|
||||||
import aiohttp
|
import aiohttp
|
||||||
import discord
|
import discord
|
||||||
import pkg_resources
|
import pkg_resources
|
||||||
|
|
||||||
from redbot.core import __version__
|
from redbot.core import (
|
||||||
from redbot.core import checks
|
__version__,
|
||||||
from redbot.core import i18n
|
version_info as red_version_info,
|
||||||
from redbot.core import commands
|
VersionInfo,
|
||||||
|
checks,
|
||||||
|
commands,
|
||||||
|
i18n,
|
||||||
|
)
|
||||||
from .utils.predicates import MessagePredicate
|
from .utils.predicates import MessagePredicate
|
||||||
from .utils.chat_formatting import pagify, box, inline
|
from .utils.chat_formatting import pagify, box, inline
|
||||||
|
|
||||||
@ -274,7 +277,7 @@ class Core(commands.Cog, CoreLogic):
|
|||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
async with session.get("{}/json".format(red_pypi)) as r:
|
async with session.get("{}/json".format(red_pypi)) as r:
|
||||||
data = await r.json()
|
data = await r.json()
|
||||||
outdated = StrictVersion(data["info"]["version"]) > StrictVersion(__version__)
|
outdated = VersionInfo.from_str(data["info"]["version"]) > red_version_info
|
||||||
about = (
|
about = (
|
||||||
"This is an instance of [Red, an open source Discord bot]({}) "
|
"This is an instance of [Red, an open source Discord bot]({}) "
|
||||||
"created by [Twentysix]({}) and [improved by many]({}).\n\n"
|
"created by [Twentysix]({}) and [improved by many]({}).\n\n"
|
||||||
|
|||||||
@ -9,7 +9,7 @@ _conn = None
|
|||||||
|
|
||||||
|
|
||||||
def _initialize(**kwargs):
|
def _initialize(**kwargs):
|
||||||
kwargs.get("URI", "mongodb")
|
uri = kwargs.get("URI", "mongodb")
|
||||||
host = kwargs["HOST"]
|
host = kwargs["HOST"]
|
||||||
port = kwargs["PORT"]
|
port = kwargs["PORT"]
|
||||||
admin_user = kwargs["USERNAME"]
|
admin_user = kwargs["USERNAME"]
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
|
import contextlib
|
||||||
import sys
|
import sys
|
||||||
import codecs
|
import codecs
|
||||||
import datetime
|
import datetime
|
||||||
import logging
|
import logging
|
||||||
import traceback
|
import traceback
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
from distutils.version import StrictVersion
|
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
import aiohttp
|
import aiohttp
|
||||||
@ -13,7 +13,7 @@ import pkg_resources
|
|||||||
from colorama import Fore, Style, init
|
from colorama import Fore, Style, init
|
||||||
from pkg_resources import DistributionNotFound
|
from pkg_resources import DistributionNotFound
|
||||||
|
|
||||||
from . import __version__, commands
|
from . import __version__ as red_version, version_info as red_version_info, VersionInfo, commands
|
||||||
from .data_manager import storage_type
|
from .data_manager import storage_type
|
||||||
from .utils.chat_formatting import inline, bordered, humanize_list
|
from .utils.chat_formatting import inline, bordered, humanize_list
|
||||||
from .utils import fuzzy_command_search, format_fuzzy_results
|
from .utils import fuzzy_command_search, format_fuzzy_results
|
||||||
@ -105,7 +105,6 @@ def init_events(bot, cli_flags):
|
|||||||
|
|
||||||
prefixes = cli_flags.prefix or (await bot.db.prefix())
|
prefixes = cli_flags.prefix or (await bot.db.prefix())
|
||||||
lang = await bot.db.locale()
|
lang = await bot.db.locale()
|
||||||
red_version = __version__
|
|
||||||
red_pkg = pkg_resources.get_distribution("Red-DiscordBot")
|
red_pkg = pkg_resources.get_distribution("Red-DiscordBot")
|
||||||
dpy_version = discord.__version__
|
dpy_version = discord.__version__
|
||||||
|
|
||||||
@ -125,24 +124,22 @@ def init_events(bot, cli_flags):
|
|||||||
|
|
||||||
INFO.append("{} cogs with {} commands".format(len(bot.cogs), len(bot.commands)))
|
INFO.append("{} cogs with {} commands".format(len(bot.cogs), len(bot.commands)))
|
||||||
|
|
||||||
try:
|
with contextlib.suppress(aiohttp.ClientError, discord.HTTPException):
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
async with session.get("https://pypi.python.org/pypi/red-discordbot/json") as r:
|
async with session.get("https://pypi.python.org/pypi/red-discordbot/json") as r:
|
||||||
data = await r.json()
|
data = await r.json()
|
||||||
if StrictVersion(data["info"]["version"]) > StrictVersion(red_version):
|
if VersionInfo.from_str(data["info"]["version"]) > red_version_info:
|
||||||
INFO.append(
|
INFO.append(
|
||||||
"Outdated version! {} is available "
|
"Outdated version! {} is available "
|
||||||
"but you're using {}".format(data["info"]["version"], red_version)
|
"but you're using {}".format(data["info"]["version"], red_version)
|
||||||
)
|
)
|
||||||
owner = discord.utils.get(bot.get_all_members(), id=bot.owner_id)
|
owner = await bot.get_user_info(bot.owner_id)
|
||||||
await owner.send(
|
await owner.send(
|
||||||
"Your Red instance is out of date! {} is the current "
|
"Your Red instance is out of date! {} is the current "
|
||||||
"version, however you are using {}!".format(
|
"version, however you are using {}!".format(
|
||||||
data["info"]["version"], red_version
|
data["info"]["version"], red_version
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
except:
|
|
||||||
pass
|
|
||||||
INFO2 = []
|
INFO2 = []
|
||||||
|
|
||||||
sentry = await bot.db.enable_sentry()
|
sentry = await bot.db.enable_sentry()
|
||||||
|
|||||||
@ -8,18 +8,14 @@ import asyncio
|
|||||||
import aiohttp
|
import aiohttp
|
||||||
|
|
||||||
import pkg_resources
|
import pkg_resources
|
||||||
from pathlib import Path
|
|
||||||
from distutils.version import StrictVersion
|
|
||||||
from redbot.setup import (
|
from redbot.setup import (
|
||||||
basic_setup,
|
basic_setup,
|
||||||
load_existing_config,
|
load_existing_config,
|
||||||
remove_instance,
|
remove_instance,
|
||||||
remove_instance_interaction,
|
remove_instance_interaction,
|
||||||
create_backup,
|
create_backup,
|
||||||
save_config,
|
|
||||||
)
|
)
|
||||||
from redbot.core import __version__
|
from redbot.core import __version__, version_info as red_version_info, VersionInfo
|
||||||
from redbot.core.utils import safe_delete
|
|
||||||
from redbot.core.cli import confirm
|
from redbot.core.cli import confirm
|
||||||
|
|
||||||
if sys.platform == "linux":
|
if sys.platform == "linux":
|
||||||
@ -390,7 +386,7 @@ async def is_outdated():
|
|||||||
async with session.get("{}/json".format(red_pypi)) as r:
|
async with session.get("{}/json".format(red_pypi)) as r:
|
||||||
data = await r.json()
|
data = await r.json()
|
||||||
new_version = data["info"]["version"]
|
new_version = data["info"]["version"]
|
||||||
return StrictVersion(new_version) > StrictVersion(__version__), new_version
|
return VersionInfo.from_str(new_version) > red_version_info, new_version
|
||||||
|
|
||||||
|
|
||||||
def main_menu():
|
def main_menu():
|
||||||
|
|||||||
@ -1,6 +1,36 @@
|
|||||||
from redbot import core
|
from redbot import core
|
||||||
|
from redbot.core import VersionInfo
|
||||||
|
|
||||||
|
|
||||||
def test_version_working():
|
def test_version_working():
|
||||||
assert hasattr(core, "__version__")
|
assert hasattr(core, "__version__")
|
||||||
assert core.__version__[0] == "3"
|
assert core.__version__[0] == "3"
|
||||||
|
|
||||||
|
|
||||||
|
# When adding more of these, ensure they are added in ascending order of precedence
|
||||||
|
version_tests = (
|
||||||
|
"3.0.0a32.post10.dev12",
|
||||||
|
"3.0.0rc1.dev1",
|
||||||
|
"3.0.0rc1",
|
||||||
|
"3.0.0",
|
||||||
|
"3.0.1",
|
||||||
|
"3.0.1.post1.dev1",
|
||||||
|
"3.0.1.post1",
|
||||||
|
"2018.10.6b21",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_version_info_str_parsing():
|
||||||
|
for version_str in version_tests:
|
||||||
|
assert version_str == str(VersionInfo.from_str(version_str))
|
||||||
|
|
||||||
|
|
||||||
|
def test_version_info_lt():
|
||||||
|
for next_idx, cur in enumerate(version_tests[:-1], start=1):
|
||||||
|
cur_test = VersionInfo.from_str(cur)
|
||||||
|
next_test = VersionInfo.from_str(version_tests[next_idx])
|
||||||
|
assert cur_test < next_test
|
||||||
|
|
||||||
|
|
||||||
|
def test_version_info_gt():
|
||||||
|
assert VersionInfo.from_str(version_tests[1]) > VersionInfo.from_str(version_tests[0])
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user