24 Commits

Author SHA1 Message Date
AB
282efe5be4 Add k8s deploy example 2021-08-23 01:06:11 +03:00
AB
f1dc1d0897 Add Dockerfile. 2021-08-23 00:58:25 +03:00
AB
d8b37b32df Bump version 2021-08-20 21:22:43 +03:00
AB
47c68ee432 Update telegram-bot for a new UPDATEKU 2021-08-20 20:38:13 +03:00
AB
ac2be9929a Rollback tokio 2021-08-19 18:40:12 +03:00
7432ce6398 Bump many libs 2021-08-19 18:08:19 +03:00
AB
0831e3f503 Add хере command. 2021-06-12 15:02:09 +03:00
AB
a0f4c40be0 Add хере command. 2021-06-12 14:58:38 +03:00
AB
1facef6897 Add debug message. 2021-04-04 22:35:33 +03:00
AB
428416a2a3 Add handler in case of error in here command. 2021-03-10 19:57:45 +03:00
AB
77dec205f1 Bump version. 2021-01-20 20:16:08 +03:00
AB
6c761d7576 @here command now call only active users (at least 1 message in last 60 days) 2021-01-20 20:15:46 +03:00
AB
865fd3bbe4 Bump 2021-01-20 15:54:05 +03:00
AB
30bdb23a32 Add @here command 2021-01-20 15:53:22 +03:00
AB
f97562e9b7 Merge remote-tracking branch 'origin/main' into main 2021-01-11 11:39:34 +03:00
AB
2d000101c2 Merge 2021-01-11 11:39:20 +03:00
a26d227190 Merge pull request #10 from house-of-vanity/code
code
2021-01-11 11:26:51 +03:00
AB
cc44f0e23b Merge remote-tracking branch 'origin/main' into main
# Conflicts:
#	assets/help_text.rs
2021-01-11 11:22:47 +03:00
AB
96df636195 Add automerge action. 2021-01-11 11:21:18 +03:00
36660d384d Merge pull request #9 from house-of-vanity/code
Code
2021-01-10 21:39:38 +03:00
AB
788c2cbbd4 Fix type in help. 2021-01-09 01:06:10 +03:00
AB
9d5e5a3217 Fix type in help. 2021-01-08 17:54:05 +03:00
945da05794 Update README 2021-01-08 06:42:32 -08:00
3085d4c450 Merge pull request #8 from house-of-vanity/code
Code
2021-01-08 17:38:56 +03:00
11 changed files with 199 additions and 71 deletions

27
.github/workflows/automerge.yml vendored Normal file
View File

@ -0,0 +1,27 @@
name: automerge
on:
pull_request:
types:
- labeled
- unlabeled
- synchronize
- opened
- edited
- ready_for_review
- reopened
- unlocked
pull_request_review:
types:
- submitted
check_suite:
types:
- completed
status: {}
jobs:
automerge:
runs-on: ubuntu-latest
steps:
- name: automerge
uses: "pascalgn/automerge-action@v0.13.0"
env:
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"

1
.gitignore vendored
View File

@ -7,3 +7,4 @@ memory.sqlite3
/voice /voice
/.idea /.idea
Cargo.lock Cargo.lock
k8s/k8s-deploy.yaml

View File

@ -1,6 +1,6 @@
[package] [package]
name = "desubot" name = "desubot"
version = "0.5.1" version = "0.5.7"
authors = ["AB <ab@hexor.ru>"] authors = ["AB <ab@hexor.ru>"]
edition = "2018" edition = "2018"
@ -12,7 +12,8 @@ tokio = { version = "0.2", features = ["full"]}
tracing = "0.1.9" tracing = "0.1.9"
tracing-futures = "0.2" tracing-futures = "0.2"
multipart = { version = "0.16", default-features = false, features = ["client"] } multipart = { version = "0.16", default-features = false, features = ["client"] }
telegram-bot = "0.8.0" #telegram-bot = "0.8.0"
telegram-bot = { git = "https://github.com/ayrat555/telegram-bot", branch = "ayrat555/api-fixes-10" }
silicon = "0.4.0" silicon = "0.4.0"
hyper = "0.13" hyper = "0.13"
hyper-tls = { version = "0.4", optional = true } hyper-tls = { version = "0.4", optional = true }

14
Dockerfile Normal file
View File

@ -0,0 +1,14 @@
# syntax=docker/dockerfile:1
FROM rust:latest AS builder
WORKDIR /desubot
ADD ./ /desubot/
RUN cargo build --release
FROM ubuntu:latest
WORKDIR /storage
COPY --from=builder /desubot/target/release/desubot /usr/bin/
COPY mystem /usr/bin/
RUN apt update && apt install -y fontconfig openssl ca-certificates && rm -rf /var/lib/apt/lists/*
ENTRYPOINT desubot

2
README
View File

@ -7,8 +7,6 @@ Telegram bot with light group statistic and heavy spy features.
* /here command to mention all members. * /here command to mention all members.
* Alongside with saving whole message bot perform blacklist filter and stemming for every word (only Russian). "Красивую собаку мыли негры" -> "красивый собака мыть негр" * Alongside with saving whole message bot perform blacklist filter and stemming for every word (only Russian). "Красивую собаку мыли негры" -> "красивый собака мыть негр"
* Generate sentences using Markov Chains trained on history with /markov_all. * Generate sentences using Markov Chains trained on history with /markov_all.
== TODO ==
* Syntax highlighting for CODE exported to image. * Syntax highlighting for CODE exported to image.
== Important == == Important ==

View File

@ -2,7 +2,7 @@
static CODE_HELP: &str = "<b>Code highlighter</b> static CODE_HELP: &str = "<b>Code highlighter</b>
<i>Usage</i> <i>Usage</i>
<pre>/CODE <pre>/code
&lt;CODE&gt; &lt;CODE&gt;
#&lt;lang - JS by default&gt; #&lt;theme - Dracula by default&gt;</pre> #&lt;lang - JS by default&gt; #&lt;theme - Dracula by default&gt;</pre>

View File

@ -0,0 +1,43 @@
---
apiVersion: v1
kind: Secret
metadata:
name: desubot-api-token
data:
token: 123.... # Base64 encoded token.
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: desubot
spec:
serviceName: "desubot"
replicas: 1
selector:
matchLabels:
app: desubot
template:
metadata:
labels:
app: desubot
spec:
containers:
- name: desubot
image: ultradesu/desubot:latest
volumeMounts:
- name: storage
mountPath: /storage
env:
- name: TELEGRAM_BOT_TOKEN
valueFrom:
secretKeyRef:
name: desubot-api-token
key: token
volumeClaimTemplates:
- metadata:
name: storage
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 50Gi

View File

@ -21,7 +21,7 @@ use syntect::highlighting::Theme;
use syntect::parsing::SyntaxReference; use syntect::parsing::SyntaxReference;
use syntect::util::LinesWithEndings; use syntect::util::LinesWithEndings;
use telegram_bot::prelude::*; use telegram_bot::prelude::*;
use telegram_bot::{Api, Message, ParseMode}; use telegram_bot::{Api, Message, ParseMode, UserId};
include!("../assets/help_text.rs"); include!("../assets/help_text.rs");
@ -69,7 +69,7 @@ impl Execute for Sql {
let mut sql = self.data.clone(); let mut sql = self.data.clone();
debug!("PIZDA - {}", sql); debug!("PIZDA - {}", sql);
if sql == "/sql" || sql == "/sql-" { if sql == "/sql" || sql == "/sql-" {
return Ok(SQL_HELP.to_string()) return Ok(SQL_HELP.to_string());
} }
let is_head = if sql.starts_with('-') { let is_head = if sql.starts_with('-') {
sql = sql.replacen("-", "", 1); sql = sql.replacen("-", "", 1);
@ -192,7 +192,15 @@ impl Execute for Sql {
#[async_trait] #[async_trait]
impl Execute for Here { impl Execute for Here {
async fn exec(&self, api: &Api, message: &Message) -> Result<(), Error> { async fn exec(&self, api: &Api, message: &Message) -> Result<(), Error> {
let members: Vec<telegram_bot::User> = db::get_members(message.chat.id()).unwrap(); let members: Vec<telegram_bot::User> =
db::get_members(message.chat.id(), 60).unwrap_or(vec![telegram_bot::User {
id: UserId::new(124317807),
first_name: "Ultradesu".to_string(),
last_name: None,
username: None,
is_bot: false,
language_code: None,
}]);
for u in &members { for u in &members {
debug!("Found user {:?} in chat {}", u, message.chat.id()); debug!("Found user {:?} in chat {}", u, message.chat.id());
} }

View File

@ -180,18 +180,29 @@ pub(crate) async fn get_messages_user_all(
Ok(messages) Ok(messages)
} }
pub(crate) fn get_members(id: telegram_bot::ChatId) -> Result<Vec<telegram_bot::User>> { pub(crate) fn get_members(id: telegram_bot::ChatId, limit: u32) -> Result<Vec<telegram_bot::User>> {
let where_statement = if limit > 0 {
format!("and days_seen <= {}", limit)
} else {
"".into()
};
debug!("{}", where_statement);
let conn = open()?; let conn = open()?;
let mut stmt = conn.prepare_cached( let mut stmt = conn.prepare_cached(&format!(
" "
SELECT DISTINCT(u.username), u.id, u.first_name, u.last_name, u.date SELECT DISTINCT(u.username), u.id, u.first_name, u.last_name, u.date,
(strftime('%s','now')-r.date)/60/60/24 as days_seen
FROM relations r FROM relations r
JOIN user u JOIN user u
ON u.id = r.user_id ON u.id = r.user_id
LEFT JOIN conf c LEFT JOIN conf c
ON r.conf_id = c.id ON r.conf_id = c.id
WHERE c.id = :id", WHERE c.id = :id
)?; {}
GROUP BY u.id
ORDER BY r.date DESC",
where_statement
))?;
let mut rows = stmt.query_named(&[(":id", &id.to_string())])?; let mut rows = stmt.query_named(&[(":id", &id.to_string())])?;
let mut users = Vec::new(); let mut users = Vec::new();
@ -283,7 +294,11 @@ pub(crate) async fn add_user(message: Message) -> Result<(), Error> {
(":first_name", &update.first_name), (":first_name", &update.first_name),
(":last_name", &update.last_name), (":last_name", &update.last_name),
])?; ])?;
debug!("User {} updated: {:?}", update.first_name, get_user(update.id)); debug!(
"User {} updated: {:?}",
update.first_name,
get_user(update.id)
);
} }
Err(_) => { Err(_) => {
let unix_time = SystemTime::now() let unix_time = SystemTime::now()
@ -417,6 +432,7 @@ pub(crate) async fn add_sentence(
}; };
// Save stemmed words // Save stemmed words
debug!("Going to stem: {}", text);
let words = mystem.stemming(text)?; let words = mystem.stemming(text)?;
conn.execute("BEGIN TRANSACTION", params![]); conn.execute("BEGIN TRANSACTION", params![]);
for word in words { for word in words {

View File

@ -53,7 +53,12 @@ pub async fn handler(
} }
} }
} }
s if s.contains("/here") => { s if s.contains("/here")
|| s.contains("@here")
|| s.contains("/хере")
|| s.contains("@хере")
|| s.contains("\"хере") =>
{
db::add_sentence(&message, mystem).await?; db::add_sentence(&message, mystem).await?;
Here { Here {
data: "".to_string(), data: "".to_string(),
@ -118,9 +123,7 @@ pub async fn handler(
.exec_mystem(&api, &message, mystem) .exec_mystem(&api, &message, mystem)
.await? .await?
} }
_ => { _ => db::add_sentence(&message, mystem).await?,
db::add_sentence(&message, mystem).await?
}
} }
} }
MessageKind::Photo { ref caption, .. } => { MessageKind::Photo { ref caption, .. } => {

View File

@ -1,4 +1,6 @@
#![allow(unreachable_code)]
use std::{env, process}; use std::{env, process};
use tokio::time::{delay_for, Duration};
use futures::StreamExt; use futures::StreamExt;
use telegram_bot::*; use telegram_bot::*;
@ -16,7 +18,7 @@ use mystem::MyStem;
#[tokio::main] #[tokio::main]
async fn main() -> Result<(), errors::Error> { async fn main() -> Result<(), errors::Error> {
env_logger::from_env(Env::default().default_filter_or("info")).init(); env_logger::Builder::from_env(Env::default().default_filter_or("info")).init();
let mut mystem = match MyStem::new() { let mut mystem = match MyStem::new() {
Ok(mystem) => mystem, Ok(mystem) => mystem,
Err(e) => { Err(e) => {
@ -44,12 +46,20 @@ async fn main() -> Result<(), errors::Error> {
me.first_name, me.first_name,
me.id me.id
); );
loop {
while let Some(update) = stream.next().await { while let Some(update) = stream.next().await {
let update = update?; match update {
if let UpdateKind::Message(message) = update.kind { Ok(u) => {
if let UpdateKind::Message(message) = u.kind {
db::add_conf(message.clone()).await?; db::add_conf(message.clone()).await?;
db::add_user(message.clone()).await?; db::add_user(message.clone()).await?;
match handlers::handler(api.clone(), message, token.clone(), &mut mystem, me.clone()) match handlers::handler(
api.clone(),
message,
token.clone(),
&mut mystem,
me.clone(),
)
.await .await
{ {
Ok(_) => {} Ok(_) => {}
@ -57,5 +67,12 @@ async fn main() -> Result<(), errors::Error> {
} }
} }
} }
Err(e) => {
warn!("Telegram API Error: {:?}", e);
}
};
}
delay_for(Duration::from_secs(2)).await;
}
Ok(()) Ok(())
} }