Compare commits

...

4 Commits

9 changed files with 97 additions and 54 deletions

60
Cargo.lock generated
View File

@ -95,6 +95,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f"
dependencies = [
"cfg-if",
"getrandom 0.2.10",
"once_cell",
"version_check",
]
@ -958,13 +959,13 @@ dependencies = [
[[package]]
name = "cssparser"
version = "0.27.2"
version = "0.29.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "754b69d351cdc2d8ee09ae203db831e005560fc6030da058f86ad60c92a9cb0a"
checksum = "f93d03419cb5950ccfd3daf3ff1c7a36ace64609a1a8746d493df1ca0afde0fa"
dependencies = [
"cssparser-macros",
"dtoa-short",
"itoa 0.4.8",
"itoa",
"matches",
"phf 0.8.0",
"proc-macro2",
@ -1099,6 +1100,16 @@ dependencies = [
"dtoa",
]
[[package]]
name = "duplicate"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de78e66ac9061e030587b2a2e75cc88f22304913c907b11307bca737141230cb"
dependencies = [
"heck 0.4.1",
"proc-macro-error",
]
[[package]]
name = "ego-tree"
version = "0.6.2"
@ -1702,12 +1713,6 @@ dependencies = [
"either",
]
[[package]]
name = "itoa"
version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
[[package]]
name = "itoa"
version = "1.0.6"
@ -2723,15 +2728,16 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "scraper"
version = "0.13.0"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5684396b456f3eb69ceeb34d1b5cb1a2f6acf7ca4452131efa3ba0ee2c2d0a70"
checksum = "59e25654b5e9fd557a67dbaab5a5d36b8c448d0561beb4c041b6dbb902eddfa6"
dependencies = [
"ahash 0.8.3",
"cssparser",
"ego-tree",
"getopts",
"html5ever",
"matches",
"once_cell",
"selectors",
"smallvec",
"tendril",
@ -2928,22 +2934,20 @@ checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b"
[[package]]
name = "selectors"
version = "0.22.0"
version = "0.24.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df320f1889ac4ba6bc0cdc9c9af7af4bd64bb927bccdf32d81140dc1f9be12fe"
checksum = "0c37578180969d00692904465fb7f6b3d50b9a2b952b87c23d0e2e5cb5013416"
dependencies = [
"bitflags",
"cssparser",
"derive_more",
"fxhash",
"log",
"matches",
"phf 0.8.0",
"phf_codegen 0.8.0",
"precomputed-hash",
"servo_arc",
"smallvec",
"thin-slice",
]
[[package]]
@ -2993,7 +2997,7 @@ version = "1.0.96"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1"
dependencies = [
"itoa 1.0.6",
"itoa",
"ryu",
"serde",
]
@ -3016,16 +3020,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
dependencies = [
"form_urlencoded",
"itoa 1.0.6",
"itoa",
"ryu",
"serde",
]
[[package]]
name = "servo_arc"
version = "0.1.1"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d98238b800e0d1576d8b6e3de32827c2d74bee68bb97748dcf5071fb53965432"
checksum = "d52aa42f8fdf0fed91e5ce7f23d8138441002fa31dca008acf47e6fd4721f741"
dependencies = [
"nodrop",
"stable_deref_trait",
@ -3210,7 +3214,7 @@ dependencies = [
"hkdf 0.12.3",
"hmac 0.12.1",
"indexmap",
"itoa 1.0.6",
"itoa",
"libc",
"log",
"md-5",
@ -3470,12 +3474,6 @@ version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d"
[[package]]
name = "thin-slice"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c"
[[package]]
name = "thiserror"
version = "1.0.40"
@ -3509,12 +3507,13 @@ dependencies = [
[[package]]
name = "tildes-parser"
version = "0.1.0"
source = "git+https://git.bauke.xyz/tildes-community/tildes-parser.git?rev=08bf7ed#08bf7ed29e10ba6012afcd57cea263e9f0a707e9"
source = "git+https://git.bauke.xyz/tildes-community/tildes-parser.git?rev=6f0d4d394d533a331b0c9cf19fe80d60f0865ca7#6f0d4d394d533a331b0c9cf19fe80d60f0865ca7"
dependencies = [
"color-eyre",
"duplicate",
"lazy_static",
"regex",
"scraper",
"thiserror",
]
[[package]]
@ -3529,6 +3528,7 @@ dependencies = [
"dotenvy",
"grass",
"plotters",
"scraper",
"sea-orm",
"sea-orm-migration",
"surf",
@ -3569,7 +3569,7 @@ version = "0.3.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea9e1b3cf1243ae005d9e74085d4d542f3125458f3a81af210d901dcd7411efd"
dependencies = [
"itoa 1.0.6",
"itoa",
"serde",
"time-core",
"time-macros 0.2.9",

View File

@ -18,6 +18,7 @@ chrono = "0.4.22"
color-eyre = "0.6.2"
dotenvy = "0.15.5"
grass = "0.11.2"
scraper = "0.16.0"
sea-orm-migration = "0.11.3"
tracing = "0.1.36"
@ -41,7 +42,7 @@ version = "2.3.2"
[dependencies.tildes-parser]
git = "https://git.bauke.xyz/tildes-community/tildes-parser.git"
rev = "08bf7ed"
rev = "6f0d4d394d533a331b0c9cf19fe80d60f0865ca7"
[dependencies.tracing-subscriber]
features = ["env-filter"]

View File

@ -29,12 +29,9 @@ impl UserCountChart {
group_name: &str,
render_point_circles: bool,
truncate: bool,
output_dir: &str,
) -> Result<PathBuf> {
let parent = if truncate {
parent.join("charts/user-count")
} else {
parent.join("charts-untruncated/user-count")
};
let parent = parent.join(format!("{}/user-count", output_dir));
create_dir_all(&parent).await?;
let (mut datapoints, mut min_count, mut max_count) = (vec![], i64::MAX, 0);

View File

@ -115,9 +115,31 @@ pub async fn run() -> Result<()> {
groups: GroupDataModel::get_n_most_recent(&db, 31, &group.name)
.await?,
};
chart
.render(&output, &group.name, true, true, "charts")
.await?;
chart
.render(&output, &group.name, true, false, "charts-untruncated")
.await?;
chart.render(&output, &group.name, true, true).await?;
chart.render(&output, &group.name, true, false).await?;
{
let total_chart = UserCountChart {
groups: GroupDataModel::get_all(&db, &group.name).await?,
};
total_chart
.render(&output, &group.name, false, true, "charts-total")
.await?;
total_chart
.render(
&output,
&group.name,
false,
false,
"charts-total-untruncated",
)
.await?;
}
GroupTemplate::new(group.description.clone(), &group.name)
.await
@ -136,16 +158,12 @@ pub async fn run() -> Result<()> {
write_assets(&output).await?;
if let Some(group) = user_count_group {
let path =
output.join(&format!("charts/user-count/{}.svg", &group.name));
copy(path, output.join("charts/main-user-count.svg")).await?;
let path = output.join(&format!(
"charts-untruncated/user-count/{}.svg",
&group.name
));
copy(path, output.join("charts-untruncated/main-user-count.svg"))
.await?;
for dir in ["charts", "charts-untruncated"] {
let from_path =
output.join(&format!("{}/user-count/{}.svg", dir, &group.name));
let to_path = output.join(format!("{}/main-user-count.svg", dir));
copy(from_path, to_path).await?;
}
}
}
},

View File

@ -42,6 +42,20 @@ impl GroupDataModel {
Ok(group)
}
/// Get all the saved group datas from a given group name.
pub async fn get_all(
db: &DatabaseConnection,
name: &str,
) -> Result<Vec<Self>> {
Ok(
GroupDataEntity::find()
.order_by_asc(GroupDataColumn::SnapshotId)
.filter(GroupDataColumn::Name.eq(name))
.all(db)
.await?,
)
}
/// Get the N most recently saved group datas from a given group name.
pub async fn get_n_most_recent(
db: &DatabaseConnection,

View File

@ -65,3 +65,7 @@ details {
.underline {
text-decoration: underline;
}
.small {
font-size: 1rem;
}

View File

@ -44,7 +44,11 @@
<td>
<a href="/{{ group.name }}">{{ group.name }}</a>
</td>
<td>{{ group.subscribers }}</td>
<td>
{{ group.subscribers }}&nbsp;<span class="small"
title="Percentage of subscribers compared to the highest-subscribed group."
>({{ group.subscribers|percentage(user_count) }})</span>
</td>
<td>
{% if let Some(description) = group.description %}
{{ description }}

View File

@ -40,7 +40,7 @@ pub struct HomeTemplate {
pub today: NaiveDate,
/// The user count from the group with the most subscribers.
pub user_count: String,
pub user_count: i64,
}
impl HomeTemplate {
@ -59,9 +59,7 @@ impl HomeTemplate {
groups,
page_title: "Tildes Statistics".to_string(),
today: today(),
user_count: user_count
.map(|n| n.to_string())
.unwrap_or_else(|| "unknown".to_string()),
user_count: user_count.unwrap_or(1),
}
}
@ -128,3 +126,10 @@ impl GroupTemplate {
Ok(())
}
}
mod filters {
pub fn percentage(a: &i64, b: &i64) -> askama::Result<String> {
let percentage = (*a as f64 / *b as f64) * 100_f64;
Ok(format!("{:.2}%", percentage))
}
}

View File

@ -9,9 +9,9 @@ use {
eyre::{eyre, WrapErr},
Result,
},
scraper::Html,
sea_orm::{ConnectOptions, Database, DatabaseConnection},
surf::{Client, Config},
tildes_parser::Html,
};
/// Creates the SeaQL [`DatabaseConnection`].