padded readme out. made python location configurable. made ignore_bots configurable. replaced max_message_length with serenity's provided constant

This commit is contained in:
jude 2020-10-12 19:12:33 +01:00
parent 3756e462e0
commit 88596fb399
6 changed files with 31 additions and 11 deletions

View File

@ -11,4 +11,23 @@ Serenity and Rust are proving wonders for SoundFX. This is all in an effort to r
## How do I use it? ## How do I use it?
You'll need rustc and cargo for compilation. To run, you'll need Python 3 still (due to no suitable replacement for dateparser in Rust) You'll need rustc and cargo for compilation. To run, you'll need Python 3 still (due to no suitable replacement for dateparser in Rust)
TODO fill out the rest of this ### Compiling
Reminder Bot can be built by running `cargo build --release` in the top level directory.
### Setting up Python
Reminder Bot by default looks for a venv within it's working directory to run Python out of. To set up a venv, install `python-venv` and run `python -m venv venv`. Then, run `source venv/bin/activate` to activate the venv, and do `pip install dateparser` to install the required library
### Environment Variables
Reminder Bot reads a number of environment variables. Some are essential, and others have hardcoded fallbacks. Environment variables can be loaded from a .env file in the working directory.
__Required Variables__
* `DATABASE_URL` - the URL of your MySQL database (`mysql://user[:password]@domain/database`)
* `DISCORD_TOKEN` - your application's bot user's authorization token
__Other Variables__
* `LOCAL_TIMEZONE` - default `UTC`, necessary for calculations in the natural language processor
* `DEFAULT_PREFIX` - default `$`, used for the default prefix on new guilds
* `SUBSCRIPTION_ROLES` - default `None`, accepts a list of Discord role IDs that are given to subscribed users
* `CNC_GUILD` - default `None`, accepts a single Discord guild ID for the server that the subscription roles belong to
* `IGNORE_BOTS` - default `1`, if `1`, Reminder Bot will ignore all other bots
* `PYTHON_LOCATION` - default `venv/bin/python3`. Can be changed if your Python executable is located somewhere else

View File

@ -29,6 +29,7 @@ use crate::{
MIN_INTERVAL, MIN_INTERVAL,
MAX_TIME, MAX_TIME,
LOCAL_TIMEZONE, LOCAL_TIMEZONE,
PYTHON_LOCATION,
CHARACTERS, CHARACTERS,
DAY, DAY,
HOUR, HOUR,
@ -843,7 +844,7 @@ async fn natural(ctx: &Context, msg: &Message, args: String) -> CommandResult {
let (time_crop_opt, msg_crop_opt) = (args_iter.next(), args_iter.next()); let (time_crop_opt, msg_crop_opt) = (args_iter.next(), args_iter.next());
if let (Some(time_crop), Some(msg_crop)) = (time_crop_opt, msg_crop_opt) { if let (Some(time_crop), Some(msg_crop)) = (time_crop_opt, msg_crop_opt) {
let python_call = Command::new("venv/bin/python3") let python_call = Command::new(&*PYTHON_LOCATION)
.arg("dp.py") .arg("dp.py")
.arg(time_crop) .arg(time_crop)
.arg(&user_data.timezone) .arg(&user_data.timezone)
@ -863,7 +864,6 @@ async fn natural(ctx: &Context, msg: &Message, args: String) -> CommandResult {
let mut content = msg_crop; let mut content = msg_crop;
let mut interval = None; let mut interval = None;
// check other options and then create reminder :)
if msg.guild_id.is_some() { if msg.guild_id.is_some() {
let re_match = Regex::new(&format!(r#"(?:\s*)(?P<msg>.*) {} (?P<mentions>((?:<@\d+>)|(?:<@!\d+>)|(?:<#\d+>)|(?:\s+))+)$"#, to_str)) let re_match = Regex::new(&format!(r#"(?:\s*)(?P<msg>.*) {} (?P<mentions>((?:<@\d+>)|(?:<@!\d+>)|(?:<#\d+>)|(?:\s+))+)$"#, to_str))
.unwrap() .unwrap()
@ -898,7 +898,7 @@ async fn natural(ctx: &Context, msg: &Message, args: String) -> CommandResult {
let interval_str = captures.name("interval").unwrap().as_str(); let interval_str = captures.name("interval").unwrap().as_str();
let python_call = Command::new("venv/bin/python3") let python_call = Command::new(&*PYTHON_LOCATION)
.arg("dp.py") .arg("dp.py")
.arg(&format!("1 {}", interval_str)) .arg(&format!("1 {}", interval_str))
.arg(&*LOCAL_TIMEZONE) .arg(&*LOCAL_TIMEZONE)

View File

@ -1,6 +1,7 @@
use regex_command_attr::command; use regex_command_attr::command;
use serenity::{ use serenity::{
constants::MESSAGE_CODE_LIMIT,
client::Context, client::Context,
model::{ model::{
id::{ id::{
@ -20,7 +21,6 @@ use crate::{
UserData, UserData,
GuildData, GuildData,
}, },
consts::MAX_MESSAGE_LENGTH,
SQLPool, SQLPool,
}; };
use sqlx::MySqlPool; use sqlx::MySqlPool;
@ -321,7 +321,7 @@ async fn todo(ctx: &Context, msg: &Message, target: TodoTarget, subcommand: SubC
todo_items.iter().enumerate().for_each(|(count, todo)| { todo_items.iter().enumerate().for_each(|(count, todo)| {
let display = format!("{}: {}\n", count + 1, todo.value); let display = format!("{}: {}\n", count + 1, todo.value);
if char_count + display.len() > MAX_MESSAGE_LENGTH { if char_count + display.len() > MESSAGE_CODE_LIMIT as usize {
char_count = display.len(); char_count = display.len();
todo_groups.push(display); todo_groups.push(display);

View File

@ -1,5 +1,4 @@
pub const PREFIX: &str = "$"; pub const PREFIX: &str = "$";
pub const MAX_MESSAGE_LENGTH: usize = 2048;
pub const DAY: u64 = 86_400; pub const DAY: u64 = 86_400;
pub const HOUR: u64 = 3_600; pub const HOUR: u64 = 3_600;
@ -45,4 +44,6 @@ lazy_static! {
pub static ref MAX_TIME: i64 = env::var("MAX_TIME").ok().map(|inner| inner.parse::<i64>().ok()).flatten().unwrap_or(60*60*24*365*50); pub static ref MAX_TIME: i64 = env::var("MAX_TIME").ok().map(|inner| inner.parse::<i64>().ok()).flatten().unwrap_or(60*60*24*365*50);
pub static ref LOCAL_TIMEZONE: String = env::var("LOCAL_TIMEZONE").unwrap_or_else(|_| "UTC".to_string()); pub static ref LOCAL_TIMEZONE: String = env::var("LOCAL_TIMEZONE").unwrap_or_else(|_| "UTC".to_string());
pub static ref PYTHON_LOCATION: String = env::var("PYTHON_LOCATION").unwrap_or_else(|_| "venv/bin/python3".to_string());
} }

View File

@ -1,6 +1,7 @@
use async_trait::async_trait; use async_trait::async_trait;
use serenity::{ use serenity::{
constants::MESSAGE_CODE_LIMIT,
http::Http, http::Http,
Result as SerenityResult, Result as SerenityResult,
client::Context, client::Context,
@ -9,6 +10,7 @@ use serenity::{
standard::CommandResult, standard::CommandResult,
}, },
model::{ model::{
id::ChannelId,
guild::{ guild::{
Guild, Guild,
Member, Member,
@ -41,8 +43,6 @@ use crate::{
SQLPool, SQLPool,
consts::PREFIX, consts::PREFIX,
}; };
use serenity::model::id::ChannelId;
use crate::consts::MAX_MESSAGE_LENGTH;
type CommandFn = for<'fut> fn(&'fut Context, &'fut Message, String) -> BoxFuture<'fut, CommandResult>; type CommandFn = for<'fut> fn(&'fut Context, &'fut Message, String) -> BoxFuture<'fut, CommandResult>;
@ -168,7 +168,7 @@ impl SendIterator for ChannelId {
let mut current_content = String::new(); let mut current_content = String::new();
for line in content { for line in content {
if current_content.len() + line.len() > MAX_MESSAGE_LENGTH { if current_content.len() + line.len() > MESSAGE_CODE_LIMIT as usize {
self.say(&http, &current_content).await?; self.say(&http, &current_content).await?;
current_content = line; current_content = line;

View File

@ -88,7 +88,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let logged_in_id = http.get_current_user().map_ok(|user| user.id.as_u64().to_owned()).await?; let logged_in_id = http.get_current_user().map_ok(|user| user.id.as_u64().to_owned()).await?;
let framework = RegexFramework::new(logged_in_id) let framework = RegexFramework::new(logged_in_id)
.ignore_bots(true) .ignore_bots(env::var("IGNORE_BOTS").map_or(true, |var| var == "1"))
.default_prefix(&env::var("DEFAULT_PREFIX").unwrap_or_else(|_| PREFIX.to_string())) .default_prefix(&env::var("DEFAULT_PREFIX").unwrap_or_else(|_| PREFIX.to_string()))
.add_command("ping", &info_cmds::PING_COMMAND) .add_command("ping", &info_cmds::PING_COMMAND)