aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2024-04-28 22:59:20 +0200
committermetamuffin <metamuffin@disroot.org>2024-04-28 22:59:20 +0200
commit8f731106364bf828747af7e6177cc447a69a56d9 (patch)
tree643c0ab54de74c847ade4bf67d2f2cd3ee2e2419
parentbd305b4303c202a8071999de9a4003ed4211588a (diff)
downloadmeta-adservices-8f731106364bf828747af7e6177cc447a69a56d9.tar
meta-adservices-8f731106364bf828747af7e6177cc447a69a56d9.tar.bz2
meta-adservices-8f731106364bf828747af7e6177cc447a69a56d9.tar.zst
show leaderboard
-rw-r--r--src/info.rs24
-rw-r--r--src/state.rs34
2 files changed, 53 insertions, 5 deletions
diff --git a/src/info.rs b/src/info.rs
index c3fa0a9..1e5d8d9 100644
--- a/src/info.rs
+++ b/src/info.rs
@@ -1,10 +1,13 @@
-use crate::{s_file, Template};
+use crate::error::MyResult;
+use crate::{s_file, state::Logic, Template};
use markup::{doctype, DynRender};
-use rocket::{get, http::ContentType};
+use rocket::{get, http::ContentType, State};
+use std::sync::Arc;
#[get("/")]
-pub fn r_index<'a>() -> Template<DynRender<'a>> {
- Template(markup::new! {
+pub async fn r_index<'a>(state: &State<Arc<Logic>>) -> MyResult<Template<DynRender<'a>>> {
+ let leaderboard = state.get_leaderboard().await?;
+ Ok(Template(markup::new! {
@doctype()
html {
head {
@@ -41,6 +44,17 @@ pub fn r_index<'a>() -> Template<DynRender<'a>> {
li { "The image, URL or names should be free of malware" }
}
}
+ h2 { "leaderboard" }
+ table {
+ tr { th { "Domain" } th { "Impressions" } th { "Impression weight" } }
+ @for (domain, raw, weighted) in &leaderboard {
+ tr {
+ td { @domain }
+ td { @raw }
+ td { @weighted }
+ }
+ }
+ }
h2 { "privacy" }
p { "data used by meta adservices: " }
ul {
@@ -54,7 +68,7 @@ pub fn r_index<'a>() -> Template<DynRender<'a>> {
}
}
}
- })
+ }))
}
#[get("/style.css")]
diff --git a/src/state.rs b/src/state.rs
index ff5509b..9ad2f9a 100644
--- a/src/state.rs
+++ b/src/state.rs
@@ -76,6 +76,40 @@ impl Logic {
state
}
+ pub async fn get_leaderboard(&self) -> anyhow::Result<Vec<(String, u64, f64)>> {
+ let txn = self.database.begin_read()?;
+ let mut d = {
+ let raw = txn.open_table(T_IMPRESSIONS_RAW)?;
+ let weighted = txn.open_table(T_IMPRESSIONS_WEIGHTED)?;
+
+ weighted.iter()?.try_fold(Vec::new(), |mut s, k| {
+ let (k, v) = k?;
+ s.push((
+ k.value().to_owned(),
+ raw.get(k.value())?.map(|e| e.value()).unwrap_or_default(),
+ v.value(),
+ ));
+ Ok::<_, anyhow::Error>(s)
+ })?
+ };
+
+ #[derive(PartialEq, PartialOrd)]
+ struct OrdAnyway(f64);
+ impl Eq for OrdAnyway {}
+ impl Ord for OrdAnyway {
+ fn cmp(&self, other: &Self) -> std::cmp::Ordering {
+ self.partial_cmp(other).unwrap()
+ }
+ }
+
+ d.sort_by_key(|(_, _, w)| OrdAnyway(*w));
+ while d.len() > 16 {
+ d.pop();
+ }
+
+ Ok(d)
+ }
+
async fn commit_db(&self, mut rx: Receiver<ImpressionEvent>) -> anyhow::Result<()> {
let mut deadline = None;
let mut impressions_by_addr = vec![0u16; self.config.bloom_filter_size];