initial git dump
This commit is contained in:
commit
781e25470b
47 changed files with 2361 additions and 0 deletions
231
turnerbund/:w
Normal file
231
turnerbund/:w
Normal file
|
|
@ -0,0 +1,231 @@
|
|||
use tracing_subscriber::prelude::*;
|
||||
use tracing_subscriber::{fmt, EnvFilter};
|
||||
pub use tracing::{error, warn, info, debug, trace};
|
||||
|
||||
#[cfg(feature="disabled")]
|
||||
mod disabled {
|
||||
|
||||
//mod select;
|
||||
//use select::WeightedSet;
|
||||
mod api;
|
||||
mod utils;
|
||||
mod id;
|
||||
mod user;
|
||||
|
||||
use tracing_subscriber::prelude::*;
|
||||
use tracing_subscriber::{fmt, EnvFilter};
|
||||
pub use tracing::{error, warn, info, debug, trace};
|
||||
|
||||
use rand::prelude::*;
|
||||
use std::collections::HashSet;
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum NoError {}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Eq, Hash, PartialEq, PartialOrd, Ord)]
|
||||
struct UserID(u128);
|
||||
|
||||
impl std::fmt::Display for UserID {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "UserID({})", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct Participants(Vec<(UserID, usize)>);
|
||||
|
||||
trait Event {
|
||||
fn registered(&self, uid: UserID) -> bool;
|
||||
fn participated(&self, uid: UserID) -> bool { self.registered(uid) }
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct MockEvent {
|
||||
id: usize,
|
||||
users: HashMap<UserID, bool>,
|
||||
}
|
||||
|
||||
impl MockEvent {
|
||||
fn new(id: usize, registrants: HashSet<UserID>, participants: HashSet<UserID>) -> Self {
|
||||
let users = registrants.into_iter()
|
||||
.map(|uid| (uid, participants.contains(&uid)))
|
||||
.collect();
|
||||
Self { id, users }
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for MockEvent {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "MockEvent{}({:?})", self.id, self.users)
|
||||
}
|
||||
}
|
||||
|
||||
impl Event for &MockEvent {
|
||||
fn registered(&self, uid: UserID) -> bool {
|
||||
self.users.get(&uid).is_some()
|
||||
}
|
||||
|
||||
fn participated(&self, uid: UserID) -> bool {
|
||||
self.users.get(&uid).is_some_and(|participated|*participated)
|
||||
}
|
||||
}
|
||||
|
||||
impl Participants {
|
||||
pub fn add(mut self, uid: UserID) -> Self {
|
||||
self.0.push((uid, 1));
|
||||
self
|
||||
}
|
||||
|
||||
pub fn select<H>(mut self, history: H, rng: &mut impl Rng, count: usize)
|
||||
-> HashSet<UserID>
|
||||
where
|
||||
H: Iterator,
|
||||
<H as Iterator>::Item: Event,
|
||||
{
|
||||
for event in history {
|
||||
let mut modified = false;
|
||||
for item in self.0.iter_mut() {
|
||||
if event.registered(item.0) && !event.participated(item.0) {
|
||||
modified = true;
|
||||
item.1 += 1;
|
||||
}
|
||||
}
|
||||
if !modified {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
println!("{:?}", self.0);
|
||||
|
||||
self.0.sample_weighted(rng, count, |item: &'_ (_, usize)| item.1 as f64)
|
||||
.unwrap()
|
||||
.map(|item| item.0)
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
async fn connect<'a, I: spond::auth::Identifier + From<&'a str>>(id: &'a str) -> Result<spond::Api, spond::error::Api> {
|
||||
let pw = std::env::var("SPOND_PASSWORD").expect("a password is required in SPOND_PASSWORD");
|
||||
let id: I = id.into();
|
||||
let auth = spond::auth::Login::new(id, pw);
|
||||
let client = spond::Api::new(auth).await?;
|
||||
Ok(client)
|
||||
}
|
||||
|
||||
async fn main() -> anyhow::Result<()> {
|
||||
let filter = EnvFilter::try_from_default_env()
|
||||
.unwrap_or_else(|_| EnvFilter::new("info"));
|
||||
tracing_subscriber::registry()
|
||||
.with(fmt::layer().pretty())
|
||||
.with(filter)
|
||||
.init();
|
||||
|
||||
error!("Error Message");
|
||||
warn!("Warn Message");
|
||||
info!("Info Message");
|
||||
debug!("Debug Message");
|
||||
trace!("Trace Message");
|
||||
|
||||
let client = if let Ok(email) = std::env::var("SPOND_EMAIL") {
|
||||
connect::<spond::auth::Email>(&email).await?
|
||||
} else if let Ok(phone) = std::env::var("SPOND_PHONE") {
|
||||
connect::<spond::auth::Phone>(&phone).await?
|
||||
} else {
|
||||
panic!("no credentials provided");
|
||||
};
|
||||
|
||||
let _ = client;
|
||||
|
||||
|
||||
let users = (0..25).map(UserID).collect::<Vec<UserID>>();
|
||||
let mut events = Vec::new();
|
||||
|
||||
for id in 0..5 {
|
||||
let mut rng = rand::rng();
|
||||
let want = users.iter().filter(|_| (&mut rng).random_bool(0.75)).map(|id|id.clone()).collect::<HashSet<UserID>>();
|
||||
|
||||
let mut participants = Participants::default();
|
||||
for uid in want.iter() {
|
||||
participants = participants.add(*uid);
|
||||
}
|
||||
|
||||
let participants = participants.select(events.iter().rev(), &mut rng, 12);
|
||||
let event = MockEvent::new(id, want, participants);
|
||||
println!("{event}");
|
||||
events.push(event);
|
||||
}
|
||||
|
||||
for uid in users.into_iter() {
|
||||
let (registered, participated) = events.iter()
|
||||
.fold((0, 0), |(registered, participated), event| {
|
||||
let registered = registered + if event.registered(uid) { 1 } else { 0 };
|
||||
let participated = participated + if event.participated(uid) { 1 } else { 0 };
|
||||
(registered, participated)
|
||||
});
|
||||
|
||||
println!("{uid}: ({participated}/{registered}) {:.2}%",
|
||||
(participated as f64) / (registered as f64) * 100f64);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn tracing_setup(filter: &str) {
|
||||
let filter = EnvFilter::try_from_default_env()
|
||||
.unwrap_or_else(|_| EnvFilter::new(filter));
|
||||
|
||||
tracing_subscriber::registry()
|
||||
.with(fmt::layer().pretty())
|
||||
.with(filter)
|
||||
.init();
|
||||
}
|
||||
|
||||
async fn connect<A: spond::traits::client::Authenticator + Sync, C: spond::traits::authentication::login::Credentials + Sync>(authenticator: A, credentials: C) -> Result<A::Private, spond::error::api::Public<<A as spond::traits::client::Public>::Error, <spond::authentication::Tokens as spond::traits::Schema<C>>::Error>> {
|
||||
let auth = spond::authentication::Login;
|
||||
|
||||
authenticator.authenticate(&auth, &credentials).await
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize)]
|
||||
struct Spond()
|
||||
|
||||
#[derive(serde::Deserialize)]
|
||||
struct Sponds(Vec<Spond>);
|
||||
|
||||
impl spond::traits::endpoint::Private<SpondsQuery> for Sponds {
|
||||
const METHOD: spond::Method = spond::Method::GET;
|
||||
type Schema = Self;
|
||||
|
||||
fn path(&self, _: &SpodsW
|
||||
}
|
||||
|
||||
#[derive(serde::Seralize)]
|
||||
struct SpondsQuery;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
tracing_setup("info");
|
||||
|
||||
#[cfg(feature="disabled")]
|
||||
disabled::main().await;
|
||||
|
||||
error!("Error Message");
|
||||
warn!("Warn Message");
|
||||
info!("Info Message");
|
||||
debug!("Debug Message");
|
||||
trace!("Trace Message");
|
||||
|
||||
let pw = std::env::var("SPOND_PASSWORD").expect("a password is required in SPOND_PASSWORD");
|
||||
let client = spond::reqwest::Public::new().expect("public client");
|
||||
let client = if let Ok(email) = std::env::var("SPOND_EMAIL") {
|
||||
connect(client, spond::authentication::login::Email::new(&email, &pw)).await
|
||||
} else if let Ok(phone) = std::env::var("SPOND_PHONE") {
|
||||
connect(client, spond::authentication::login::Phone::new(&phone, &pw)).await
|
||||
} else {
|
||||
panic!("no credentials provided");
|
||||
};
|
||||
|
||||
let _ = client.execute(;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue