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