Compare commits
4 Commits
db0f1c5be8
...
65eb941eb4
Author | SHA1 | Date |
---|---|---|
Bauke | 65eb941eb4 | |
Bauke | f28a0bf505 | |
Bauke | d615aa2843 | |
Bauke | 4c38866de8 |
|
@ -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",
|
||||
|
|
|
@ -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"]
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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?;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -65,3 +65,7 @@ details {
|
|||
.underline {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.small {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
|
|
@ -44,7 +44,11 @@
|
|||
<td>
|
||||
<a href="/{{ group.name }}">{{ group.name }}</a>
|
||||
</td>
|
||||
<td>{{ group.subscribers }}</td>
|
||||
<td>
|
||||
{{ group.subscribers }} <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 }}
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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`].
|
||||
|
|
Loading…
Reference in New Issue