1
0
mirror of https://github.com/osmarks/autobotrobot synced 2024-09-27 14:48:14 +00:00

Execute some languages via coliru

This commit is contained in:
osmarks 2018-11-11 10:03:25 +00:00
parent a2718a2442
commit 8ad0dbb06c

View File

@ -4,6 +4,7 @@ extern crate calc;
extern crate ddg;
extern crate regex;
#[macro_use] extern crate lazy_static;
extern crate reqwest;
use serenity::client::{Client, EventHandler};
use serenity::framework::standard::{StandardFramework, help_commands};
@ -31,11 +32,11 @@ pub fn main() {
.case_insensitivity(true)
.on_mention(true))
.help(help_commands::with_embeds)
.before(|_context, _message, command| { println!("Executing {}!", command); true })
.before(|_context, message, _command| { println!("> {}", message.content); true })
.command("ping", |c| c.cmd(ping).desc("Says Pong.").known_as("test"))
.command("search", |c| c.cmd(search).desc("Executes a search using DuckDuckGo.").known_as("ddg"))
.command("eval", |c| c.cmd(eval).desc("Evaluates an arithmetic expression.").known_as("calc"))
.command("exec", |c| c.cmd(exec).desc("DO NOT USE"))
.command("exec", |c| c.cmd(exec).desc("Executes code passed in codeblock with language set via Coliru. Supported languages: python, shell."))
.command("eval-polish", |c| c.cmd(eval_polish).desc("Evaluates a Polish-notation arithmetic expression.")));
if let Err(why) = client.start() {
@ -80,6 +81,48 @@ command!(eval_polish(_context, message, args) {
send_result(message, &calc::eval_polish(&expr))?;
});
fn execute_coliru(command: &str, code: &str) -> Result<String, reqwest::Error> {
lazy_static! {
static ref CLIENT: reqwest::Client = reqwest::Client::new();
}
let mut data = std::collections::HashMap::new();
data.insert("src", code);
data.insert("cmd", command);
let mut res = CLIENT.post("http://coliru.stacked-crooked.com/compile")
.json(&data)
.send()?;
Ok(res.text()?)
}
// Thanks StackOverflow!
fn truncate(s: &str, max_chars: usize) -> &str {
match s.char_indices().nth(max_chars) {
None => s,
Some((idx, _)) => &s[..idx],
}
}
fn to_code_block(s: &str) -> String {
format!("```\n{}\n```", truncate(s, 1990)) // Discord only allows 2000 Unicode codepoints per message
}
fn execute_and_respond(channel: &ChannelId, command: &str, code: &str) -> Result<(), serenity::Error> {
let coliru_result = execute_coliru(command, code);
match coliru_result {
Ok(stdout) => {
channel.send_message(|m|
m.content(&to_code_block(&stdout)))?;
},
Err(e) => send_error(channel, &format!("{}", e))?
}
Ok(())
}
command!(exec(_context, message) {
lazy_static! {
static ref RE: Regex = Regex::new("(?s)^.*exec.*```([a-zA-Z0-9_\\-+]+)\n(.+)\n```").unwrap();
@ -96,10 +139,16 @@ command!(exec(_context, message) {
let code = &captures[2];
let lang = &captures[1];
let channel = &message.channel_id;
match lang {
_ => send_error(&message.channel_id, &format!("Unknown language `{}`.", lang))?
};
"test" => execute_and_respond(channel, "echo Hello, World!", ""),
"py" | "python" => execute_and_respond(channel, "mv main.cpp main.py && python main.py", code),
"sh" | "shell" => execute_and_respond(channel, "mv main.cpp main.sh && sh main.sh", code),
"lua" => execute_and_respond(channel, "mv main.cpp main.lua && lua main.lua", code),
"haskell" | "hs" => execute_and_respond(channel, "mv main.cpp main.hs && runhaskell main.hs", code),
_ => send_error(channel, &format!("Unknown language `{}`.", lang))
}?;
});
// BELOW THIS LINE BE DRAGONS
@ -154,6 +203,7 @@ command!(search(_context, message, args) {
let query = args.multiple::<String>()?.join(" ");
let result = ddg::Query::new(query.as_str(), "autobotrobot").no_html().execute()?;
let channel = &message.channel_id;
match result.response_type {
ddg::Type::Article | ddg::Type::Name => send_search_result(channel, SearchResult {
title: query,