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 anyhow::anyhow;
use image::RgbaImage; use image::RgbaImage;
use crate::{ use crate::assets::get_data_dir;
assets::get_data_dir, use crate::context::{Error, UserContext};
context::{Error, UserContext}, use crate::user::User;
user::User,
};
use super::{ use super::chart::{Difficulty, Level};
chart::{Difficulty, Level}, use super::play::get_best_plays;
play::get_best_plays, use super::score::{Grade, ScoringSystem};
score::{Grade, ScoringSystem}, // }}}
};
// {{{ Goal // {{{ Goal
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,3 +1,4 @@
// {{{ Imports
use std::num::NonZeroU64; use std::num::NonZeroU64;
use std::path::PathBuf; use std::path::PathBuf;
use std::str::FromStr; use std::str::FromStr;
@ -7,7 +8,13 @@ use poise::serenity_prelude::{CreateAttachment, CreateMessage};
use crate::assets::get_var; use crate::assets::get_var;
use crate::context::Error; use crate::context::Error;
use crate::{commands::discord::MessageContext, context::UserContext}; 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 struct CliContext {
pub user_id: u64, pub user_id: u64,
pub data: UserContext, pub data: UserContext,

View file

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

View file

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

View file

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

View file

@ -1,34 +1,28 @@
// {{{ Imports
use std::io::Cursor; use std::io::Cursor;
use anyhow::anyhow; use anyhow::anyhow;
use image::{DynamicImage, ImageBuffer}; use image::{DynamicImage, ImageBuffer};
use poise::{ use poise::serenity_prelude::{CreateAttachment, CreateEmbed};
serenity_prelude::{CreateAttachment, CreateEmbed}, use poise::CreateReply;
CreateReply,
};
use crate::{ use crate::arcaea::achievement::GoalStats;
arcaea::{ use crate::arcaea::chart::Level;
achievement::GoalStats, use crate::arcaea::jacket::BITMAP_IMAGE_SIZE;
chart::Level, use crate::arcaea::play::{compute_b30_ptt, get_best_plays};
jacket::BITMAP_IMAGE_SIZE, use crate::arcaea::rating::rating_as_float;
play::{compute_b30_ptt, get_best_plays}, use crate::arcaea::score::ScoringSystem;
rating::rating_as_float, use crate::assets::{
score::ScoringSystem, get_difficulty_background, with_font, B30_BACKGROUND, COUNT_BACKGROUND, EXO_FONT,
}, GRADE_BACKGROUND, NAME_BACKGROUND, PTT_EMBLEM, SCORE_BACKGROUND, STATUS_BACKGROUND,
assert_is_pookie, TOP_BACKGROUND,
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::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
/// Stats display /// Stats display

View file

@ -1,3 +1,4 @@
// {{{ Imports
use include_dir::{include_dir, Dir}; use include_dir::{include_dir, Dir};
use r2d2::Pool; use r2d2::Pool;
use r2d2_sqlite::SqliteConnectionManager; use r2d2_sqlite::SqliteConnectionManager;
@ -6,34 +7,19 @@ use std::fs;
use std::path::Path; use std::path::Path;
use std::sync::LazyLock; use std::sync::LazyLock;
use crate::{ use crate::arcaea::{chart::SongCache, jacket::JacketCache};
arcaea::{chart::SongCache, jacket::JacketCache}, use crate::assets::{get_data_dir, EXO_FONT, GEOSANS_FONT, KAZESAWA_BOLD_FONT, KAZESAWA_FONT};
assets::{get_data_dir, EXO_FONT, GEOSANS_FONT, KAZESAWA_BOLD_FONT, KAZESAWA_FONT}, use crate::recognition::{hyperglass::CharMeasurements, ui::UIMeasurements};
recognition::{hyperglass::CharMeasurements, ui::UIMeasurements}, use crate::timed;
timed, // }}}
};
// Types used by all command functions // {{{ Common types
pub type Error = anyhow::Error; pub type Error = anyhow::Error;
pub type Context<'a> = poise::Context<'a, UserContext, Error>; pub type Context<'a> = poise::Context<'a, UserContext, Error>;
// }}}
// {{{ DB connection
pub type DbConnection = r2d2::Pool<SqliteConnectionManager>; 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 { pub fn connect_db(data_dir: &Path) -> DbConnection {
fs::create_dir_all(data_dir).expect("Could not create $SHIMMERING_DATA_DIR"); 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.") 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 { impl UserContext {
#[inline] #[inline]
@ -89,7 +91,8 @@ impl UserContext {
}) })
} }
} }
// }}}
// {{{ Testing helpers
#[cfg(test)] #[cfg(test)]
pub mod testing { pub mod testing {
use super::*; use super::*;
@ -137,3 +140,4 @@ pub mod testing {
}}; }};
} }
} }
// }}}

View file

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

View file

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

View file

@ -1,9 +1,13 @@
// {{{ Imports
use std::fs; use std::fs;
use anyhow::anyhow; use anyhow::anyhow;
use image::GenericImage; 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 // {{{ Rects
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]

View file

@ -1,13 +1,8 @@
use std::str::FromStr;
use anyhow::anyhow; use anyhow::anyhow;
use poise::serenity_prelude::UserId;
use rusqlite::Row; use rusqlite::Row;
use crate::{ use crate::commands::discord::MessageContext;
commands::discord::MessageContext, use crate::context::{Error, UserContext};
context::{Context, Error, UserContext},
};
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct User { pub struct User {
@ -75,14 +70,3 @@ impl User {
Ok(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())
}