232 lines
7.7 KiB
Python
232 lines
7.7 KiB
Python
import discord
|
|
from discord import errors
|
|
from discord.ext import pages
|
|
from discord.utils import find
|
|
|
|
from tortoise import transactions
|
|
|
|
from payphone import bot
|
|
from payphone.db import models
|
|
from payphone.core import constants, formatting as fmt
|
|
from payphone.cogs.mods import modals, views, embeds
|
|
|
|
|
|
class ReportView(discord.ui.View):
|
|
"""The view sent together with the report embed."""
|
|
|
|
def __init__(
|
|
self, bot: bot.Payphone, report: models.Report, remaining_reports: int
|
|
) -> None:
|
|
"""Initializes the view.
|
|
|
|
Args:
|
|
bot (bot.Payphone): The bot.
|
|
report (models.Report): The report.
|
|
remaining_reports (int): The amount of reports that need to be reviewed remaining.
|
|
"""
|
|
|
|
super().__init__(timeout=900, disable_on_timeout=True)
|
|
|
|
self.bot = bot
|
|
self.report = report
|
|
|
|
option_labels = set(
|
|
f"Ban {rs.profile.name} [ID: {rs.user_id}]" for rs in report.call.call_rss
|
|
)
|
|
|
|
actions = discord.ui.Select(
|
|
placeholder="Actions",
|
|
options=[discord.SelectOption(label=label) for label in option_labels],
|
|
)
|
|
|
|
async def actions_callback(interaction: discord.Interaction) -> None:
|
|
# interaction.data = {'values': ['Ban Nyeki (JPP)'], 'custom_id': 'staff_call_report:actions', 'component_type': 3}
|
|
value = interaction.data["values"][0]
|
|
|
|
user_id = int(value.rsplit("[ID: ", 1)[1][:-1])
|
|
|
|
await interaction.response.send_modal(
|
|
modals.BanUserModal(
|
|
bot,
|
|
find(
|
|
lambda rs: rs.user_id == user_id, report.call.call_rss
|
|
).profile,
|
|
report.id,
|
|
)
|
|
)
|
|
|
|
actions.callback = actions_callback
|
|
|
|
self.add_item(actions)
|
|
self.add_item(
|
|
discord.ui.Button(
|
|
label=f"Remaining: {remaining_reports}", disabled=True, row=2
|
|
)
|
|
)
|
|
|
|
@discord.ui.button(label="Message Logs", style=discord.ButtonStyle.gray, row=2)
|
|
async def message_logs(
|
|
self, _button: discord.ui.Button, interaction: discord.Interaction
|
|
) -> None:
|
|
report = self.report
|
|
|
|
messages = (
|
|
await models.Message.filter(call=report.call)
|
|
.order_by("id")
|
|
.prefetch_related("contents")
|
|
)
|
|
|
|
logs = []
|
|
|
|
reporter_channel_id = find(
|
|
lambda rs: rs.user_id == report.reported_by_id, report.call.call_rss
|
|
).channel_id
|
|
|
|
profiles_to_relationship_mapping = {
|
|
rs.profile_id: rs for rs in report.call.call_rss
|
|
}
|
|
|
|
last_user_id = None
|
|
last_channel_id = None
|
|
|
|
current_block = ""
|
|
|
|
for message in messages:
|
|
is_new_block = (
|
|
message.user_id != last_user_id or last_channel_id != message.channel_id
|
|
)
|
|
|
|
if is_new_block:
|
|
logs.append(current_block)
|
|
current_block = ""
|
|
|
|
current_block += f"{"+" if message.channel_id == reporter_channel_id else "-"} {f"{profiles_to_relationship_mapping[message.profile_id].profile.name}{f" (Masked as {profiles_to_relationship_mapping[message.profile_id].mask_name})" if profiles_to_relationship_mapping[message.profile_id].is_masked else ""}" if message.profile_id in profiles_to_relationship_mapping else "Unknown"}:"
|
|
|
|
for content in message.contents:
|
|
current_block += (
|
|
f"\n{"!" if not content.was_propagated else "X" if message.was_deleted else " "} {content.content}"
|
|
)
|
|
|
|
last_user_id = message.user_id
|
|
last_channel_id = message.channel_id
|
|
|
|
log_pages = []
|
|
|
|
for current_block in logs:
|
|
if len(log_pages) > 0 and len(log_pages[-1]) + len(current_block) < 1000:
|
|
log_pages[-1] += "\n\n" + current_block.replace(
|
|
"```",
|
|
f"`{constants.INVISIBLE_CHARACTER}`{constants.INVISIBLE_CHARACTER}`",
|
|
)
|
|
|
|
else:
|
|
log_pages.append(
|
|
current_block.replace(
|
|
"```",
|
|
f"`{constants.INVISIBLE_CHARACTER}`{constants.INVISIBLE_CHARACTER}`",
|
|
)
|
|
)
|
|
|
|
await pages.Paginator(
|
|
[f"```diff\n{page}\n```" for page in log_pages],
|
|
timeout=300,
|
|
).respond(interaction, ephemeral=True)
|
|
|
|
@discord.ui.button(label="Accept", style=discord.ButtonStyle.green, row=2)
|
|
@transactions.atomic()
|
|
async def accept(
|
|
self, _button: discord.ui.Button, interaction: discord.Interaction
|
|
) -> None:
|
|
report = self.report
|
|
|
|
report.status = models.ReportStatus.ACCEPTED
|
|
await report.save()
|
|
|
|
next_report = (
|
|
await models.Report.filter(status=models.ReportStatus.ON_REVIEW)
|
|
.order_by("-priority")
|
|
.limit(1)
|
|
.first()
|
|
.select_related("call")
|
|
.prefetch_related("call__call_rss", "call__call_rss__profile")
|
|
)
|
|
total = await models.Report.filter(status=models.ReportStatus.ON_REVIEW).count()
|
|
|
|
banned_user_ids = (
|
|
await models.Ban.filter(report=report)
|
|
.distinct()
|
|
.values_list("user_id", flat=True)
|
|
)
|
|
|
|
if next_report is None:
|
|
await interaction.response.edit_message(
|
|
content="✅ No reports left, have this cookie 🍪 !!",
|
|
embed=None,
|
|
view=None,
|
|
)
|
|
|
|
else:
|
|
await interaction.response.edit_message(
|
|
embed=embeds.ReportEmbed(self.bot, next_report),
|
|
view=views.ReportView(self.bot, next_report, total),
|
|
)
|
|
|
|
if len(banned_user_ids) > 0:
|
|
profiles = [
|
|
rs.profile
|
|
for rs in report.call.call_rss
|
|
if rs.user_id in banned_user_ids
|
|
]
|
|
|
|
try:
|
|
await (await self.bot.get_or_fetch_user(report.reported_by_id)).send(
|
|
f"🔔 Your report for call `{report.call_id}` helped us ban "
|
|
+ fmt.text_join(
|
|
[
|
|
(
|
|
f"`{p.name}`"
|
|
if p.user_id != report.reported_by_id
|
|
else "`you`"
|
|
)
|
|
for p in profiles
|
|
]
|
|
)
|
|
+ ". Thank you for your report!"
|
|
)
|
|
|
|
except errors.DiscordException:
|
|
pass
|
|
|
|
@discord.ui.button(label="Decline", style=discord.ButtonStyle.red, row=2)
|
|
@transactions.atomic()
|
|
async def decline(
|
|
self, _button: discord.ui.Button, interaction: discord.Interaction
|
|
) -> None:
|
|
report = self.report
|
|
|
|
report.status = models.ReportStatus.DECLINED
|
|
await report.save()
|
|
|
|
report = (
|
|
await models.Report.filter(status=models.ReportStatus.ON_REVIEW)
|
|
.order_by("-priority")
|
|
.limit(1)
|
|
.first()
|
|
.select_related("call")
|
|
.prefetch_related("call__call_rss", "call__call_rss__profile")
|
|
)
|
|
total = await models.Report.filter(status=models.ReportStatus.ON_REVIEW).count()
|
|
|
|
if report is None:
|
|
await interaction.response.edit_message(
|
|
content="✅ No reports left, have this cookie 🍪 !!",
|
|
embed=None,
|
|
view=None,
|
|
)
|
|
return
|
|
|
|
await interaction.response.edit_message(
|
|
embed=embeds.ReportEmbed(self.bot, report),
|
|
view=views.ReportView(self.bot, report, total),
|
|
)
|