Compare commits

..

5 Commits

Author SHA1 Message Date
c8979bef2a Add drone-ci
Some checks failed
continuous-integration/drone/push Build is failing
2020-10-29 16:07:33 +01:00
d6fa0c5530 Add v1 of the shitty-emojipasta 2020-10-29 16:06:48 +01:00
ac039233ea rewrite dockerfile / deployment 2020-10-25 12:19:35 +01:00
95bd2077ce refactor sarcastifybot 2020-10-25 12:16:42 +01:00
59f91e72e9 Added shitty 3rd option 2020-09-08 17:06:51 +02:00
8 changed files with 4019 additions and 444 deletions

11
.drone.yml Normal file
View File

@@ -0,0 +1,11 @@
kind: pipeline
type: kubernetes
name: default
steps:
- name: test
image: rust:1.47
commands:
- cargo build --all
- cargo test --verbose --all

818
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -12,4 +12,8 @@ telegram-bot = "0.7.0"
dotenv = "0.15.0"
tokio = { version="^0.2.0", features=["macros"] }
futures = "^0.3.5"
futures = "^0.3.5"
serde_json = "1.0"
once_cell = "^1.4.1"
indexmap = { version="1.6.0", features=["serde-1"] }
rand = "0.7.3"

View File

@@ -1,10 +1,21 @@
FROM rust:1.43 as builder
FROM rust:1.47 as builder
WORKDIR /usr/src/sarcastifybot
# Avoid having to install/build all dependencies by copying
# the Cargo files and making a dummy src/main.rs
COPY Cargo.toml .
COPY Cargo.lock .
RUN mkdir -p src && echo "fn main() {}" > src/main.rs
RUN cargo build --release
# We need to touch our real main.rs file or else docker will use
# the cached one.
COPY . .
RUN cargo install --path .
RUN touch src/main.rs
RUN cargo build --release
FROM debian:buster
RUN apt-get update && apt-get install -y openssl ca-certificates
COPY --from=builder /usr/local/cargo/bin/sarcastifybot /usr/local/bin/sarcastifybot
COPY --from=builder /usr/src/sarcastifybot/target/release/sarcastifybot /usr/local/bin/sarcastifybot
CMD ["sarcastifybot"]

View File

@@ -1,7 +1,7 @@
IMAGE_TAG=harbor.blacknova.io/nvls/sarcastifybot:latest
image:
docker build -t $(IMAGE_TAG) .
podman build -t $(IMAGE_TAG) .
push:
docker push $(IMAGE_TAG)
podman push $(IMAGE_TAG)

3408
assets/emojis.json Normal file

File diff suppressed because it is too large Load Diff

23
deployment.yml Normal file
View File

@@ -0,0 +1,23 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: sarcastifybot
labels:
app: sarcastifybot
spec:
replicas: 1
selector:
matchLabels:
app: sarcastifybot
template:
metadata:
labels:
app: sarcastifybot
spec:
containers:
- name: main
image: harbor.blacknova.io/nvls/sarcastifybot:latest
imagePullPolicy: Always
env:
- name: TELEGRAM_BOT_TOKEN
value: "924754197:AAGvpdqUY-2pOy1wnQIW2zeS-oA7-lxwfqU"

View File

@@ -3,11 +3,129 @@ use std::env;
use dotenv::dotenv;
use futures::StreamExt;
use telegram_bot::*;
use once_cell::sync::Lazy;
use indexmap::map::IndexMap;
static EMOJI_DATA: Lazy<IndexMap<String, String>> = Lazy::new(|| {
let data = include_str!("../assets/emojis.json");
serde_json::from_str(data).expect("Failed to parse json emoji data")
});
/// Returns two versions of AlTeRnAtInG case equivalents of the given message
/// The first result contains the a version beginning with an uppercase letter,
/// the second result begins with a lowercase letter.
///
/// # Arguments
///
/// * `message` - A string slice that contains the message to convert
fn generate_alternate_case(message: &str) -> (String, String) {
let mut option1 = String::new();
let mut option2 = String::new();
let mut stream = message.chars().enumerate();
while let Some((idx, letter)) = stream.next() {
if idx % 2 == 0 {
option1.push(letter.to_uppercase().next().unwrap());
option2.push(letter.to_lowercase().next().unwrap());
} else {
option1.push(letter.to_lowercase().next().unwrap());
option2.push(letter.to_uppercase().next().unwrap());
}
}
(option1, option2)
}
/// Generate a spaced-out version of the message.
///
/// # Arguments
///
/// * `message` - A string slice that contains the message to convert
fn generate_spaced(message: &str) -> String
{
let mut result = String::new();
let mut stream = message.chars().enumerate();
while let Some((_, letter)) = stream.next() {
result.push(letter);
result.push(' ');
}
// Trim trailing space
result.pop();
result
}
fn generate_emojipasta(message: &str) -> String
{
use rand::seq::SliceRandom;
let mut rng = rand::thread_rng();
let emojis: Vec<&String> = EMOJI_DATA.values().collect();
let mut result: Vec<String> = Vec::new();
let mut stream = message.split_whitespace().enumerate();
while let Some((_, word)) = stream.next() {
result.push(word.into());
// Lowercase word
let word: String = word.to_lowercase();
if let Some(emoji) = EMOJI_DATA.get(&word) {
result.push(emoji.to_string());
} else if let Some(emoji) = emojis.choose(&mut rng) {
result.push(emoji.to_string());
}
}
return result.join(" ");
}
fn generate_responses(message: &str) -> Vec<InlineQueryResult> {
if message == "" {
return vec![];
}
let (alt_up, alt_down) = generate_alternate_case(message);
let spaced = generate_spaced(message);
let pasta = generate_emojipasta(message);
vec![
InlineQueryResultArticle::new(
"altcase_up", alt_up.clone(), InputTextMessageContent {
message_text: alt_up,
parse_mode: None,
disable_web_page_preview: false,
}
).into(),
InlineQueryResultArticle::new(
"altcase_down", alt_down.clone(), InputTextMessageContent {
message_text: alt_down,
parse_mode: None,
disable_web_page_preview: false,
}
).into(),
InlineQueryResultArticle::new(
"spaced", spaced.clone(), InputTextMessageContent {
message_text: spaced,
parse_mode: None,
disable_web_page_preview: false,
}
).into(),
InlineQueryResultArticle::new(
"emojipasta", pasta.clone(), InputTextMessageContent {
message_text: pasta,
parse_mode: None,
disable_web_page_preview: false,
}
).into(),
]
}
#[tokio::main]
async fn main() {
dotenv().ok();
let token = env::var("TELEGRAM_BOT_TOKEN").expect("TELEGRAM_BOT_TOKEN not set");
let api = Api::new(token);
@@ -20,42 +138,26 @@ async fn main() {
};
if let UpdateKind::InlineQuery(query) = update.kind {
let mut option1 = String::new();
let mut option2 = String::new();
if query.query == "" {
api.send(query.answer(vec![])).await.ok();
continue;
}
{
let mut stream = query.query.chars().enumerate();
while let Some((idx, letter)) = stream.next() {
if idx % 2 == 0 {
option1.push(letter.to_uppercase().next().unwrap());
option2.push(letter.to_lowercase().next().unwrap());
} else {
option1.push(letter.to_lowercase().next().unwrap());
option2.push(letter.to_uppercase().next().unwrap());
}
}
}
api.send(query.answer(vec![
InlineQueryResultArticle::new(
"1", option1.clone(), InputTextMessageContent {
message_text: option1,
parse_mode: None,
disable_web_page_preview: false,
}
).into(),
InlineQueryResultArticle::new(
"2", option2.clone(), InputTextMessageContent {
message_text: option2,
parse_mode: None,
disable_web_page_preview: false,
}
).into(),
])).await.ok();
let responses = generate_responses(&query.query);
api.send(query.answer(responses)).await.ok();
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_alternating() {
let (option1, option2) = generate_alternate_case("This is a test");
assert_eq!(option1, "ThIs iS A TeSt");
assert_eq!(option2, "tHiS Is a tEsT");
}
#[test]
fn test_spaced() {
let option = generate_spaced("This is a test");
assert_eq!(option, "T h i s i s a t e s t")
}
}