Compare commits
No commits in common. "352d107e3599f8bba92caca0f8b7ff436fb44ee2" and "b64b7836fa8f1ad65c66cc973ba872e3e5298aeb" have entirely different histories.
352d107e35
...
b64b7836fa
|
@ -15,7 +15,6 @@
|
||||||
"stylelint-config-standard-scss"
|
"stylelint-config-standard-scss"
|
||||||
],
|
],
|
||||||
"rules": {
|
"rules": {
|
||||||
"no-descending-specificity": null,
|
|
||||||
"string-quotes": "single"
|
"string-quotes": "single"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,10 +8,10 @@ use {
|
||||||
|
|
||||||
use crate::group_data::GroupDataModel;
|
use crate::group_data::GroupDataModel;
|
||||||
|
|
||||||
const BACKGROUND_1: RGBColor = RGBColor(31, 23, 49);
|
const BACKGROUND_1: RGBColor = RGBColor(17, 17, 17);
|
||||||
const BACKGROUND_2: RGBColor = RGBColor(42, 32, 65);
|
const BACKGROUND_2: RGBColor = RGBColor(0, 0, 0);
|
||||||
const FOREGROUND: RGBColor = RGBColor(242, 239, 255);
|
const FOREGROUND: RGBColor = RGBColor(255, 255, 255);
|
||||||
const ACCENT_1: RGBColor = RGBColor(210, 184, 58);
|
const ACCENT_1: RGBColor = RGBColor(255, 0, 255);
|
||||||
|
|
||||||
/// The chart for the user count.
|
/// The chart for the user count.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -46,7 +46,7 @@ impl UserCountChart {
|
||||||
|
|
||||||
let path = parent.join("user-count.svg");
|
let path = parent.join("user-count.svg");
|
||||||
let chart_root = SVGBackend::new(&path, (1280, 720)).into_drawing_area();
|
let chart_root = SVGBackend::new(&path, (1280, 720)).into_drawing_area();
|
||||||
chart_root.fill(&BACKGROUND_2)?;
|
chart_root.fill(&BACKGROUND_1)?;
|
||||||
|
|
||||||
let text_style =
|
let text_style =
|
||||||
|font_size: i32| ("sans-serif", font_size).into_font().color(&FOREGROUND);
|
|font_size: i32| ("sans-serif", font_size).into_font().color(&FOREGROUND);
|
||||||
|
@ -55,15 +55,15 @@ impl UserCountChart {
|
||||||
.margin(20, 20, 20, 20)
|
.margin(20, 20, 20, 20)
|
||||||
.titled("Tildes User Count", text_style(30))?;
|
.titled("Tildes User Count", text_style(30))?;
|
||||||
|
|
||||||
chart_root.fill(&BACKGROUND_2)?;
|
chart_root.fill(&BACKGROUND_1)?;
|
||||||
|
|
||||||
let mut chart = ChartBuilder::on(&chart_root)
|
let mut chart = ChartBuilder::on(&chart_root)
|
||||||
.caption(
|
.caption(
|
||||||
format!("Using the {group_name} subscriber count."),
|
format!("Using the {group_name} subscriber count."),
|
||||||
text_style(20),
|
text_style(20),
|
||||||
)
|
)
|
||||||
.x_label_area_size(50)
|
.x_label_area_size(40)
|
||||||
.y_label_area_size(50)
|
.y_label_area_size(40)
|
||||||
.margin(10)
|
.margin(10)
|
||||||
.build_cartesian_2d(0..(datapoints_len + 1), min_count..max_count)?;
|
.build_cartesian_2d(0..(datapoints_len + 1), min_count..max_count)?;
|
||||||
|
|
||||||
|
@ -75,9 +75,9 @@ impl UserCountChart {
|
||||||
.y_labels(5)
|
.y_labels(5)
|
||||||
.y_label_formatter(&|y| format!("{y:0}"))
|
.y_label_formatter(&|y| format!("{y:0}"))
|
||||||
.label_style(text_style(20))
|
.label_style(text_style(20))
|
||||||
.axis_style(&BACKGROUND_1)
|
.axis_style(&BACKGROUND_2)
|
||||||
.light_line_style(&BACKGROUND_1)
|
.light_line_style(&BACKGROUND_2)
|
||||||
.bold_line_style(&BACKGROUND_2)
|
.bold_line_style(&BACKGROUND_1)
|
||||||
.draw()?;
|
.draw()?;
|
||||||
|
|
||||||
chart
|
chart
|
||||||
|
|
|
@ -85,19 +85,15 @@ pub async fn run() -> Result<()> {
|
||||||
command: web_command,
|
command: web_command,
|
||||||
} => match web_command {
|
} => match web_command {
|
||||||
WebSubcommands::Build { output } => {
|
WebSubcommands::Build { output } => {
|
||||||
let (groups, user_count_group) =
|
let user_count_group =
|
||||||
if let Some(snapshot) = SnapshotModel::get_most_recent(&db).await? {
|
if let Some(snapshot) = SnapshotModel::get_most_recent(&db).await? {
|
||||||
(
|
GroupDataModel::get_highest_subscribers(&db, &snapshot).await?
|
||||||
GroupDataModel::get_all_by_snapshot(&db, &snapshot).await?,
|
|
||||||
GroupDataModel::get_highest_subscribers(&db, &snapshot).await?,
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
(vec![], None)
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
create_dir_all(&output).await?;
|
create_dir_all(&output).await?;
|
||||||
HomeTemplate::new(
|
HomeTemplate::new(
|
||||||
groups,
|
|
||||||
user_count_group.as_ref().map(|group| group.subscribers),
|
user_count_group.as_ref().map(|group| group.subscribers),
|
||||||
)
|
)
|
||||||
.render_to_file(&output)
|
.render_to_file(&output)
|
||||||
|
|
|
@ -19,12 +19,7 @@ impl GroupDataModel {
|
||||||
db: &DatabaseConnection,
|
db: &DatabaseConnection,
|
||||||
snapshot: &SnapshotModel,
|
snapshot: &SnapshotModel,
|
||||||
) -> Result<Vec<Self>> {
|
) -> Result<Vec<Self>> {
|
||||||
let groups = snapshot
|
let groups = snapshot.find_related(GroupDataEntity).all(db).await?;
|
||||||
.find_related(GroupDataEntity)
|
|
||||||
.order_by_asc(GroupDataColumn::Name)
|
|
||||||
.all(db)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
Ok(groups)
|
Ok(groups)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +44,7 @@ impl GroupDataModel {
|
||||||
name: &str,
|
name: &str,
|
||||||
) -> Result<Vec<Self>> {
|
) -> Result<Vec<Self>> {
|
||||||
let groups = GroupDataEntity::find()
|
let groups = GroupDataEntity::find()
|
||||||
.order_by_asc(GroupDataColumn::SnapshotId)
|
.order_by_desc(GroupDataColumn::SnapshotId)
|
||||||
.filter(GroupDataColumn::Name.eq(name))
|
.filter(GroupDataColumn::Name.eq(name))
|
||||||
.limit(amount)
|
.limit(amount)
|
||||||
.all(db)
|
.all(db)
|
||||||
|
|
|
@ -6,11 +6,11 @@ body {
|
||||||
--small-spacing: 4px;
|
--small-spacing: 4px;
|
||||||
--medium-spacing: 8px;
|
--medium-spacing: 8px;
|
||||||
--large-spacing: 16px;
|
--large-spacing: 16px;
|
||||||
--background-1: #1f1731;
|
--background-1: #222;
|
||||||
--background-2: #2a2041;
|
--background-2: #111;
|
||||||
--foreground-1: #f2efff;
|
--foreground-1: #fff;
|
||||||
--anchor-1: #d2b83a;
|
--anchor-1: #f0f;
|
||||||
--anchor-2: var(--foreground-1);
|
--anchor-2: #000;
|
||||||
|
|
||||||
background-color: var(--background-1);
|
background-color: var(--background-1);
|
||||||
color: var(--foreground-1);
|
color: var(--foreground-1);
|
||||||
|
@ -20,8 +20,10 @@ body {
|
||||||
a,
|
a,
|
||||||
a:visited {
|
a:visited {
|
||||||
color: var(--anchor-1);
|
color: var(--anchor-1);
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
|
background-color: var(--anchor-1);
|
||||||
color: var(--anchor-2);
|
color: var(--anchor-2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,41 +24,13 @@
|
||||||
.page-main {
|
.page-main {
|
||||||
h2,
|
h2,
|
||||||
img,
|
img,
|
||||||
p,
|
p {
|
||||||
table {
|
|
||||||
margin-bottom: var(--medium-spacing);
|
margin-bottom: var(--medium-spacing);
|
||||||
|
|
||||||
&:last-child {
|
&:last-child {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
table {
|
|
||||||
border: 2px solid var(--background-2);
|
|
||||||
border-collapse: collapse;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
thead {
|
|
||||||
background-color: var(--background-2);
|
|
||||||
border-bottom: 2px solid var(--background-2);
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
tr {
|
|
||||||
border: 2px solid var(--background-2);
|
|
||||||
}
|
|
||||||
|
|
||||||
td,
|
|
||||||
th {
|
|
||||||
padding: var(--medium-spacing);
|
|
||||||
}
|
|
||||||
|
|
||||||
tbody {
|
|
||||||
> tr:nth-of-type(2n) {
|
|
||||||
background-color: var(--background-2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.page-footer {
|
.page-footer {
|
||||||
|
|
|
@ -13,38 +13,13 @@
|
||||||
<h2>General</h2>
|
<h2>General</h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
There are currently an estimated
|
There are currently an
|
||||||
|
<abbr title="Based on the group with the highest subscriber count.">estimated</abbr>
|
||||||
<span class="underline">{{ user_count }}</span>
|
<span class="underline">{{ user_count }}</span>
|
||||||
registered users on Tildes.
|
registered users on Tildes.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<img src="/charts/user-count.svg" alt="User Count Chart">
|
<img src="/charts/user-count.svg" alt="User Count Chart">
|
||||||
|
|
||||||
<table>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Group</th>
|
|
||||||
<th>Subscribers</th>
|
|
||||||
<th>Description</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
|
|
||||||
<tbody>
|
|
||||||
{% for group in groups %}
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<a href="https://tildes.net/{{ group.name }}">{{ group.name }}</a>
|
|
||||||
</td>
|
|
||||||
<td>{{ group.subscribers }}</td>
|
|
||||||
<td>
|
|
||||||
{% if let Some(description) = group.description %}
|
|
||||||
{{ description }}
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<footer class="page-footer">
|
<footer class="page-footer">
|
||||||
|
|
|
@ -7,15 +7,12 @@ use {
|
||||||
color_eyre::Result,
|
color_eyre::Result,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{group_data::GroupDataModel, utilities::today};
|
use crate::utilities::today;
|
||||||
|
|
||||||
/// The template for the home page.
|
/// The template for the home page.
|
||||||
#[derive(Template)]
|
#[derive(Template)]
|
||||||
#[template(path = "index.html")]
|
#[template(path = "index.html")]
|
||||||
pub struct HomeTemplate {
|
pub struct HomeTemplate {
|
||||||
/// The groups to create the table with.
|
|
||||||
pub groups: Vec<GroupDataModel>,
|
|
||||||
|
|
||||||
/// The string for the `<title>` element.
|
/// The string for the `<title>` element.
|
||||||
pub page_title: String,
|
pub page_title: String,
|
||||||
|
|
||||||
|
@ -28,9 +25,8 @@ pub struct HomeTemplate {
|
||||||
|
|
||||||
impl HomeTemplate {
|
impl HomeTemplate {
|
||||||
/// Create a new [`HomeTemplate`].
|
/// Create a new [`HomeTemplate`].
|
||||||
pub fn new(groups: Vec<GroupDataModel>, user_count: Option<i64>) -> Self {
|
pub fn new(user_count: Option<i64>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
groups,
|
|
||||||
page_title: "Tildes Statistics".to_string(),
|
page_title: "Tildes Statistics".to_string(),
|
||||||
today: today(),
|
today: today(),
|
||||||
user_count: user_count
|
user_count: user_count
|
||||||
|
|
Loading…
Reference in New Issue