1
Fork 0

Nicely format imports

This commit is contained in:
prescientmoon 2024-09-17 02:43:18 +02:00
parent 0e0043d2c1
commit 50f8db4e2e
Signed by: prescientmoon
SSH key fingerprint: SHA256:WFp/cO76nbarETAoQcQXuV+0h7XJsEsOCI0UsyPIy6U
19 changed files with 153 additions and 162 deletions

View file

@ -1,17 +1,15 @@
// {{{ Imports
use anyhow::anyhow;
use image::RgbaImage;
use crate::{
assets::get_data_dir,
context::{Error, UserContext},
user::User,
};
use crate::assets::get_data_dir;
use crate::context::{Error, UserContext};
use crate::user::User;
use super::{
chart::{Difficulty, Level},
play::get_best_plays,
score::{Grade, ScoringSystem},
};
use super::chart::{Difficulty, Level};
use super::play::get_best_plays;
use super::score::{Grade, ScoringSystem};
// }}}
// {{{ Goal
#[derive(Debug, Clone, Copy)]

View file

@ -1,13 +1,13 @@
// {{{ Imports
use std::{fmt::Display, num::NonZeroU16, path::PathBuf};
use anyhow::anyhow;
use image::{ImageBuffer, Rgb};
use rusqlite::types::{FromSql, FromSqlError, FromSqlResult, ValueRef};
use crate::{
bitmap::Color,
context::{DbConnection, Error},
};
use crate::bitmap::Color;
use crate::context::{DbConnection, Error};
// }}}
// {{{ Difficuly
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]

View file

@ -1,3 +1,4 @@
// {{{ Imports
use std::fs;
use anyhow::Context;
@ -6,11 +7,10 @@ use num::Integer;
use serde::{Deserialize, Serialize};
use serde_with::serde_as;
use crate::{
arcaea::chart::{Difficulty, Jacket, SongCache},
assets::{get_asset_dir, should_skip_jacket_art},
context::Error,
};
use crate::arcaea::chart::{Difficulty, Jacket, SongCache};
use crate::assets::{get_asset_dir, should_skip_jacket_art};
use crate::context::Error;
// }}}
/// How many sub-segments to split each side into
pub const SPLIT_FACTOR: u32 = 8;

View file

@ -1,3 +1,4 @@
// {{{ Imports
use std::array;
use std::num::NonZeroU64;
@ -17,6 +18,7 @@ use crate::user::User;
use super::rating::{rating_as_fixed, rating_as_float};
use super::score::{Score, ScoringSystem};
// }}}
// {{{ Create play
#[derive(Debug, Clone)]

View file

@ -1,13 +1,13 @@
// {{{ Imports
use std::fmt::{Display, Write};
use num::{Rational32, Rational64};
use crate::context::Error;
use super::{
chart::Chart,
rating::{rating_as_float, rating_from_fixed, Rating},
};
use super::chart::Chart;
use super::rating::{rating_as_float, rating_from_fixed, Rating};
// }}}
// {{{ Scoring system
#[derive(Debug, Clone, Copy, poise::ChoiceParameter)]

View file

@ -1,16 +1,17 @@
use std::{
cell::RefCell,
env::var,
path::PathBuf,
str::FromStr,
sync::{LazyLock, OnceLock},
thread::LocalKey,
};
// {{{ Imports
use std::cell::RefCell;
use std::env::var;
use std::path::PathBuf;
use std::str::FromStr;
use std::sync::{LazyLock, OnceLock};
use std::thread::LocalKey;
use freetype::{Face, Library};
use image::{DynamicImage, RgbaImage};
use crate::{arcaea::chart::Difficulty, timed};
use crate::arcaea::chart::Difficulty;
use crate::timed;
// }}}
// {{{ Path helpers
#[inline]

View file

@ -5,18 +5,18 @@
//!
//! There's still stuff to be implemented here, like a cache for glyphs and
//! whatnot, but this does run pretty stably for the b30 renderer.
// {{{ Imports
use anyhow::anyhow;
use freetype::{
bitmap::PixelMode,
face::{KerningMode, LoadFlag},
ffi::{FT_Set_Var_Design_Coordinates, FT_GLYPH_BBOX_PIXELS},
Bitmap, BitmapGlyph, Face, Glyph, StrokerLineCap, StrokerLineJoin,
};
use freetype::bitmap::PixelMode;
use freetype::face::{KerningMode, LoadFlag};
use freetype::ffi::{FT_Set_Var_Design_Coordinates, FT_GLYPH_BBOX_PIXELS};
use freetype::{Bitmap, BitmapGlyph, Face, Glyph, StrokerLineCap, StrokerLineJoin};
use image::{GenericImage, RgbImage, RgbaImage};
use num::traits::Euclid;
use crate::{assets::FREETYPE_LIB, context::Error};
use crate::assets::FREETYPE_LIB;
use crate::context::Error;
// }}}
// {{{ Color
#[derive(Debug, Clone, Copy)]

View file

@ -1,10 +1,10 @@
// {{{ Imports
use std::path::PathBuf;
use crate::{
cli::context::CliContext,
commands::score::magic_impl,
context::{Error, UserContext},
};
use crate::cli::context::CliContext;
use crate::commands::score::magic_impl;
use crate::context::{Error, UserContext};
// }}}
#[derive(clap::Args)]
pub struct Args {

View file

@ -1,3 +1,4 @@
// {{{ Imports
use std::num::NonZeroU64;
use std::path::PathBuf;
use std::str::FromStr;
@ -7,7 +8,13 @@ use poise::serenity_prelude::{CreateAttachment, CreateMessage};
use crate::assets::get_var;
use crate::context::Error;
use crate::{commands::discord::MessageContext, context::UserContext};
// }}}
/// Similar in scope to [crate::commands::discord::mock::MockContext],
/// except replies and messages are printed to the standard output.
///
/// Attachments are ignored, and [CreateMessage] values are printed
/// as TOML.
pub struct CliContext {
pub user_id: u64,
pub data: UserContext,

View file

@ -1,21 +1,18 @@
use std::{
fs,
io::{stdout, Write},
};
// {{{ Imports
use std::fs;
use std::io::{stdout, Write};
use anyhow::{anyhow, bail, Context};
use image::imageops::FilterType;
use crate::{
arcaea::{
chart::{Difficulty, SongCache},
jacket::{ImageVec, BITMAP_IMAGE_SIZE},
},
assets::{get_asset_dir, get_data_dir},
context::{connect_db, Error},
recognition::fuzzy_song_name::guess_chart_name,
};
use crate::arcaea::chart::{Difficulty, SongCache};
use crate::arcaea::jacket::{ImageVec, BITMAP_IMAGE_SIZE};
use crate::assets::{get_asset_dir, get_data_dir};
use crate::context::{connect_db, Error};
use crate::recognition::fuzzy_song_name::guess_chart_name;
// }}}
/// Hacky function which clears the current line of the standard output.
#[inline]
fn clear_line() {
print!("\r \r");

View file

@ -1,32 +1,27 @@
// {{{ Imports
use anyhow::anyhow;
use poise::serenity_prelude::{CreateAttachment, CreateEmbed, CreateMessage};
use crate::{
arcaea::{chart::Side, play::Play},
context::{Context, Error},
get_user,
recognition::fuzzy_song_name::guess_song_and_chart,
};
use crate::arcaea::{chart::Side, play::Play};
use crate::context::{Context, Error};
use crate::get_user;
use crate::recognition::fuzzy_song_name::guess_song_and_chart;
use std::io::Cursor;
use chrono::DateTime;
use image::{ImageBuffer, Rgb};
use plotters::{
backend::{BitMapBackend, PixelFormat, RGBPixel},
chart::{ChartBuilder, LabelAreaPosition},
drawing::IntoDrawingArea,
element::Circle,
series::LineSeries,
style::{IntoFont, TextStyle, BLUE, WHITE},
};
use plotters::backend::{BitMapBackend, PixelFormat, RGBPixel};
use plotters::chart::{ChartBuilder, LabelAreaPosition};
use plotters::drawing::IntoDrawingArea;
use plotters::element::Circle;
use plotters::series::LineSeries;
use plotters::style::{IntoFont, TextStyle, BLUE, WHITE};
use poise::CreateReply;
use crate::{
arcaea::score::{Score, ScoringSystem},
user::discord_id_to_discord_user,
};
use crate::arcaea::score::{Score, ScoringSystem};
use super::discord::MessageContext;
// }}}
// {{{ Top command
/// Chart-related stats
@ -134,7 +129,7 @@ mod info_tests {
}
}
// }}}
// {{{ Discord wrapper
/// Show a chart given it's name
#[poise::command(prefix_command, slash_command, user_cooldown = 1)]
async fn info(
@ -148,6 +143,7 @@ async fn info(
Ok(())
}
// }}}
// }}}
// {{{ Best score
/// Show the best score on a given chart
#[poise::command(prefix_command, slash_command, user_cooldown = 1)]
@ -193,7 +189,7 @@ async fn best(
song,
chart,
0,
Some(&discord_id_to_discord_user(&ctx, &user.discord_id).await?),
Some(&ctx.fetch_user(&user.discord_id).await?),
)?;
ctx.channel_id()

View file

@ -1,12 +1,14 @@
use std::{num::NonZeroU64, str::FromStr};
// {{{ Imports
use std::num::NonZeroU64;
use std::str::FromStr;
use poise::serenity_prelude::{futures::future::join_all, CreateAttachment, CreateMessage};
use poise::serenity_prelude::futures::future::join_all;
use poise::serenity_prelude::{CreateAttachment, CreateMessage};
use crate::{
arcaea::play::Play,
context::{Error, UserContext},
timed,
};
use crate::arcaea::play::Play;
use crate::context::{Error, UserContext};
use crate::timed;
// }}}
// {{{ Trait
pub trait MessageContext {

View file

@ -1,3 +1,4 @@
// {{{ Imports
use crate::arcaea::play::{CreatePlay, Play};
use crate::arcaea::score::Score;
use crate::context::{Context, Error};
@ -10,6 +11,7 @@ use poise::serenity_prelude as serenity;
use poise::serenity_prelude::CreateMessage;
use super::discord::MessageContext;
// }}}
// {{{ Score
/// Score management

View file

@ -1,34 +1,28 @@
// {{{ Imports
use std::io::Cursor;
use anyhow::anyhow;
use image::{DynamicImage, ImageBuffer};
use poise::{
serenity_prelude::{CreateAttachment, CreateEmbed},
CreateReply,
};
use poise::serenity_prelude::{CreateAttachment, CreateEmbed};
use poise::CreateReply;
use crate::{
arcaea::{
achievement::GoalStats,
chart::Level,
jacket::BITMAP_IMAGE_SIZE,
play::{compute_b30_ptt, get_best_plays},
rating::rating_as_float,
score::ScoringSystem,
},
assert_is_pookie,
assets::{
get_difficulty_background, with_font, B30_BACKGROUND, COUNT_BACKGROUND, EXO_FONT,
GRADE_BACKGROUND, NAME_BACKGROUND, PTT_EMBLEM, SCORE_BACKGROUND, STATUS_BACKGROUND,
TOP_BACKGROUND,
},
bitmap::{Align, BitmapCanvas, Color, LayoutDrawer, LayoutManager, Rect},
context::{Context, Error},
get_user,
logs::debug_image_log,
reply_errors, timed,
user::User,
use crate::arcaea::achievement::GoalStats;
use crate::arcaea::chart::Level;
use crate::arcaea::jacket::BITMAP_IMAGE_SIZE;
use crate::arcaea::play::{compute_b30_ptt, get_best_plays};
use crate::arcaea::rating::rating_as_float;
use crate::arcaea::score::ScoringSystem;
use crate::assets::{
get_difficulty_background, with_font, B30_BACKGROUND, COUNT_BACKGROUND, EXO_FONT,
GRADE_BACKGROUND, NAME_BACKGROUND, PTT_EMBLEM, SCORE_BACKGROUND, STATUS_BACKGROUND,
TOP_BACKGROUND,
};
use crate::bitmap::{Align, BitmapCanvas, Color, LayoutDrawer, LayoutManager, Rect};
use crate::context::{Context, Error};
use crate::logs::debug_image_log;
use crate::user::User;
use crate::{assert_is_pookie, get_user, reply_errors, timed};
// }}}
// {{{ Stats
/// Stats display

View file

@ -1,3 +1,4 @@
// {{{ Imports
use include_dir::{include_dir, Dir};
use r2d2::Pool;
use r2d2_sqlite::SqliteConnectionManager;
@ -6,34 +7,19 @@ use std::fs;
use std::path::Path;
use std::sync::LazyLock;
use crate::{
arcaea::{chart::SongCache, jacket::JacketCache},
assets::{get_data_dir, EXO_FONT, GEOSANS_FONT, KAZESAWA_BOLD_FONT, KAZESAWA_FONT},
recognition::{hyperglass::CharMeasurements, ui::UIMeasurements},
timed,
};
use crate::arcaea::{chart::SongCache, jacket::JacketCache};
use crate::assets::{get_data_dir, EXO_FONT, GEOSANS_FONT, KAZESAWA_BOLD_FONT, KAZESAWA_FONT};
use crate::recognition::{hyperglass::CharMeasurements, ui::UIMeasurements};
use crate::timed;
// }}}
// Types used by all command functions
// {{{ Common types
pub type Error = anyhow::Error;
pub type Context<'a> = poise::Context<'a, UserContext, Error>;
// }}}
// {{{ DB connection
pub type DbConnection = r2d2::Pool<SqliteConnectionManager>;
// Custom user data passed to all command functions
#[derive(Clone)]
pub struct UserContext {
pub db: DbConnection,
pub song_cache: SongCache,
pub jacket_cache: JacketCache,
pub ui_measurements: UIMeasurements,
pub geosans_measurements: CharMeasurements,
pub exo_measurements: CharMeasurements,
// TODO: do we really need both after I've fixed the bug in the ocr code?
pub kazesawa_measurements: CharMeasurements,
pub kazesawa_bold_measurements: CharMeasurements,
}
pub fn connect_db(data_dir: &Path) -> DbConnection {
fs::create_dir_all(data_dir).expect("Could not create $SHIMMERING_DATA_DIR");
@ -52,6 +38,22 @@ pub fn connect_db(data_dir: &Path) -> DbConnection {
Pool::new(SqliteConnectionManager::file(&db_path)).expect("Could not open sqlite database.")
}
// }}}
// {{{ UserContext
/// Custom user data passed to all command functions
#[derive(Clone)]
pub struct UserContext {
pub db: DbConnection,
pub song_cache: SongCache,
pub jacket_cache: JacketCache,
pub ui_measurements: UIMeasurements,
pub geosans_measurements: CharMeasurements,
pub exo_measurements: CharMeasurements,
// TODO: do we really need both after I've fixed the bug in the ocr code?
pub kazesawa_measurements: CharMeasurements,
pub kazesawa_bold_measurements: CharMeasurements,
}
impl UserContext {
#[inline]
@ -89,7 +91,8 @@ impl UserContext {
})
}
}
// }}}
// {{{ Testing helpers
#[cfg(test)]
pub mod testing {
use super::*;
@ -137,3 +140,4 @@ pub mod testing {
}};
}
}
// }}}

View file

@ -21,20 +21,18 @@
//! aforementioned precomputed vectors are generated using almost the exact
//! procedure described in steps 1-6, except the images are generated at
//! startup using my very own bitmap rendering module (`crate::bitmap`).
// {{{ Imports
use anyhow::{anyhow, bail};
use freetype::Face;
use image::{DynamicImage, ImageBuffer, Luma};
use imageproc::{
contrast::{threshold, ThresholdType},
region_labelling::{connected_components, Connectivity},
};
use imageproc::contrast::{threshold, ThresholdType};
use imageproc::region_labelling::{connected_components, Connectivity};
use num::traits::Euclid;
use crate::{
bitmap::{Align, BitmapCanvas, Color, TextStyle},
context::Error,
logs::{debug_image_buffer_log, debug_image_log},
};
use crate::bitmap::{Align, BitmapCanvas, Color, TextStyle};
use crate::context::Error;
use crate::logs::{debug_image_buffer_log, debug_image_log};
// }}}
// {{{ ConponentVec
/// How many sub-segments to split each side into

View file

@ -1,3 +1,4 @@
// {{{ Imports
use std::fmt::Display;
use anyhow::{anyhow, bail};
@ -20,6 +21,7 @@ use crate::recognition::ui::{
ScoreScreenRect, SongSelectRect, UIMeasurementRect, UIMeasurementRect::*,
};
use crate::transform::rotate;
// }}}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ScoreKind {

View file

@ -1,9 +1,13 @@
// {{{ Imports
use std::fs;
use anyhow::anyhow;
use image::GenericImage;
use crate::{assets::get_config_dir, bitmap::Rect, context::Error};
use crate::assets::get_config_dir;
use crate::bitmap::Rect;
use crate::context::Error;
// }}}
// {{{ Rects
#[derive(Debug, Clone, Copy)]

View file

@ -1,13 +1,8 @@
use std::str::FromStr;
use anyhow::anyhow;
use poise::serenity_prelude::UserId;
use rusqlite::Row;
use crate::{
commands::discord::MessageContext,
context::{Context, Error, UserContext},
};
use crate::commands::discord::MessageContext;
use crate::context::{Error, UserContext};
#[derive(Debug, Clone)]
pub struct User {
@ -75,14 +70,3 @@ impl User {
Ok(user)
}
}
#[inline]
pub async fn discord_id_to_discord_user(
&ctx: &Context<'_>,
discord_id: &str,
) -> Result<poise::serenity_prelude::User, Error> {
UserId::from_str(discord_id)?
.to_user(ctx.http())
.await
.map_err(|e| e.into())
}