tangled
alpha
login
or
join now
zzstoatzz.io
/
status
0
fork
atom
slack status without the slack
status.zzstoatzz.io/
quickslice
0
fork
atom
overview
issues
pulls
pipelines
fix(clippy): remove unused import after extraction
zzstoatzz.io
6 months ago
a6290d15
24e08bf7
+45
-51
3 changed files
expand all
collapse all
unified
split
src
api
mod.rs
status.rs
status_util.rs
+1
src/api/mod.rs
···
1
1
pub mod auth;
2
2
pub mod preferences;
3
3
pub mod status;
4
4
+
pub mod status_util;
4
5
pub mod webhooks;
5
6
6
7
pub use auth::OAuthClientType;
+4
-51
src/api/status.rs
···
10
10
lexicons::record::KnownRecord,
11
11
rate_limiter::RateLimiter,
12
12
templates::{ErrorTemplate, FeedTemplate, Profile, StatusTemplate},
13
13
-
webhooks::{StatusEvent, send_status_event},
14
13
};
15
14
use actix_multipart::Multipart;
16
15
use actix_session::Session;
···
31
30
};
32
31
use atrium_oauth::DefaultHttpClient;
33
32
use futures_util::TryStreamExt as _;
34
34
-
use serde::{Deserialize, Serialize};
33
33
+
use serde::Serialize;
35
34
use std::{collections::HashMap, sync::Arc};
36
35
37
36
/// HandleResolver to make it easier to access the OAuthClient in web requests
···
45
44
did == ADMIN_DID
46
45
}
47
46
48
48
-
/// The post body for changing your status
49
49
-
#[derive(Serialize, Deserialize, Clone)]
50
50
-
pub struct StatusForm {
51
51
-
pub status: String,
52
52
-
pub text: Option<String>,
53
53
-
pub expires_in: Option<String>, // e.g., "1h", "30m", "1d", etc.
54
54
-
}
55
55
-
56
56
-
/// The post body for deleting a specific status
57
57
-
#[derive(Serialize, Deserialize)]
58
58
-
pub struct DeleteRequest {
59
59
-
pub uri: String,
60
60
-
}
61
61
-
62
62
-
/// Hide/unhide a status (admin only)
63
63
-
#[derive(Deserialize)]
64
64
-
pub struct HideStatusRequest {
65
65
-
pub uri: String,
66
66
-
pub hidden: bool,
67
67
-
}
68
68
-
69
69
-
/// Parse duration string like "1h", "30m", "1d" into chrono::Duration
70
70
-
fn parse_duration(duration_str: &str) -> Option<chrono::Duration> {
71
71
-
if duration_str.is_empty() {
72
72
-
return None;
73
73
-
}
74
74
-
75
75
-
let (num_str, unit) = duration_str.split_at(duration_str.len() - 1);
76
76
-
let num: i64 = num_str.parse().ok()?;
77
77
-
78
78
-
match unit {
79
79
-
"m" => Some(chrono::Duration::minutes(num)),
80
80
-
"h" => Some(chrono::Duration::hours(num)),
81
81
-
"d" => Some(chrono::Duration::days(num)),
82
82
-
"w" => Some(chrono::Duration::weeks(num)),
83
83
-
_ => None,
84
84
-
}
85
85
-
}
47
47
+
use crate::api::status_util::{DeleteRequest, HideStatusRequest, StatusForm, parse_duration};
86
48
87
49
/// Homepage - shows logged-in user's status, or owner's status if not logged in
88
50
#[get("/")]
···
1252
1214
let did_for_event = did_string.clone();
1253
1215
let uri = req.uri.clone();
1254
1216
tokio::spawn(async move {
1255
1255
-
let event = StatusEvent {
1256
1256
-
event: "status.deleted",
1257
1257
-
did: &did_for_event,
1258
1258
-
handle: None,
1259
1259
-
status: None,
1260
1260
-
text: None,
1261
1261
-
uri: Some(&uri),
1262
1262
-
since: None,
1263
1263
-
expires: None,
1264
1264
-
};
1265
1265
-
send_status_event(pool, &did_for_event, event).await;
1217
1217
+
crate::webhooks::emit_deleted(pool, &did_for_event, &uri)
1218
1218
+
.await;
1266
1219
});
1267
1220
}
1268
1221
+40
src/api/status_util.rs
···
1
1
+
use serde::{Deserialize, Serialize};
2
2
+
3
3
+
/// The post body for changing your status
4
4
+
#[derive(Serialize, Deserialize, Clone)]
5
5
+
pub struct StatusForm {
6
6
+
pub status: String,
7
7
+
pub text: Option<String>,
8
8
+
pub expires_in: Option<String>, // e.g., "1h", "30m", "1d", etc.
9
9
+
}
10
10
+
11
11
+
/// The post body for deleting a specific status
12
12
+
#[derive(Serialize, Deserialize)]
13
13
+
pub struct DeleteRequest {
14
14
+
pub uri: String,
15
15
+
}
16
16
+
17
17
+
/// Hide/unhide a status (admin only)
18
18
+
#[derive(Deserialize)]
19
19
+
pub struct HideStatusRequest {
20
20
+
pub uri: String,
21
21
+
pub hidden: bool,
22
22
+
}
23
23
+
24
24
+
/// Parse duration string like "1h", "30m", "1d" into chrono::Duration
25
25
+
pub fn parse_duration(duration_str: &str) -> Option<chrono::Duration> {
26
26
+
if duration_str.is_empty() {
27
27
+
return None;
28
28
+
}
29
29
+
30
30
+
let (num_str, unit) = duration_str.split_at(duration_str.len() - 1);
31
31
+
let num: i64 = num_str.parse().ok()?;
32
32
+
33
33
+
match unit {
34
34
+
"m" => Some(chrono::Duration::minutes(num)),
35
35
+
"h" => Some(chrono::Duration::hours(num)),
36
36
+
"d" => Some(chrono::Duration::days(num)),
37
37
+
"w" => Some(chrono::Duration::weeks(num)),
38
38
+
_ => None,
39
39
+
}
40
40
+
}