1use futures_util::{Stream, StreamExt};
2use tokio_util::sync::CancellationToken;
3use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
4
5pub use crate::web::{ApiChannelMessage, App, ImageContainer};
6
7mod db;
8mod users;
9mod web;
10
11pub use {
12 db::Camera, db::CameraPermission, db::CameraPermissionUserView, db::CameraPermissionView,
13 db::CameraSetting, db::CameraSettingNoMeta, db::Model, db::User, db::Video,
14 db::VideoCameraView,
15};
16
17pub fn or_until_shutdown<S>(
22 stream: S,
23 shutdown_token: CancellationToken,
24) -> impl Stream<Item = S::Item>
25where
26 S: Stream,
27{
28 async_stream::stream! {
29 futures_util::pin_mut!(stream);
30
31 loop {
32 tokio::select! {
33 Some(item) = stream.next() => {
34 yield item
35 }
36 () = shutdown_token.cancelled() => {
37 break;
38 }
39 }
40 }
41 }
42}
43
44pub async fn run() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
45 tracing_subscriber::registry()
48 .with(
49 tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| {
50 format!(
51 "{}=debug,axum_login=debug,tower_sessions=debug,sqlx=warn,tower_http=debug",
52 env!("CARGO_CRATE_NAME")
53 )
54 .into()
55 }),
56 )
57 .with(tracing_subscriber::fmt::layer().compact().without_time())
58 .try_init()?;
59
60 App::new().await?.serve().await?;
62
63 Ok(())
64}