1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
use crate::routes::dtos::{Error, Response};
use libangelshark::{AcmRunner, Message, ParallelIterator};
use log::error;
use serde::Deserialize;
use warp::{
body::{content_length_limit, json},
hyper::StatusCode,
path, post, reply, Filter, Rejection, Reply,
};
const SIXTEEN_K: u64 = 1024 * 16;
pub fn busy_filter(
runner: AcmRunner,
) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
post()
.and(path!("service" / "busyout" / ..))
.and(content_length_limit(SIXTEEN_K))
.and(json())
.map(move |entries| queue_and_run(entries, "busyout", runner.to_owned()))
}
pub fn release_filter(
runner: AcmRunner,
) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
post()
.and(path!("service" / "release" / ..))
.and(content_length_limit(SIXTEEN_K))
.and(json())
.map(move |entries| queue_and_run(entries, "release", runner.to_owned()))
}
pub fn toggle_filter(
runner: AcmRunner,
) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
post()
.and(path!("service" / "toggle" / ..))
.and(content_length_limit(SIXTEEN_K))
.and(json())
.map(move |entries| queue_and_run(entries, "toggle", runner.to_owned()))
}
fn queue_and_run(entries: Entries, command: &str, mut runner: AcmRunner) -> impl Reply {
for entry in entries.into_iter() {
if command == "toggle" {
runner.queue_input(
&entry.acm,
&Message::new(&format!("busyout station {}", entry.ext)),
);
runner.queue_input(
&entry.acm,
&Message::new(&format!("release station {}", entry.ext)),
);
} else {
runner.queue_input(
&entry.acm,
&Message::new(&format!("{} station {}", command, entry.ext)),
);
}
}
// generate output on runner
let output: Result<Vec<Vec<_>>, _> = runner
.run()
.map(|(name, output)| -> Result<Vec<Response>, anyhow::Error> {
Ok(output?
.into_iter()
.filter_map(move |msg| {
(msg.command != "logoff").then(|| Response::from((name.to_owned(), msg)))
})
.collect())
})
.collect();
// handle errors and package output as json
match output {
Err(e) => {
error!("busyout-release extension: {}", e);
reply::with_status(
reply::json(&Error {
reason: e.to_string(),
}),
StatusCode::INTERNAL_SERVER_ERROR,
)
}
Ok(r) => reply::with_status(
reply::json(&r.into_iter().flatten().collect::<Vec<_>>()),
StatusCode::OK,
),
}
}
type Entries = Vec<Entry>;
#[derive(Debug, Deserialize)]
struct Entry {
acm: String,
ext: String,
}
|