Skip to content

Commit

Permalink
random aphorism sequence
Browse files Browse the repository at this point in the history
  • Loading branch information
veeso committed Aug 31, 2022
1 parent 322c7b0 commit e8ea862
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 23 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Released on 31/08/2022

- From now on courses and aphorisms are read from `parameters.json`. RELOAD REQUIRES A BOT RESTART.
- Added `PARAMETERS_PATH` to environment parameters
- Repeating random aphorisms are now PREVENTED creating a shuffled sequence

## 0.3.4

Expand Down
62 changes: 46 additions & 16 deletions src/big_luca/aphorism.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,39 @@
//!
//! This module contains the papi's aphorisms

use super::PARAMETERS;
use rand::seq::SliceRandom;
use std::sync::atomic::{AtomicUsize, Ordering};

use rand::Rng;

pub struct Aphorism;
pub struct AphorismJar {
aphorisms: Vec<String>,
index: AtomicUsize,
}

impl Aphorism {
impl AphorismJar {
/// Get a random aphorism of the papi
pub fn get_random() -> String {
pub fn get_random(&self) -> &str {
if self.index.load(Ordering::Relaxed) >= self.aphorisms.len() {
self.index.store(0, Ordering::SeqCst);
}
let aphorism = self
.aphorisms
.get(self.index.load(Ordering::Relaxed))
.map(|x| x.as_str())
.unwrap_or_default();
self.index.fetch_add(1, Ordering::SeqCst);
aphorism
}
}

impl From<&[String]> for AphorismJar {
fn from(aphorisms: &[String]) -> Self {
let mut aphorisms: Vec<String> = aphorisms.iter().map(|x| x.to_string()).collect();
let mut rng = rand::thread_rng();
let aphorisms = PARAMETERS.get().unwrap().aphorisms.as_slice();
aphorisms[rng.gen_range(0..aphorisms.len())].clone()
aphorisms.shuffle(&mut rng);
Self {
aphorisms,
index: AtomicUsize::new(0),
}
}
}

Expand All @@ -22,18 +43,27 @@ mod test {

use super::*;
use crate::big_luca::Parameters;

use pretty_assertions::assert_eq;
use std::path::Path;

#[test]
fn should_get_random_aphorism() {
assert!(PARAMETERS
.set(Parameters::try_from_path(Path::new("config/parameters.json")).unwrap())
.is_ok());
assert!(!Aphorism::get_random().is_empty());
assert!(PARAMETERS
.get()
.unwrap()
let parameters = Parameters::try_from_path(Path::new("config/parameters.json")).unwrap();
let aphorism = AphorismJar::from(parameters.aphorisms.as_slice());
assert!(!aphorism.get_random().is_empty());
assert!(parameters
.aphorisms
.contains(&Aphorism::get_random()))
.contains(&aphorism.get_random().to_string()));
}

#[test]
fn should_wrap_and_increment_index() {
let parameters = Parameters::try_from_path(Path::new("config/parameters.json")).unwrap();
let aphorism = AphorismJar::from(&parameters.aphorisms[0..2]);
assert_eq!(aphorism.aphorisms.len(), 2);
assert_eq!(aphorism.aphorisms[0], aphorism.get_random());
assert_eq!(aphorism.aphorisms[1], aphorism.get_random());
assert_eq!(aphorism.aphorisms[0], aphorism.get_random());
}
}
18 changes: 15 additions & 3 deletions src/big_luca/automatize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,27 @@ use crate::big_luca::redis::RedisRepository;
use super::repository::Repository;
use super::rsshub::RssHubClient;
use super::youtube::Youtube;
use super::{AnswerBuilder, Aphorism, Stickers};
use super::{AnswerBuilder, AphorismJar, Parameters, Stickers};

use chrono::Utc;
use once_cell::sync::OnceCell;
use teloxide::prelude::*;
use teloxide::types::ChatId;
use thiserror::Error;
use tokio_cron_scheduler::{Job, JobScheduler, JobSchedulerError};

/// Aphorism jAR RESERVED TO THE AUTOMATIZER
static APHORISMS_JAR: OnceCell<AphorismJar> = OnceCell::new();

type AutomatizerResult<T> = Result<T, AutomatizerError>;

/// Automatizer error
#[derive(Debug, Error)]
pub enum AutomatizerError {
#[error("scheduler error: {0}")]
Scheduler(JobSchedulerError),
#[error("failed to setup aphorism jar")]
BadAphorisms,
}

impl From<JobSchedulerError> for AutomatizerError {
Expand All @@ -37,8 +43,14 @@ pub struct Automatizer {

impl Automatizer {
/// Start automatizer
pub async fn start() -> AutomatizerResult<Self> {
pub async fn start(params: &Parameters) -> AutomatizerResult<Self> {
debug!("starting automatizer");
if APHORISMS_JAR
.set(AphorismJar::from(params.aphorisms.as_slice()))
.is_err()
{
return Err(AutomatizerError::BadAphorisms);
}
Ok(Self {
scheduler: Self::setup_cron_scheduler().await?,
})
Expand Down Expand Up @@ -124,7 +136,7 @@ impl Automatizer {
async fn send_perla() -> anyhow::Result<()> {
let bot = Bot::from_env().auto_send();
let message = AnswerBuilder::default()
.text(Aphorism::get_random())
.text(APHORISMS_JAR.get().unwrap().get_random())
.sticker(Stickers::random())
.finalize();
for chat in Self::subscribed_chats().await?.iter() {
Expand Down
15 changes: 11 additions & 4 deletions src/big_luca/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,15 @@ use teloxide::{dispatching::update_listeners::webhooks, prelude::*, utils::comma
use url::Url;

use answer::{Answer, AnswerBuilder};
use aphorism::Aphorism;
use aphorism::AphorismJar;
use automatize::Automatizer;
use commands::Command;
pub use config::Config;
use once_cell::sync::OnceCell;
pub use parameters::Parameters;
use stickers::Stickers;

static APHORISMS_JAR: OnceCell<AphorismJar> = OnceCell::new();
pub static AUTOMATIZER: OnceCell<Automatizer> = OnceCell::new();
pub static PARAMETERS: OnceCell<Parameters> = OnceCell::new();

Expand All @@ -42,14 +43,20 @@ impl BigLuca {
if let Err(err) = Config::try_from_env() {
return Err(err);
}
let automatizer = Automatizer::start()
let parameters = Parameters::try_from_path(&config.parameters_path)?;
let automatizer = Automatizer::start(&parameters)
.await
.map_err(|e| anyhow::anyhow!("failed to start automatizer: {}", e))?;
// read parameters
if AUTOMATIZER.set(automatizer).is_err() {
anyhow::bail!("failed to set automatizer");
};
let parameters = Parameters::try_from_path(&config.parameters_path)?;
if APHORISMS_JAR
.set(AphorismJar::from(parameters.aphorisms.as_slice()))
.is_err()
{
anyhow::bail!("failed to set aphorisms");
}
if PARAMETERS.set(parameters).is_err() {
anyhow::bail!("failed to set parameters");
}
Expand Down Expand Up @@ -138,7 +145,7 @@ La lista di attesa può durare mesi e solo in pochi dopo una rigida selezione ri
/// Send a random aphorism
fn aphorism() -> Answer {
AnswerBuilder::default()
.text(Aphorism::get_random())
.text(APHORISMS_JAR.get().unwrap().get_random())
.sticker(Stickers::random())
.finalize()
}
Expand Down

0 comments on commit e8ea862

Please sign in to comment.