Nicely format imports
This commit is contained in:
parent
0e0043d2c1
commit
50f8db4e2e
|
@ -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)]
|
||||||
|
|
|
@ -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)]
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)]
|
||||||
|
|
|
@ -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)]
|
||||||
|
|
|
@ -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]
|
||||||
|
|
|
@ -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)]
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 {
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// }}}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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)]
|
||||||
|
|
20
src/user.rs
20
src/user.rs
|
@ -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())
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue