Compare commits
5 Commits
6a93251d81
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| c8979bef2a | |||
| d6fa0c5530 | |||
| ac039233ea | |||
| 95bd2077ce | |||
| 59f91e72e9 |
11
.drone.yml
Normal file
11
.drone.yml
Normal 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
818
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -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"
|
||||
|
||||
17
Dockerfile
17
Dockerfile
@@ -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"]
|
||||
|
||||
4
Makefile
4
Makefile
@@ -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
3408
assets/emojis.json
Normal file
File diff suppressed because it is too large
Load Diff
23
deployment.yml
Normal file
23
deployment.yml
Normal 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"
|
||||
176
src/main.rs
176
src/main.rs
@@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user