forked from jmug/stoatchat
merge: branch 'master' into webhooks
This commit is contained in:
@@ -184,6 +184,7 @@ pub enum EventV1 {
|
||||
id: String,
|
||||
data: PartialUser,
|
||||
clear: Vec<FieldsUser>,
|
||||
event_id: Option<String>,
|
||||
},
|
||||
|
||||
/// Relationship with another user changed
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
_ => {}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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!()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,4 +27,5 @@ pub mod users {
|
||||
|
||||
pub mod safety {
|
||||
pub mod report;
|
||||
pub mod snapshot;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
88
crates/quark/src/impl/generic/safety/snapshot.rs
Normal file
88
crates/quark/src/impl/generic/safety/snapshot.rs
Normal 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))
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
@@ -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.
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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>>;
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
Reference in New Issue
Block a user