diff options
author | metamuffin <metamuffin@disroot.org> | 2024-04-28 22:59:20 +0200 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2024-04-28 22:59:20 +0200 |
commit | 8f731106364bf828747af7e6177cc447a69a56d9 (patch) | |
tree | 643c0ab54de74c847ade4bf67d2f2cd3ee2e2419 /src | |
parent | bd305b4303c202a8071999de9a4003ed4211588a (diff) | |
download | meta-adservices-8f731106364bf828747af7e6177cc447a69a56d9.tar meta-adservices-8f731106364bf828747af7e6177cc447a69a56d9.tar.bz2 meta-adservices-8f731106364bf828747af7e6177cc447a69a56d9.tar.zst |
show leaderboard
Diffstat (limited to 'src')
-rw-r--r-- | src/info.rs | 24 | ||||
-rw-r--r-- | src/state.rs | 34 |
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]; |