spoiler filtering
This commit is contained in:
@@ -3,16 +3,24 @@ import random
|
|||||||
|
|
||||||
# Custom libs
|
# Custom libs
|
||||||
|
|
||||||
from utils import mention, from_now, str_datetime, message_link, SPLIT_TOKEN
|
from utils import (
|
||||||
|
mention,
|
||||||
|
from_now,
|
||||||
|
str_datetime,
|
||||||
|
message_link,
|
||||||
|
SPLIT_TOKEN,
|
||||||
|
FilterLevel,
|
||||||
|
should_allow_spoiler,
|
||||||
|
)
|
||||||
|
|
||||||
MAX_RANDOM_TRIES = 10
|
MAX_RANDOM_TRIES = 100
|
||||||
|
|
||||||
|
|
||||||
class History:
|
class History:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.messages = []
|
self.messages = []
|
||||||
|
|
||||||
async def to_string_image(self, *, type: str) -> List[str]:
|
async def to_string_image(self, *, type: str, spoiler: FilterLevel) -> List[str]:
|
||||||
if len(self.messages) == 0:
|
if len(self.messages) == 0:
|
||||||
return ["There was no messages matching your filters"]
|
return ["There was no messages matching your filters"]
|
||||||
message = None
|
message = None
|
||||||
@@ -24,6 +32,10 @@ class History:
|
|||||||
while real_message is None and index < len(self.messages):
|
while real_message is None and index < len(self.messages):
|
||||||
message = self.messages[index]
|
message = self.messages[index]
|
||||||
real_message = await message.fetch()
|
real_message = await message.fetch()
|
||||||
|
if real_message is not None and not should_allow_spoiler(
|
||||||
|
real_message, spoiler
|
||||||
|
):
|
||||||
|
real_message = None
|
||||||
index += 1
|
index += 1
|
||||||
intro = f"First image out of {len(self.messages):,}"
|
intro = f"First image out of {len(self.messages):,}"
|
||||||
elif type == "last":
|
elif type == "last":
|
||||||
@@ -32,6 +44,10 @@ class History:
|
|||||||
while real_message is None and index < len(self.messages):
|
while real_message is None and index < len(self.messages):
|
||||||
message = self.messages[index]
|
message = self.messages[index]
|
||||||
real_message = await message.fetch()
|
real_message = await message.fetch()
|
||||||
|
if real_message is not None and not should_allow_spoiler(
|
||||||
|
real_message, spoiler
|
||||||
|
):
|
||||||
|
real_message = None
|
||||||
index += 1
|
index += 1
|
||||||
intro = f"Last image out of {len(self.messages):,}"
|
intro = f"Last image out of {len(self.messages):,}"
|
||||||
elif type == "random":
|
elif type == "random":
|
||||||
@@ -40,6 +56,10 @@ class History:
|
|||||||
while real_message is None and tries < MAX_RANDOM_TRIES:
|
while real_message is None and tries < MAX_RANDOM_TRIES:
|
||||||
message = random.choice(self.messages)
|
message = random.choice(self.messages)
|
||||||
real_message = await message.fetch()
|
real_message = await message.fetch()
|
||||||
|
if real_message is not None and not should_allow_spoiler(
|
||||||
|
real_message, spoiler
|
||||||
|
):
|
||||||
|
real_message = None
|
||||||
tries += 1
|
tries += 1
|
||||||
|
|
||||||
if real_message is None:
|
if real_message is None:
|
||||||
|
|||||||
@@ -12,7 +12,10 @@ class FirstScanner(HistoryScanner):
|
|||||||
return generate_help(
|
return generate_help(
|
||||||
"first",
|
"first",
|
||||||
"Read first message (add text to filter like %find)",
|
"Read first message (add text to filter like %find)",
|
||||||
args=["image - pull an image instead of a message"],
|
args=[
|
||||||
|
"image - pull an image instead of a message",
|
||||||
|
"spoiler:allow/only - allow spoiler images",
|
||||||
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@@ -20,6 +23,8 @@ class FirstScanner(HistoryScanner):
|
|||||||
|
|
||||||
async def get_results(self, intro: str) -> List[str]:
|
async def get_results(self, intro: str) -> List[str]:
|
||||||
if self.images_only:
|
if self.images_only:
|
||||||
return await self.history.to_string_image(type="first")
|
return await self.history.to_string_image(
|
||||||
|
type="first", spoiler=self.spoiler
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
return self.history.to_string(type="first")
|
return self.history.to_string(type="first")
|
||||||
|
|||||||
@@ -8,13 +8,14 @@ import re
|
|||||||
from .scanner import Scanner
|
from .scanner import Scanner
|
||||||
from data_types import History
|
from data_types import History
|
||||||
from logs import ChannelLogs, MessageLog
|
from logs import ChannelLogs, MessageLog
|
||||||
|
from utils import FilterLevel
|
||||||
|
|
||||||
|
|
||||||
class HistoryScanner(Scanner, ABC):
|
class HistoryScanner(Scanner, ABC):
|
||||||
def __init__(self, *, help: str):
|
def __init__(self, *, help: str):
|
||||||
super().__init__(
|
super().__init__(
|
||||||
has_digit_args=True,
|
has_digit_args=True,
|
||||||
valid_args=["all", "everyone"],
|
valid_args=["all", "everyone", "spoiler", "spoiler:allow", "spoiler:only"],
|
||||||
help=help,
|
help=help,
|
||||||
intro_context="",
|
intro_context="",
|
||||||
all_args=True,
|
all_args=True,
|
||||||
@@ -24,6 +25,12 @@ class HistoryScanner(Scanner, ABC):
|
|||||||
self.history = History()
|
self.history = History()
|
||||||
self.all_messages = "all" in args or "everyone" in args
|
self.all_messages = "all" in args or "everyone" in args
|
||||||
self.images_only = "image" in args
|
self.images_only = "image" in args
|
||||||
|
if "spoiler" in args or "spoiler:allow" in args:
|
||||||
|
self.spoiler = FilterLevel.ALLOW
|
||||||
|
elif "spoiler:only" in args:
|
||||||
|
self.spoiler = FilterLevel.ONLY
|
||||||
|
else:
|
||||||
|
self.spoiler = FilterLevel.NONE
|
||||||
if not self.images_only:
|
if not self.images_only:
|
||||||
self.queries = [
|
self.queries = [
|
||||||
(
|
(
|
||||||
|
|||||||
@@ -12,7 +12,10 @@ class LastScanner(HistoryScanner):
|
|||||||
return generate_help(
|
return generate_help(
|
||||||
"last",
|
"last",
|
||||||
"Read last message (add text to filter like %find)",
|
"Read last message (add text to filter like %find)",
|
||||||
args=["image - pull an image instead of a message"],
|
args=[
|
||||||
|
"image - pull an image instead of a message",
|
||||||
|
"spoiler:allow/only - allow spoiler images",
|
||||||
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@@ -20,6 +23,6 @@ class LastScanner(HistoryScanner):
|
|||||||
|
|
||||||
async def get_results(self, intro: str) -> List[str]:
|
async def get_results(self, intro: str) -> List[str]:
|
||||||
if self.images_only:
|
if self.images_only:
|
||||||
return await self.history.to_string_image(type="last")
|
return await self.history.to_string_image(type="last", spoiler=self.spoiler)
|
||||||
else:
|
else:
|
||||||
return self.history.to_string(type="last")
|
return self.history.to_string(type="last")
|
||||||
|
|||||||
@@ -12,7 +12,10 @@ class RandomScanner(HistoryScanner):
|
|||||||
return generate_help(
|
return generate_help(
|
||||||
"rand",
|
"rand",
|
||||||
"Read a random message (add text to filter like %find)",
|
"Read a random message (add text to filter like %find)",
|
||||||
args=["image - pull an image instead of a message"],
|
args=[
|
||||||
|
"image - pull an image instead of a message",
|
||||||
|
"spoiler:allow/only - allow spoiler images",
|
||||||
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@@ -20,6 +23,8 @@ class RandomScanner(HistoryScanner):
|
|||||||
|
|
||||||
async def get_results(self, intro: str) -> List[str]:
|
async def get_results(self, intro: str) -> List[str]:
|
||||||
if self.images_only:
|
if self.images_only:
|
||||||
return await self.history.to_string_image(type="random")
|
return await self.history.to_string_image(
|
||||||
|
type="random", spoiler=self.spoiler
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
return self.history.to_string(type="random")
|
return self.history.to_string(type="random")
|
||||||
|
|||||||
@@ -100,6 +100,25 @@ class FakeMessage:
|
|||||||
self.id = id
|
self.id = id
|
||||||
|
|
||||||
|
|
||||||
|
def is_image_spoiler(message: discord.Message) -> bool:
|
||||||
|
if len(message.attachments) > 0:
|
||||||
|
return message.attachments[0].is_spoiler()
|
||||||
|
elif len(message.embeds) > 0:
|
||||||
|
return re.match(r"||[^|]*http[^|]||", message.content.lower()) is not None
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def should_allow_spoiler(message: discord.Message, spoiler: FilterLevel) -> bool:
|
||||||
|
is_spoiler = is_image_spoiler(message)
|
||||||
|
return (
|
||||||
|
not is_spoiler
|
||||||
|
and spoiler <= FilterLevel.ALLOW
|
||||||
|
or is_spoiler
|
||||||
|
and spoiler >= FilterLevel.ALLOW
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# FILE
|
# FILE
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user