|
1 | | -from datetime import datetime, timedelta |
| 1 | +from datetime import datetime, timedelta, UTC |
2 | 2 | from typing import TYPE_CHECKING |
3 | 3 |
|
4 | 4 | import discord |
|
11 | 11 | from utils.utils import encrypt_id |
12 | 12 |
|
13 | 13 |
|
| 14 | +CONSENT_VERSION = 1 |
| 15 | + |
| 16 | + |
14 | 17 | class ActiveSurvey: |
15 | 18 | def __init__(self, template: int | SurveyTemplate, end: datetime | timedelta | None = None): |
16 | 19 | self.template: int | SurveyTemplate = template |
@@ -87,17 +90,24 @@ def __init__(self, custom_id: int): |
87 | 90 | self.encrypted_user_id: str | None = None |
88 | 91 |
|
89 | 92 | async def callback(self, interaction: discord.Interaction): |
90 | | - # await interaction.response.defer() |
91 | 93 | template = self.view.survey.template |
92 | 94 |
|
93 | 95 | # Check If Time Is Up On The Survey |
94 | 96 | if self.view.survey.end and self.view.survey.end < datetime.now(): |
95 | 97 | await self.view.end_survey() |
96 | 98 | return await interaction.respond(embed=await ef.fail("Sorry! This Survey Has Ended"), ephemeral=True) |
97 | 99 |
|
| 100 | + # await interaction.response.defer() |
| 101 | + |
98 | 102 | # Get The Encrypted User ID |
99 | 103 | self.encrypted_user_id = await encrypt_id(interaction.user.id) |
100 | 104 |
|
| 105 | + # Check If The User Has Completed The Data Sharing Consent Form |
| 106 | + sql = """SELECT version_id FROM surveys.data_sharing_consent WHERE user_id = $1 AND guild_id = $2;""" |
| 107 | + if await db.fetchval(sql, str(interaction.user.id), str(interaction.guild_id)) != CONSENT_VERSION: |
| 108 | + v = DataSharingConsent() |
| 109 | + return await interaction.respond(embed=v.embed, view=v, ephemeral=True) |
| 110 | + |
101 | 111 | # Fetch The Template If Needed |
102 | 112 | if isinstance(template, int): |
103 | 113 | self.view.survey.template = await SurveyTemplate.fetch(template, True) |
@@ -143,8 +153,49 @@ def view(self) -> ActiveSurveyView: |
143 | 153 | pass |
144 | 154 |
|
145 | 155 |
|
| 156 | +class DataSharingConsent(discord.ui.View): |
| 157 | + def __init__(self): |
| 158 | + super().__init__(timeout=300, disable_on_timeout=True) |
| 159 | + d = ( |
| 160 | + '## Before You Can Continue!\nBy clicking the "Confirm" button you consent to the Bot sharing your ' |
| 161 | + "responses with the Creator of the Survey and any other Users the Creator has allowed access. This " |
| 162 | + "agreement extends to all future submissions in this Server. You can revoke this consent by joining the " |
| 163 | + "[support server](<https://discord.gg/f39cJ9D>) and requesting your consent to be revoked. If consent " |
| 164 | + "is revoked it will only apply to future submissions and any existing submissions will still be able to " |
| 165 | + "be shared with the Creator. If you do not wish to consent you will not be able to participate in any " |
| 166 | + "surveys, but can choose to consent at any point in the future by attempting to respond to a survey. " |
| 167 | + "\n-# Some terminology is used in this agreement. The definitions of each term can be found in the [" |
| 168 | + "TOS](<https://gist.github.com/Icebluewolf/7e73be418408ac48a35deb8045ae2a29>) or [Privacy Policy](" |
| 169 | + "<https://gist.github.com/Icebluewolf/90335bbc4d82d435d437b5da98f71df6>)" |
| 170 | + ) |
| 171 | + self.embed = discord.Embed(title="Data Sharing Consent Form", description=d) |
| 172 | + |
| 173 | + @discord.ui.button(emoji="✅", label="Confirm", style=discord.ButtonStyle.success) |
| 174 | + async def confirm(self, button, interaction: discord.Interaction): |
| 175 | + await interaction.response.defer() |
| 176 | + sql = ( |
| 177 | + "INSERT INTO surveys.data_sharing_consent (user_id, guild_id, timestamp, version_id) " |
| 178 | + "VALUES ($1, $2, $3, $4) ON CONFLICT (user_id, guild_id) DO UPDATE SET version_id = excluded.version_id;" |
| 179 | + ) |
| 180 | + now = datetime.now(UTC) |
| 181 | + await db.execute( |
| 182 | + sql, str(interaction.user.id), str(interaction.guild_id), now.replace(tzinfo=None), CONSENT_VERSION |
| 183 | + ) |
| 184 | + message = ( |
| 185 | + f"Please Click The Button To Take The Survey Again!\n\nThis Form Was Completed By " |
| 186 | + f"{interaction.user.name} (`{interaction.user.id}`) In {interaction.guild.name} " |
| 187 | + f"(`{interaction.guild_id}`) At {discord.utils.format_dt(now, "F")}" |
| 188 | + ) |
| 189 | + await interaction.edit(embed=await ef.success(message), view=None) |
| 190 | + |
| 191 | + @discord.ui.button(emoji="❎", label="Reject", style=discord.ButtonStyle.danger) |
| 192 | + async def reject(self, button, interaction: discord.Interaction): |
| 193 | + message = "You Rejected The Consent Form. To Accept It You Can Try To Take Another Servey" |
| 194 | + await interaction.edit(embed=await ef.general(message), view=None) |
| 195 | + |
| 196 | + |
146 | 197 | async def load_active_surveys(): |
147 | | - sql = """SELECT id, end_date, template_id, channel_id, message_id FROM surveys.active_guild_surveys |
| 198 | + sql = """SELECT "id", end_date, template_id, channel_id, message_id FROM surveys.active_guild_surveys |
148 | 199 | WHERE end_date > NOW();""" |
149 | 200 | rows = await db.fetch(sql) |
150 | 201 | views = [] |
|
0 commit comments