merge: branch 'master' into webhooks

This commit is contained in:
Paul Makles
2023-06-02 18:55:32 +01:00
80 changed files with 3511 additions and 312 deletions

View File

@@ -184,6 +184,7 @@ pub enum EventV1 {
id: String,
data: PartialUser,
clear: Vec<FieldsUser>,
event_id: Option<String>,
},
/// Relationship with another user changed

View File

@@ -302,6 +302,7 @@ impl State {
..Default::default()
},
clear: vec![],
event_id: Some(ulid::Ulid::new().to_string()),
};
for server in self.cache.servers.keys() {
@@ -499,6 +500,17 @@ impl State {
}
}
EventV1::UserUpdate { event_id, .. } => {
if let Some(id) = event_id {
if self.cache.seen_events.contains(id) {
return false;
}
self.cache.seen_events.put(id.to_string(), ());
}
*event_id = None;
}
EventV1::UserRelationship { id, user, .. } => {
self.cache.users.insert(id.clone(), user.clone());
@@ -508,6 +520,7 @@ impl State {
self.remove_subscription(id);
}
}
_ => {}
}

View File

@@ -1,5 +1,7 @@
use std::collections::{HashMap, HashSet};
use lru::LruCache;
use crate::models::{Channel, Member, Server, User};
/// Enumeration representing some change in subscriptions
@@ -26,7 +28,7 @@ pub enum SubscriptionStateChange {
/// ------------------------------------------------
/// We can strip these objects to core information!!
/// ------------------------------------------------
#[derive(Debug, Default)]
#[derive(Debug)]
pub struct Cache {
pub user_id: String,
@@ -34,6 +36,23 @@ pub struct Cache {
pub channels: HashMap<String, Channel>,
pub members: HashMap<String, Member>,
pub servers: HashMap<String, Server>,
pub seen_events: LruCache<String, ()>,
}
impl Default for Cache {
fn default() -> Self {
Cache {
user_id: Default::default(),
users: Default::default(),
channels: Default::default(),
members: Default::default(),
servers: Default::default(),
seen_events: LruCache::new(20),
}
}
}
/// Client state

View File

@@ -10,7 +10,7 @@ impl AbstractSnapshot for DummyDb {
Ok(())
}
async fn fetch_snapshot(&self, _report_id: &str) -> Result<Snapshot> {
async fn fetch_snapshots(&self, _report_id: &str) -> Result<Vec<Snapshot>> {
todo!()
}
}

View File

@@ -27,4 +27,5 @@ pub mod users {
pub mod safety {
pub mod report;
pub mod snapshot;
}

View File

@@ -1,9 +1,30 @@
use crate::{models::report::PartialReport, models::Report, Database, Result};
use iso8601_timestamp::Timestamp;
use crate::{
models::report::PartialReport,
models::{report::ReportStatus, Report},
Database, Result,
};
impl Report {
/// Update report data
pub async fn update(&mut self, db: &Database, partial: PartialReport) -> Result<()> {
self.apply_options(partial.clone());
match &mut self.status {
ReportStatus::Created {} => {}
ReportStatus::Rejected { closed_at, .. } => {
if closed_at.is_none() {
closed_at.replace(Timestamp::now_utc());
}
}
ReportStatus::Resolved { closed_at } => {
if closed_at.is_none() {
closed_at.replace(Timestamp::now_utc());
}
}
}
db.update_report(&self.id, &partial).await
}
}

View File

@@ -0,0 +1,88 @@
use crate::{
models::{
message::{MessageFilter, MessageQuery, MessageSort, MessageTimePeriod},
snapshot::SnapshotContent,
Message, Server, User,
},
Database, Result,
};
impl SnapshotContent {
pub async fn generate_from_message(
db: &Database,
message: Message,
) -> Result<(SnapshotContent, Vec<String>)> {
// Collect message attachments
let files = message
.attachments
.as_ref()
.map(|attachments| attachments.iter().map(|x| x.id.to_string()).collect())
.unwrap_or_default();
// Collect prior context
let prior_context = db
.fetch_messages(MessageQuery {
filter: MessageFilter {
channel: Some(message.channel.to_string()),
..Default::default()
},
limit: Some(15),
time_period: MessageTimePeriod::Absolute {
before: Some(message.id.to_string()),
after: None,
sort: Some(MessageSort::Latest),
},
})
.await?;
// Collect leading context
let leading_context = db
.fetch_messages(MessageQuery {
filter: MessageFilter {
channel: Some(message.channel.to_string()),
..Default::default()
},
limit: Some(15),
time_period: MessageTimePeriod::Absolute {
before: None,
after: Some(message.id.to_string()),
sort: Some(MessageSort::Oldest),
},
})
.await?;
Ok((
SnapshotContent::Message {
message,
prior_context,
leading_context,
},
files,
))
}
pub fn generate_from_server(server: Server) -> Result<(SnapshotContent, Vec<String>)> {
// Collect server's icon and banner
let files = [&server.icon, &server.banner]
.iter()
.filter_map(|x| x.as_ref().map(|x| x.id.to_string()))
.collect();
Ok((SnapshotContent::Server(server), files))
}
pub fn generate_from_user(user: User) -> Result<(SnapshotContent, Vec<String>)> {
// Collect user's avatar and profile background
let files = [
user.avatar.as_ref(),
user.profile
.as_ref()
.and_then(|profile| profile.background.as_ref()),
]
.iter()
.filter_map(|x| x.as_ref().map(|x| x.id.to_string()))
.collect();
Ok((SnapshotContent::User(user), files))
}
}

View File

@@ -33,6 +33,7 @@ impl User {
id: self.id.clone(),
data: partial,
clear: remove,
event_id: Some(ulid::Ulid::new().to_string()),
}
.p_user(self.id.clone(), db)
.await;

View File

@@ -11,8 +11,8 @@ impl AbstractSnapshot for MongoDb {
self.insert_one(COL, snapshot).await.map(|_| ())
}
async fn fetch_snapshot(&self, report_id: &str) -> Result<Snapshot> {
self.find_one(
async fn fetch_snapshots(&self, report_id: &str) -> Result<Vec<Snapshot>> {
self.find(
COL,
doc! {
"report_id": report_id

View File

@@ -1,205 +0,0 @@
<mxfile host="65bd71144e">
<diagram id="9BKyaxnbqnTkbfLuLd1z" name="Page-1">
<mxGraphModel dx="1033" dy="710" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<mxCell id="56" style="edgeStyle=orthogonalEdgeStyle;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;startArrow=none;startFill=0;endArrow=diamondThin;endFill=0;strokeColor=#B3B3B3;dashed=1;" parent="1" source="2" target="6" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="57" style="edgeStyle=orthogonalEdgeStyle;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.75;entryY=1;entryDx=0;entryDy=0;startArrow=none;startFill=0;endArrow=diamondThin;endFill=0;strokeColor=#B3B3B3;dashed=1;" parent="1" source="2" target="5" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="260" y="370"/>
<mxPoint x="275" y="370"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="58" style="edgeStyle=orthogonalEdgeStyle;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.25;entryY=1;entryDx=0;entryDy=0;startArrow=none;startFill=0;endArrow=diamondThin;endFill=0;strokeColor=#B3B3B3;dashed=1;" parent="1" source="2" target="9" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="260" y="370"/>
<mxPoint x="342" y="370"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="59" style="edgeStyle=orthogonalEdgeStyle;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;startArrow=none;startFill=0;endArrow=diamondThin;endFill=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;strokeColor=#B3B3B3;dashed=1;" parent="1" source="2" target="12" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="300" y="250" as="targetPoint"/>
<Array as="points">
<mxPoint x="260" y="370"/>
<mxPoint x="300" y="370"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="2" value="Attachment" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="220" y="490" width="80" height="30" as="geometry"/>
</mxCell>
<mxCell id="49" style="edgeStyle=orthogonalEdgeStyle;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.25;entryY=1;entryDx=0;entryDy=0;startArrow=none;startFill=0;endArrow=diamondThin;endFill=1;" parent="1" source="3" target="5" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="195" y="340"/>
<mxPoint x="245" y="340"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="51" style="edgeStyle=orthogonalEdgeStyle;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;startArrow=none;startFill=0;endArrow=diamondThin;endFill=1;entryX=0.25;entryY=1;entryDx=0;entryDy=0;" parent="1" source="3" target="12" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="290" y="160" as="targetPoint"/>
<Array as="points">
<mxPoint x="195" y="260"/>
<mxPoint x="260" y="260"/>
<mxPoint x="260" y="220"/>
<mxPoint x="290" y="220"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="3" value="Channel Invite" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="150" y="400" width="90" height="30" as="geometry"/>
</mxCell>
<mxCell id="4" value="Channel Unread" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="40" y="400" width="100" height="30" as="geometry"/>
</mxCell>
<mxCell id="43" style="edgeStyle=orthogonalEdgeStyle;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.25;entryY=1;entryDx=0;entryDy=0;startArrow=none;startFill=0;endArrow=diamondThin;endFill=1;dashed=1;" parent="1" source="5" target="12" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="60" style="edgeStyle=orthogonalEdgeStyle;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;dashed=1;startArrow=none;startFill=0;endArrow=diamondThin;endFill=1;strokeColor=#FFFFFF;" parent="1" source="5" target="9" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="5" value="Channel" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="230" y="280" width="60" height="30" as="geometry"/>
</mxCell>
<mxCell id="45" style="edgeStyle=orthogonalEdgeStyle;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.75;entryY=1;entryDx=0;entryDy=0;startArrow=none;startFill=0;endArrow=diamondThin;endFill=1;" parent="1" source="6" target="12" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="46" style="edgeStyle=orthogonalEdgeStyle;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;startArrow=none;startFill=0;endArrow=diamondThin;endFill=1;" parent="1" source="6" target="5" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="310" y="355"/>
<mxPoint x="260" y="355"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="6" value="Message" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="280" y="400" width="60" height="30" as="geometry"/>
</mxCell>
<mxCell id="54" style="edgeStyle=orthogonalEdgeStyle;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;startArrow=none;startFill=0;endArrow=diamondThin;endFill=1;" parent="1" source="7" target="9" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="505" y="350"/>
<mxPoint x="355" y="350"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="7" value="Server Ban" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="470" y="400" width="70" height="30" as="geometry"/>
</mxCell>
<mxCell id="47" style="edgeStyle=orthogonalEdgeStyle;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;startArrow=none;startFill=0;endArrow=diamondThin;endFill=1;" parent="1" source="8" target="9" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="405" y="350"/>
<mxPoint x="355" y="350"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="48" style="edgeStyle=orthogonalEdgeStyle;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.75;entryY=1;entryDx=0;entryDy=0;startArrow=none;startFill=0;endArrow=diamondThin;endFill=1;" parent="1" source="8" target="12" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="405" y="350"/>
<mxPoint x="310" y="350"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="8" value="Server Member" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="360" y="400" width="90" height="30" as="geometry"/>
</mxCell>
<mxCell id="29" style="edgeStyle=orthogonalEdgeStyle;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;endArrow=diamondThin;endFill=1;startArrow=diamondThin;startFill=1;" parent="1" source="10" target="12" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="240" y="145"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="10" value="Bot" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="200" y="130" width="40" height="30" as="geometry"/>
</mxCell>
<mxCell id="31" style="edgeStyle=orthogonalEdgeStyle;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.25;entryY=1;entryDx=0;entryDy=0;startArrow=none;startFill=0;endArrow=diamondThin;endFill=1;" parent="1" source="11" target="12" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="11" value="User Settings" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="150" y="210" width="90" height="30" as="geometry"/>
</mxCell>
<mxCell id="15" style="edgeStyle=orthogonalEdgeStyle;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;endArrow=diamondThin;endFill=1;" parent="1" source="12" target="13" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="12" value="User" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="280" y="130" width="40" height="30" as="geometry"/>
</mxCell>
<mxCell id="13" value="Account" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="310" y="40" width="60" height="30" as="geometry"/>
</mxCell>
<mxCell id="17" style="edgeStyle=orthogonalEdgeStyle;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;endArrow=diamondThin;endFill=1;" parent="1" source="14" target="13" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="14" value="Session" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="350" y="130" width="60" height="30" as="geometry"/>
</mxCell>
<mxCell id="44" style="edgeStyle=orthogonalEdgeStyle;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;startArrow=none;startFill=0;endArrow=diamondThin;endFill=1;entryX=0.75;entryY=1;entryDx=0;entryDy=0;" parent="1" source="9" target="12" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="310" y="160" as="targetPoint"/>
<Array as="points">
<mxPoint x="355" y="220"/>
<mxPoint x="310" y="220"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="9" value="Server" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="330" y="280" width="50" height="30" as="geometry"/>
</mxCell>
<mxCell id="55" style="edgeStyle=orthogonalEdgeStyle;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;startArrow=none;startFill=0;endArrow=diamondThin;endFill=1;" parent="1" source="4" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="290" y="160" as="targetPoint"/>
<mxPoint x="200" y="400" as="sourcePoint"/>
<Array as="points">
<mxPoint x="90" y="370"/>
<mxPoint x="195" y="370"/>
<mxPoint x="195" y="260"/>
<mxPoint x="260" y="260"/>
<mxPoint x="260" y="220"/>
<mxPoint x="290" y="220"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="63" value="" style="edgeStyle=orthogonalEdgeStyle;html=1;startArrow=none;startFill=0;endArrow=diamondThin;endFill=0;strokeColor=#FFFFFF;entryX=1;entryY=1;entryDx=0;entryDy=0;" parent="1" source="61" target="12" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="584.25" y="335" as="targetPoint"/>
<Array as="points">
<mxPoint x="584" y="340"/>
<mxPoint x="390" y="340"/>
<mxPoint x="390" y="210"/>
<mxPoint x="320" y="210"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="64" style="edgeStyle=orthogonalEdgeStyle;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.75;entryY=1;entryDx=0;entryDy=0;startArrow=none;startFill=0;endArrow=diamondThin;endFill=1;strokeColor=#FFFFFF;" parent="1" source="61" target="9" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="584" y="340"/>
<mxPoint x="368" y="340"/>
<mxPoint x="368" y="310"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="61" value="Emoji" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="558.5" y="400" width="51.5" height="30" as="geometry"/>
</mxCell>
<mxCell id="65" style="edgeStyle=orthogonalEdgeStyle;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;startArrow=none;startFill=0;endArrow=diamondThin;endFill=0;strokeColor=#B3B3B3;dashed=1;" parent="1" source="2" target="61" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="270" y="500" as="sourcePoint"/>
<mxPoint x="320" y="440" as="targetPoint"/>
</mxGeometry>
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

View File

@@ -1,3 +1,5 @@
use iso8601_timestamp::Timestamp;
use rocket::FromFormField;
use serde::{Deserialize, Serialize};
/// Reason for reporting content (message or server)
@@ -6,16 +8,41 @@ pub enum ContentReportReason {
/// No reason has been specified
NoneSpecified,
/// Blatantly illegal content
/// Illegal content catch-all reason
Illegal,
/// Selling or facilitating use of drugs or other illegal goods
IllegalGoods,
/// Extortion or blackmail
IllegalExtortion,
/// Revenge or child pornography
IllegalPornography,
/// Illegal hacking activity
IllegalHacking,
/// Extreme violence, gore, or animal cruelty
/// With exception to violence potrayed in media / creative arts
ExtremeViolence,
/// Content that promotes harm to others / self
PromotesHarm,
/// Unsolicited advertisements
UnsolicitedSpam,
/// This is a raid
Raid,
/// Spam or platform abuse
SpamAbuse,
/// Distribution of malware
/// Scams or fraud
ScamsFraud,
/// Distribution of malware or malicious links
Malware,
/// Harassment or abuse targeted at another user
@@ -28,6 +55,9 @@ pub enum UserReportReason {
/// No reason has been specified
NoneSpecified,
/// Unsolicited advertisements
UnsolicitedSpam,
/// User is sending spam or otherwise abusing the platform
SpamAbuse,
@@ -68,6 +98,8 @@ pub enum ReportedContent {
id: String,
/// Reason for reporting a user
report_reason: UserReportReason,
/// Message context
message_id: Option<String>,
},
}
@@ -79,10 +111,26 @@ pub enum ReportStatus {
Created {},
/// Report was rejected
Rejected { rejection_reason: String },
Rejected {
rejection_reason: String,
closed_at: Option<Timestamp>,
},
/// Report was actioned and resolved
Resolved {},
Resolved { closed_at: Option<Timestamp> },
}
/// Just the status of the report
#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone, FromFormField)]
pub enum ReportStatusString {
/// Report is waiting for triage / action
Created,
/// Report was rejected
Rejected,
/// Report was actioned and resolved
Resolved,
}
/// User-generated platform moderation report.

View File

@@ -2,8 +2,8 @@
use crate::Database;
use deadqueue::limited::Queue;
use std::{collections::HashMap, time::Duration};
use once_cell::sync::Lazy;
use std::{collections::HashMap, time::Duration};
use super::DelayedTask;
@@ -95,7 +95,7 @@ pub async fn worker(db: Database) {
}) = Q.try_pop()
{
let key = (user, channel);
if let Some(mut task) = tasks.get_mut(&key) {
if let Some(task) = tasks.get_mut(&key) {
task.delay();
match &mut event {

View File

@@ -2,8 +2,8 @@
use crate::{models::channel::PartialChannel, Database};
use deadqueue::limited::Queue;
use std::{collections::HashMap, time::Duration};
use once_cell::sync::Lazy;
use std::{collections::HashMap, time::Duration};
use super::DelayedTask;
@@ -73,7 +73,7 @@ pub async fn worker(db: Database) {
// Queue incoming tasks.
while let Some(Data { channel, id, is_dm }) = Q.try_pop() {
if let Some(mut task) = tasks.get_mut(&channel) {
if let Some(task) = tasks.get_mut(&channel) {
task.data.id = id;
task.delay();
} else {

View File

@@ -6,6 +6,6 @@ pub trait AbstractSnapshot: Sync + Send {
/// Insert a new snapshot into the database
async fn insert_snapshot(&self, snapshot: &Snapshot) -> Result<()>;
/// Fetch a snapshot by a report's id
async fn fetch_snapshot(&self, report_id: &str) -> Result<Snapshot>;
/// Fetch a snapshots by a report's id
async fn fetch_snapshots(&self, report_id: &str) -> Result<Vec<Snapshot>>;
}

View File

@@ -41,7 +41,7 @@ pub static SMTP_FROM: Lazy<String> = Lazy::new(|| env::var("REVOLT_SMTP_FROM").u
// Application Logic Settings
pub static MAX_GROUP_SIZE: Lazy<usize> = Lazy::new(|| env::var("REVOLT_MAX_GROUP_SIZE").unwrap_or_else(|_| "50".to_string()).parse().unwrap());
pub static MAX_BOT_COUNT: Lazy<usize> = Lazy::new(|| env::var("REVOLT_MAX_BOT_COUNT").unwrap_or_else(|_| "5".to_string()).parse().unwrap());
pub static MAX_BOT_COUNT: Lazy<usize> = Lazy::new(|| env::var("REVOLT_MAX_BOT_COUNT").unwrap_or_else(|_| "10".to_string()).parse().unwrap());
pub static MAX_EMBED_COUNT: Lazy<usize> = Lazy::new(|| env::var("REVOLT_MAX_EMBED_COUNT").unwrap_or_else(|_| "5".to_string()).parse().unwrap());
pub static MAX_SERVER_COUNT: Lazy<usize> = Lazy::new(|| env::var("REVOLT_MAX_SERVER_COUNT").unwrap_or_else(|_| "100".to_string()).parse().unwrap());
pub static MAX_CHANNEL_COUNT: Lazy<usize> = Lazy::new(|| env::var("REVOLT_MAX_CHANNEL_COUNT").unwrap_or_else(|_| "200".to_string()).parse().unwrap());