Skip to content

Commit

Permalink
[DoD] Alternative selection modes [draft]
Browse files Browse the repository at this point in the history
  • Loading branch information
Leonid Kozarin committed Aug 22, 2024
1 parent 02b1516 commit aada05c
Show file tree
Hide file tree
Showing 15 changed files with 290 additions and 14 deletions.
7 changes: 7 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,12 @@ TOP_LIMIT=10
HELP_PUSSIES_COEF=0.01
LOAN_PAYOUT_COEF=0.1

# How to select winners of DoD? Possible options:
# 1) RANDOM - completely random
# 2) EXCLUSION - exlude TOP-N% (10% if ratio is 0.1)
# 3) WEIGHTS - the less your dick is the more chances you have
DOD_SELECTION_MODE=EXCLUSION
DOD_RICH_EXCLUSION_RATIO=0.1

# to enable Webhook Mode, set to a correct URL, proxied by a reverse proxy server
#WEBHOOK_URL=https://your.domain/DickGrowerBot/webhook

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ chrono = { version = "0.4.31", features = [ "serde" ] }
tinytemplate = "1.2.1"
base64 = { package = "simple-base64", version = "0.23.2" }
byteorder = "1.5.0"
derive_more = { version = "1.0.0-beta.6", features = ["display", "error", "constructor", "from"] }
derive_more = { version = "1.0.0-beta.6", features = ["display", "error", "constructor", "from", "from_str"] }
num-traits = "0.2.18"
downcast-rs = "1.2.0"
flurry = "0.5.1"
Expand Down
2 changes: 2 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ ARG NEWCOMERS_GRACE_DAYS
ARG TOP_LIMIT
ARG HELP_PUSSIES_COEF
ARG LOAN_PAYOUT_COEF
ARG DOD_SELECTION_MODE
ARG DOD_RICH_EXCLUSION_RATIO
ENTRYPOINT [ "/usr/local/bin/dickGrowerBot" ]

LABEL org.opencontainers.image.source=https://github.com/kozalosev/DickGrowerBot
Expand Down
2 changes: 2 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ services:
- TOP_LIMIT
- HELP_PUSSIES_COEF
- LOAN_PAYOUT_COEF
- DOD_SELECTION_MODE
- DOD_RICH_EXCLUSION_RATIO
expose:
- 8080
networks:
Expand Down
31 changes: 31 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use std::sync::{Arc, RwLock};
use anyhow::anyhow;
use reqwest::Url;
use teloxide::types::Me;
use crate::domain::Ratio;
use crate::handlers::perks::HelpPussiesPerk;
use crate::handlers::utils::Incrementor;
use crate::help;
Expand All @@ -18,6 +19,7 @@ pub struct AppConfig {
pub features: FeatureToggles,
pub top_limit: u16,
pub loan_payout_ratio: f32,
pub dod_rich_exclusion_ratio: Option<Ratio>,
pub command_toggles: CachedEnvToggles,
}

Expand All @@ -31,6 +33,7 @@ pub struct DatabaseConfig {
pub struct FeatureToggles {
pub chats_merging: bool,
pub top_unlimited: bool,
pub dod_selection_mode: DickOfDaySelectionMode,
pub pvp: BattlesFeatureToggles,
}

Expand All @@ -40,6 +43,7 @@ impl Default for FeatureToggles {
Self {
chats_merging: true,
top_unlimited: true,
dod_selection_mode: Default::default(),
pvp: Default::default(),
}
}
Expand All @@ -53,10 +57,20 @@ pub struct BattlesFeatureToggles {
pub show_stats_notice: bool,
}

#[derive(Copy, Clone, Default, derive_more::FromStr, derive_more::Display)]
pub enum DickOfDaySelectionMode {
WEIGHTS,
EXCLUSION,
#[default]
RANDOM
}

impl AppConfig {
pub fn from_env() -> Self {
let top_limit = get_env_value_or_default("TOP_LIMIT", 10);
let loan_payout_ratio = get_env_value_or_default("LOAN_PAYOUT_COEF", 0.0);
let dod_selection_mode = get_optional_env_value("DOD_SELECTION_MODE");
let dod_rich_exclusion_ratio = get_optional_env_ratio("DOD_RICH_EXCLUSION_RATIO");
let chats_merging = get_env_value_or_default("CHATS_MERGING_ENABLED", false);
let top_unlimited = get_env_value_or_default("TOP_UNLIMITED_ENABLED", false);
let check_acceptor_length = get_env_value_or_default("PVP_CHECK_ACCEPTOR_LENGTH", false);
Expand All @@ -67,6 +81,7 @@ impl AppConfig {
features: FeatureToggles {
chats_merging,
top_unlimited,
dod_selection_mode,
pvp: BattlesFeatureToggles {
check_acceptor_length,
callback_locks,
Expand All @@ -76,6 +91,7 @@ impl AppConfig {
},
top_limit,
loan_payout_ratio,
dod_rich_exclusion_ratio,
command_toggles: Default::default(),
}
}
Expand Down Expand Up @@ -165,6 +181,21 @@ where
.unwrap_or(default)
}

fn get_optional_env_value<T>(key: &str) -> T
where
T: Default + FromStr + Display,
<T as FromStr>::Err: Error + Send + Sync + 'static
{
get_env_value_or_default(key, T::default())
}

fn get_optional_env_ratio(key: &str) -> Option<Ratio> {
let value = get_env_value_or_default(key, -1.0);
Ratio::new(value)
.inspect_err(|_| log::warn!("{key} is disabled due to the invalid value: {value}"))
.ok()
}

fn ensure_starts_with_at_sign(s: String) -> String {
if s.starts_with('@') {
s
Expand Down
2 changes: 2 additions & 0 deletions src/domain/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
mod username;
mod ratio;

pub use username::*;
pub use ratio::*;
21 changes: 21 additions & 0 deletions src/domain/ratio.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use derive_more::{Display, Error};

#[derive(Debug, Copy, Clone, PartialEq)]
pub struct Ratio(f64);

#[derive(Debug, Display, Error)]
pub struct InvalidRatioValue(#[error(not(source))] f64);

impl Ratio {
pub fn new(value: f64) -> Result<Self, InvalidRatioValue> {
if (0.0..=1.0).contains(&value) {
Ok(Self(value))
} else {
Err(InvalidRatioValue(value))
}
}

pub fn to_value(self) -> f64 {
self.0
}
}
21 changes: 16 additions & 5 deletions src/handlers/dod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ use rust_i18n::t;
use teloxide::Bot;
use teloxide::macros::BotCommands;
use teloxide::types::{Message, UserId};
use crate::{metrics, repo};
use crate::{config, metrics, repo};
use crate::config::DickOfDaySelectionMode;
use crate::handlers::{ensure_lang_code, FromRefs, HandlerResult, reply_html, utils};
use crate::handlers::utils::Incrementor;

Expand All @@ -19,20 +20,30 @@ pub enum DickOfDayCommands {
}

pub async fn dod_cmd_handler(bot: Bot, msg: Message,
repos: repo::Repositories, incr: Incrementor) -> HandlerResult {
cfg: config::AppConfig, repos: repo::Repositories, incr: Incrementor) -> HandlerResult {
metrics::CMD_DOD_COUNTER.chat.inc();
let from = msg.from().ok_or(anyhow!("unexpected absence of a FROM field"))?;
let chat_id = msg.chat.id.into();
let from_refs = FromRefs(from, &chat_id);
let answer = dick_of_day_impl(&repos, incr, from_refs).await?;
let answer = dick_of_day_impl(cfg, &repos, incr, from_refs).await?;
reply_html(bot, msg, answer).await?;
Ok(())
}

pub(crate) async fn dick_of_day_impl(repos: &repo::Repositories, incr: Incrementor, from_refs: FromRefs<'_>) -> anyhow::Result<String> {
pub(crate) async fn dick_of_day_impl(cfg: config::AppConfig, repos: &repo::Repositories, incr: Incrementor,
from_refs: FromRefs<'_>) -> anyhow::Result<String> {
let (from, chat_id) = (from_refs.0, from_refs.1);
let lang_code = ensure_lang_code(Some(from));
let winner = repos.users.get_random_active_member(&chat_id.kind()).await?;
let winner = match cfg.features.dod_selection_mode {
DickOfDaySelectionMode::WEIGHTS => {
repos.users.get_random_active_member_with_poor_in_priority(&chat_id.kind()).await?
},
DickOfDaySelectionMode::EXCLUSION if cfg.dod_rich_exclusion_ratio.is_some() => {
let rich_exclusion_ratio = cfg.dod_rich_exclusion_ratio.unwrap();
repos.users.get_random_active_poor_member(&chat_id.kind(), rich_exclusion_ratio).await?
},
_ => repos.users.get_random_active_member(&chat_id.kind()).await?
};
let answer = match winner {
Some(winner) => {
let increment = incr.dod_increment(from.id, chat_id.kind()).await;
Expand Down
2 changes: 1 addition & 1 deletion src/handlers/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ impl InlineCommand {
},
InlineCommand::DickOfDay => {
metrics::CMD_DOD_COUNTER.inline.inc();
dod::dick_of_day_impl(repos, incr, from_refs)
dod::dick_of_day_impl(config, repos, incr, from_refs)
.await
.map(InlineResult::text)
},
Expand Down
Loading

0 comments on commit aada05c

Please sign in to comment.