cargo fmt

This commit is contained in:
Armaël Guéneau 2024-11-23 13:10:18 +01:00
parent 83d8be55da
commit 8b2a65d6f6

View file

@ -116,14 +116,28 @@ impl Db {
fn from_path(path: &Path, classifier: &Classifier) -> anyhow::Result<Self> { fn from_path(path: &Path, classifier: &Classifier) -> anyhow::Result<Self> {
let file = File::open(path)?; let file = File::open(path)?;
let (users, is_spam) = serde_json::from_reader(BufReader::new(file))?; let (users, is_spam) = serde_json::from_reader(BufReader::new(file))?;
let mut db = Db { users, is_spam, tokens: HashMap::new(), score: HashMap::new() }; let mut db = Db {
users,
is_spam,
tokens: HashMap::new(),
score: HashMap::new(),
};
db.recompute_tokens(); db.recompute_tokens();
db.recompute_scores(classifier); db.recompute_scores(classifier);
Ok(db) Ok(db)
} }
fn from_users(users: HashMap<UserId, UserData>, is_spam: HashMap<UserId, bool>, classifier: &Classifier) -> Db { fn from_users(
let mut db = Db { users, is_spam, tokens: HashMap::new(), score: HashMap::new() }; users: HashMap<UserId, UserData>,
is_spam: HashMap<UserId, bool>,
classifier: &Classifier,
) -> Db {
let mut db = Db {
users,
is_spam,
tokens: HashMap::new(),
score: HashMap::new(),
};
db.recompute_tokens(); db.recompute_tokens();
db.recompute_scores(classifier); db.recompute_scores(classifier);
db db
@ -131,7 +145,8 @@ impl Db {
fn store_to_path(&self, path: &Path) -> anyhow::Result<()> { fn store_to_path(&self, path: &Path) -> anyhow::Result<()> {
let file = File::create(path)?; let file = File::create(path)?;
let dat: (&HashMap<UserId, UserData>, &HashMap<UserId, bool>) = (&self.users, &self.is_spam); let dat: (&HashMap<UserId, UserData>, &HashMap<UserId, bool>) =
(&self.users, &self.is_spam);
serde_json::to_writer(BufWriter::new(file), &dat)?; serde_json::to_writer(BufWriter::new(file), &dat)?;
Ok(()) Ok(())
} }
@ -329,12 +344,7 @@ async fn load_db() -> anyhow::Result<(Db, Classifier)> {
let db: Db = if db_path.is_file() { let db: Db = if db_path.is_file() {
Db::from_path(db_path, &classifier)? Db::from_path(db_path, &classifier)?
} else { } else {
let db = let db = Db::from_users(get_users_data(&forge).await?, HashMap::new(), &classifier);
Db::from_users(
get_users_data(&forge).await?,
HashMap::new(),
&classifier
);
db.store_to_path(db_path)?; db.store_to_path(db_path)?;
db db
}; };
@ -389,7 +399,7 @@ struct AppState {
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
struct SortSetting { struct SortSetting {
sort: Option<String> sort: Option<String>,
} }
#[get("/")] #[get("/")]
@ -399,8 +409,8 @@ async fn index(data: web::Data<AppState>, q: web::Query<SortSetting>) -> impl Re
let db = &data.db.lock().unwrap(); let db = &data.db.lock().unwrap();
eprintln!("scoring users..."); eprintln!("scoring users...");
let mut users: Vec<_> = let mut users: Vec<_> = unclassified_users(db)
unclassified_users(db).into_iter() .into_iter()
.map(|(id, u)| (id, u, *db.score.get(id).unwrap())) .map(|(id, u)| (id, u, *db.score.get(id).unwrap()))
.collect(); .collect();
let mut rng = rand::thread_rng(); let mut rng = rand::thread_rng();
@ -410,15 +420,12 @@ async fn index(data: web::Data<AppState>, q: web::Query<SortSetting>) -> impl Re
eprintln!("sorting..."); eprintln!("sorting...");
match q.sort.as_ref().map(|s| s.as_str()) { match q.sort.as_ref().map(|s| s.as_str()) {
Some("legit") => // sort "legit first": by increasing score
// sort "legit first": by increasing score Some("legit") => users.sort_by_key(|(_, _, score)| (score * 1000.) as u64),
users.sort_by_key(|(_, _, score)| (score * 1000.) as u64), // keep the random order
Some("random") => Some("random") => (),
// keep the random order // sort "spam first": by decreasing score
(), _ => users.sort_by_key(|(_, _, score)| 1000 - (score * 1000.) as u64),
_ =>
// sort "spam first": by decreasing score
users.sort_by_key(|(_, _, score)| 1000 - (score * 1000.) as u64),
}; };
users.truncate(50); users.truncate(50);
@ -427,7 +434,10 @@ async fn index(data: web::Data<AppState>, q: web::Query<SortSetting>) -> impl Re
let mut context = tera::Context::new(); let mut context = tera::Context::new();
context.insert("users", &users); context.insert("users", &users);
context.insert("unclassified_users_count", &(users_count - classified_count)); context.insert(
"unclassified_users_count",
&(users_count - classified_count),
);
context.insert("total_users_count", &users_count); context.insert("total_users_count", &users_count);
eprintln!("rendering template..."); eprintln!("rendering template...");
let page = TEMPLATES.render("index.html", &context).unwrap(); let page = TEMPLATES.render("index.html", &context).unwrap();
@ -436,24 +446,23 @@ async fn index(data: web::Data<AppState>, q: web::Query<SortSetting>) -> impl Re
} }
#[post("/")] #[post("/")]
async fn apply( async fn apply(data: web::Data<AppState>, req: web::Form<HashMap<i64, String>>) -> impl Responder {
data: web::Data<AppState>,
req: web::Form<HashMap<i64, String>>,
) -> impl Responder {
eprintln!("POST /"); eprintln!("POST /");
let db = &mut data.db.lock().unwrap(); let db = &mut data.db.lock().unwrap();
let classifier = &mut data.classifier.lock().unwrap(); let classifier = &mut data.classifier.lock().unwrap();
let updates: Vec<(UserId, bool)> = let updates: Vec<(UserId, bool)> = req
req.iter() .iter()
.map(|(id, classification)| (UserId(*id), classification == "spam")) .map(|(id, classification)| (UserId(*id), classification == "spam"))
.collect(); .collect();
set_spam(db, classifier, &updates); set_spam(db, classifier, &updates);
db.store_to_path(Path::new("db.json")).unwrap(); // FIXME db.store_to_path(Path::new("db.json")).unwrap(); // FIXME
classifier.save(&mut File::create(Path::new("model.json")).unwrap(), false).unwrap(); // FIXME classifier
.save(&mut File::create(Path::new("model.json")).unwrap(), false)
.unwrap(); // FIXME
HttpResponse::SeeOther() HttpResponse::SeeOther()
.insert_header(("Location", "")) .insert_header(("Location", ""))