Apply patreon sharing across web/bot
This commit is contained in:
@@ -43,8 +43,9 @@ impl Recordable for Options {
|
||||
// Insert or update the patreon_link entry
|
||||
sqlx::query!(
|
||||
"INSERT INTO patreon_link (user_id, guild_id, linked_at) VALUES (?, ?, NOW())
|
||||
ON DUPLICATE KEY UPDATE user_id = user_id",
|
||||
ON DUPLICATE KEY UPDATE guild_id = ?",
|
||||
user_id.get(),
|
||||
guild_id.get(),
|
||||
guild_id.get()
|
||||
)
|
||||
.execute(&ctx.data().database)
|
||||
|
@@ -532,7 +532,9 @@ pub async fn create_reminder(
|
||||
};
|
||||
|
||||
let (processed_interval, processed_expires) = if let Some(repeat) = &interval {
|
||||
if check_subscription(&ctx, ctx.author().id, ctx.guild_id()).await {
|
||||
if check_subscription(&ctx, &ctx.data().database, ctx.author().id, ctx.guild_id())
|
||||
.await
|
||||
{
|
||||
(
|
||||
parse_duration(repeat)
|
||||
.or_else(|_| parse_duration(&format!("1 {}", repeat)))
|
||||
|
@@ -7,7 +7,6 @@ use std::{
|
||||
use chrono::{DateTime, Datelike, Timelike, Utc};
|
||||
use chrono_tz::Tz;
|
||||
use cron_parser::parse;
|
||||
use std::str::FromStr;
|
||||
use tokio::process::Command;
|
||||
|
||||
use crate::consts::{LOCAL_TIMEZONE, PYTHON_LOCATION};
|
||||
|
14
src/utils.rs
14
src/utils.rs
@@ -9,24 +9,25 @@ use poise::{
|
||||
|
||||
use crate::{
|
||||
consts::{CNC_GUILD, SUBSCRIPTION_ROLES},
|
||||
ApplicationContext, Context, Error,
|
||||
ApplicationContext, Context, Database, Error,
|
||||
};
|
||||
|
||||
/// Check if this user/guild combination should be considered subscribed.
|
||||
/// If the guild has a patreon linked, check the user involved in the link.
|
||||
/// Otherwise, check the user and the guild's owner
|
||||
pub async fn check_subscription(
|
||||
ctx: &Context<'_>,
|
||||
ctx: impl CacheHttp,
|
||||
database: impl Executor<'_, Database = Database>,
|
||||
user_id: UserId,
|
||||
guild_id: Option<GuildId>,
|
||||
) -> bool {
|
||||
if let Some(subscription_guild) = *CNC_GUILD {
|
||||
let user_subscribed = check_user_subscription(ctx, user_id).await;
|
||||
let user_subscribed = check_user_subscription(&ctx, user_id).await;
|
||||
|
||||
let owner_subscribed = match guild_id {
|
||||
Some(guild_id) => {
|
||||
if let Some(owner) = ctx.cache().unwrap().guild(guild_id).map(|g| g.owner_id) {
|
||||
check_user_subscription(ctx, owner).await
|
||||
check_user_subscription(&ctx, owner).await
|
||||
} else {
|
||||
false
|
||||
}
|
||||
@@ -41,10 +42,10 @@ pub async fn check_subscription(
|
||||
"SELECT user_id FROM patreon_link WHERE user_id = ?",
|
||||
guild_id.get()
|
||||
)
|
||||
.fetch_one(&ctx.data().database)
|
||||
.fetch_one(database)
|
||||
.await
|
||||
{
|
||||
check_user_subscription(ctx, row.user_id).await
|
||||
check_user_subscription(&ctx, row.user_id).await
|
||||
} else {
|
||||
false
|
||||
}
|
||||
@@ -116,6 +117,7 @@ pub trait Extract {
|
||||
}
|
||||
|
||||
pub use extract_derive::Extract;
|
||||
use sqlx::Executor;
|
||||
|
||||
macro_rules! extract_arg {
|
||||
($ctx:ident, $name:ident, String) => {
|
||||
|
@@ -233,39 +233,6 @@ pub async fn initialize(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn check_subscription(cache_http: impl CacheHttp, user_id: impl Into<UserId>) -> bool {
|
||||
offline!(true);
|
||||
|
||||
if let Some(subscription_guild) = *CNC_GUILD {
|
||||
let guild_member = GuildId::new(subscription_guild).member(cache_http, user_id).await;
|
||||
|
||||
if let Ok(member) = guild_member {
|
||||
for role in member.roles {
|
||||
if SUBSCRIPTION_ROLES.contains(&role.get()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
} else {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn check_guild_subscription(
|
||||
cache_http: impl CacheHttp,
|
||||
guild_id: impl Into<GuildId>,
|
||||
) -> bool {
|
||||
offline!(true);
|
||||
|
||||
if let Some(owner) = cache_http.cache().unwrap().guild(guild_id).map(|guild| guild.owner_id) {
|
||||
check_subscription(&cache_http, owner).await
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn check_authorization(
|
||||
cookies: &CookieJar<'_>,
|
||||
ctx: &Context,
|
||||
|
@@ -12,8 +12,9 @@ use serenity::{
|
||||
};
|
||||
use sqlx::{MySql, Pool};
|
||||
|
||||
use crate::utils::check_subscription;
|
||||
use crate::web::{
|
||||
check_authorization, check_guild_subscription, check_subscription,
|
||||
check_authorization,
|
||||
consts::MIN_INTERVAL,
|
||||
guards::transaction::Transaction,
|
||||
routes::{
|
||||
@@ -186,8 +187,13 @@ pub async fn edit_reminder(
|
||||
|| reminder.interval_months.flatten().is_some()
|
||||
|| reminder.interval_seconds.flatten().is_some()
|
||||
{
|
||||
if check_guild_subscription(&ctx.inner(), id).await
|
||||
|| check_subscription(&ctx.inner(), user_id).await
|
||||
if check_subscription(
|
||||
ctx.inner(),
|
||||
transaction.executor(),
|
||||
UserId::from(user_id),
|
||||
Some(GuildId::from(id)),
|
||||
)
|
||||
.await
|
||||
{
|
||||
let new_interval_length = match reminder.interval_days {
|
||||
Some(interval) => interval.unwrap_or(0),
|
||||
|
@@ -6,8 +6,8 @@ use serde::{Deserialize, Serialize};
|
||||
use serenity::{client::Context, model::id::UserId};
|
||||
use sqlx::types::Json;
|
||||
|
||||
use crate::utils::check_subscription;
|
||||
use crate::web::{
|
||||
check_subscription,
|
||||
consts::{
|
||||
DAY, MAX_CONTENT_LENGTH, MAX_EMBED_AUTHOR_LENGTH, MAX_EMBED_DESCRIPTION_LENGTH,
|
||||
MAX_EMBED_FIELDS, MAX_EMBED_FIELD_TITLE_LENGTH, MAX_EMBED_FIELD_VALUE_LENGTH,
|
||||
@@ -131,7 +131,7 @@ pub async fn create_reminder(
|
||||
|| reminder.interval_days.is_some()
|
||||
|| reminder.interval_months.is_some()
|
||||
{
|
||||
if !check_subscription(&ctx, user_id).await {
|
||||
if !check_subscription(&ctx, transaction.executor(), user_id, None).await {
|
||||
return Err(json!({"error": "Patreon is required to set intervals"}));
|
||||
}
|
||||
}
|
||||
|
@@ -9,8 +9,8 @@ use rocket::{
|
||||
use serenity::{client::Context, model::id::UserId};
|
||||
use sqlx::{MySql, Pool};
|
||||
|
||||
use crate::utils::check_subscription;
|
||||
use crate::web::{
|
||||
check_subscription,
|
||||
guards::transaction::Transaction,
|
||||
routes::{
|
||||
dashboard::{
|
||||
@@ -162,7 +162,9 @@ pub async fn edit_reminder(
|
||||
|| reminder.interval_months.flatten().is_some()
|
||||
|| reminder.interval_seconds.flatten().is_some()
|
||||
{
|
||||
if check_subscription(&ctx.inner(), user_id).await {
|
||||
if check_subscription(&ctx.inner(), transaction.executor(), UserId::from(user_id), None)
|
||||
.await
|
||||
{
|
||||
let new_interval_length = match reminder.interval_days {
|
||||
Some(interval) => interval.unwrap_or(0),
|
||||
None => sqlx::query!(
|
||||
|
@@ -20,9 +20,9 @@ use serenity::{
|
||||
use sqlx::types::Json;
|
||||
use sqlx::FromRow;
|
||||
|
||||
use crate::utils::check_subscription;
|
||||
use crate::web::{
|
||||
catchers::internal_server_error,
|
||||
check_guild_subscription, check_subscription,
|
||||
consts::{
|
||||
CHARACTERS, DAY, DEFAULT_AVATAR, MAX_CONTENT_LENGTH, MAX_EMBED_AUTHOR_LENGTH,
|
||||
MAX_EMBED_DESCRIPTION_LENGTH, MAX_EMBED_FIELDS, MAX_EMBED_FIELD_TITLE_LENGTH,
|
||||
@@ -477,9 +477,7 @@ pub(crate) async fn create_reminder(
|
||||
|| reminder.interval_days.is_some()
|
||||
|| reminder.interval_months.is_some()
|
||||
{
|
||||
if !check_guild_subscription(&ctx, guild_id).await
|
||||
&& !check_subscription(&ctx, user_id).await
|
||||
{
|
||||
if !check_subscription(&ctx, transaction.executor(), user_id, Some(guild_id)).await {
|
||||
return Err(json!({"error": "Patreon is required to set intervals"}));
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user