2020-11-28 17:31:08 +03:00
use crate ::db ;
2020-12-08 12:31:21 +03:00
use crate ::errors ::Error ;
2020-12-31 01:42:36 +03:00
use async_trait ::async_trait ;
2020-11-29 16:23:27 +03:00
use html_escape ::encode_text ;
2020-12-08 12:31:21 +03:00
use markov ::Chain ;
2020-12-30 14:30:53 +03:00
use mystem ::Case ::Nominative ;
2020-12-29 17:01:56 +03:00
use mystem ::Gender ::Feminine ;
2020-12-30 09:24:15 +03:00
use mystem ::Tense ::{ Inpresent , Past } ;
2020-12-30 14:30:53 +03:00
use mystem ::VerbPerson ::First ;
use mystem ::{ MyStem , VerbPerson } ;
2020-12-29 17:01:56 +03:00
use rand ::seq ::SliceRandom ;
2020-12-09 18:13:59 +03:00
use rand ::Rng ;
2020-12-29 17:01:56 +03:00
use regex ::Regex ;
2020-11-28 17:31:08 +03:00
use telegram_bot ::prelude ::* ;
2020-12-07 17:41:12 +03:00
use telegram_bot ::{ Api , Message , ParseMode } ;
2020-11-28 17:31:08 +03:00
2020-12-31 01:42:36 +03:00
pub struct Here {
pub data : String ,
}
pub struct Top {
pub data : String ,
}
pub struct MarkovAll {
pub data : String ,
}
pub struct Markov {
pub data : String ,
}
pub struct Omedeto {
pub data : String ,
}
// pub enum Command {
// Here(Here),
// Top { data: String },
// MarkovAll { data: String },
// Markov { data: String },
// Omedeto { data: String },
// }
#[ async_trait ]
pub trait Execute {
async fn run ( & self , api : Api , message : Message ) -> Result < ( ) , Error > ;
async fn run_mystem (
& self ,
api : Api ,
message : Message ,
mystem : & mut MyStem ,
) -> Result < ( ) , Error > ;
}
#[ async_trait ]
impl Execute for Here {
async fn run ( & self , api : Api , message : Message ) -> Result < ( ) , Error > {
let members : Vec < telegram_bot ::User > = db ::get_members ( message . chat . id ( ) ) . unwrap ( ) ;
for u in & members {
debug! ( " Found user {:?} in chat {} " , u , message . chat . id ( ) ) ;
}
let mut msg = " <b>I summon you</b>, " . to_string ( ) ;
for user in members {
let mention = match user . username {
Some ( username ) = > format! ( " @ {} " , username ) ,
_ = > format! (
" <a href= \" tg://user?id={} \" >{}</a> " ,
encode_text ( & user . id . to_string ( ) ) ,
encode_text ( & user . first_name )
) ,
} ;
msg = format! ( " {} {} " , msg , mention ) ;
}
match api
. send ( message . text_reply ( msg ) . parse_mode ( ParseMode ::Html ) )
. await
{
Ok ( _ ) = > debug! ( " /here command sent to {} " , message . chat . id ( ) ) ,
Err ( _ ) = > warn! ( " /here command sent failed to {} " , message . chat . id ( ) ) ,
}
//api.send(message.chat.text("Text to message chat")).await?;
//api.send(message.from.text("Private text")).await?;
Ok ( ( ) )
2020-11-28 17:31:08 +03:00
}
2020-12-31 01:42:36 +03:00
async fn run_mystem (
& self ,
api : Api ,
message : Message ,
mystem : & mut MyStem ,
) -> Result < ( ) , Error > {
unimplemented! ( )
2020-12-06 23:55:09 +03:00
}
2020-11-28 17:31:08 +03:00
}
2020-12-07 17:41:12 +03:00
2020-12-31 01:42:36 +03:00
#[ async_trait ]
impl Execute for Top {
async fn run ( & self , api : Api , message : Message ) -> Result < ( ) , Error > {
let top = db ::get_top ( & message ) . await ? ;
let mut msg = " <b>Your top using words:</b> \n <pre> " . to_string ( ) ;
let mut counter = 1 ;
for word in top . iter ( ) {
msg = format! (
" {} <b>{}</b> {} - {} \n " ,
msg , counter , word . word , word . count
) ;
counter + = 1 ;
}
msg = format! ( " {} {} " , msg , " </pre> " ) ;
match api
. send ( message . text_reply ( msg ) . parse_mode ( ParseMode ::Html ) )
. await
{
Ok ( _ ) = > debug! ( " /top command sent to {} " , message . chat . id ( ) ) ,
Err ( _ ) = > warn! ( " /top command sent failed to {} " , message . chat . id ( ) ) ,
}
//api.send(message.chat.text("Text to message chat")).await?;
//api.send(message.from.text("Private text")).await?;
Ok ( ( ) )
2020-12-07 17:41:12 +03:00
}
2020-12-31 01:42:36 +03:00
async fn run_mystem (
& self ,
api : Api ,
message : Message ,
mystem : & mut MyStem ,
) -> Result < ( ) , Error > {
unimplemented! ( )
2020-12-07 17:41:12 +03:00
}
2020-12-08 12:31:21 +03:00
}
2020-12-31 01:42:36 +03:00
#[ async_trait ]
impl Execute for MarkovAll {
async fn run ( & self , api : Api , message : Message ) -> Result < ( ) , Error > {
let messages = db ::get_messages_random_all ( ) . await ? ;
let mut chain = Chain ::new ( ) ;
chain . feed ( messages ) ;
let mut sentences = chain . generate ( ) ;
let mut msg = String ::new ( ) ;
for _ in 1 .. rand ::thread_rng ( ) . gen_range ( 2 , 10 ) {
msg = format! ( " {} {} " , msg , sentences . pop ( ) . unwrap ( ) ) ;
}
match api
. send ( message . text_reply ( msg . trim ( ) ) . parse_mode ( ParseMode ::Html ) )
. await
{
Ok ( _ ) = > debug! ( " /markov_all command sent to {} " , message . chat . id ( ) ) ,
Err ( _ ) = > warn! ( " /markov_all command sent failed to {} " , message . chat . id ( ) ) ,
}
//api.send(message.chat.text("Text to message chat")).await?;
//api.send(message.from.text("Private text")).await?;
Ok ( ( ) )
2020-12-08 12:31:21 +03:00
}
2020-12-31 01:42:36 +03:00
async fn run_mystem (
& self ,
api : Api ,
message : Message ,
mystem : & mut MyStem ,
) -> Result < ( ) , Error > {
unimplemented! ( )
2020-12-08 12:31:21 +03:00
}
}
2020-12-11 15:53:14 +03:00
2020-12-31 01:42:36 +03:00
#[ async_trait ]
impl Execute for Markov {
async fn run ( & self , api : Api , message : Message ) -> Result < ( ) , Error > {
let messages = db ::get_messages_random_group ( & message ) . await ? ;
let mut chain = Chain ::new ( ) ;
chain . feed ( messages ) ;
let mut sentences = chain . generate ( ) ;
let mut msg = String ::new ( ) ;
for _ in 1 .. rand ::thread_rng ( ) . gen_range ( 2 , 10 ) {
msg = format! ( " {} {} " , msg , sentences . pop ( ) . unwrap ( ) ) ;
}
match api
. send ( message . text_reply ( msg . trim ( ) ) . parse_mode ( ParseMode ::Html ) )
. await
{
Ok ( _ ) = > debug! ( " /markov command sent to {} " , message . chat . id ( ) ) ,
Err ( _ ) = > warn! ( " /markov command sent failed to {} " , message . chat . id ( ) ) ,
}
//api.send(message.chat.text("Text to message chat")).await?;
//api.send(message.from.text("Private text")).await?;
Ok ( ( ) )
2020-12-11 15:53:14 +03:00
}
2020-12-31 01:42:36 +03:00
async fn run_mystem (
& self ,
api : Api ,
message : Message ,
mystem : & mut MyStem ,
) -> Result < ( ) , Error > {
unimplemented! ( )
2020-12-11 15:53:14 +03:00
}
}
2020-12-29 17:01:56 +03:00
2020-12-31 01:42:36 +03:00
#[ async_trait ]
impl Execute for Omedeto {
async fn run ( & self , api : Api , message : Message ) -> Result < ( ) , Error > {
unimplemented! ( )
}
2020-12-29 17:01:56 +03:00
2020-12-31 01:42:36 +03:00
async fn run_mystem (
& self ,
api : Api ,
message : Message ,
mystem : & mut MyStem ,
) -> Result < ( ) , Error > {
let all_msg = db ::get_messages_user_all ( & message ) . await ? ;
let re = Regex ::new ( r "^[яЯ] [а -яА-Я]+(-[а -яА-Я]+(_[а -яА-Я]+)*)*" ) . unwrap ( ) ;
let mut nouns : Vec < String > = all_msg
. clone ( )
. into_iter ( )
. filter ( | m | re . is_match ( m ) )
. map ( | m | m . split ( ' ' ) . map ( | s | s . to_string ( ) ) . collect ::< Vec < String > > ( ) [ 1 ] . clone ( ) )
. filter ( | m | {
let stem = mystem . stemming ( m . clone ( ) ) . unwrap_or_default ( ) ;
if stem . is_empty ( ) {
false
} else if stem [ 0 ] . lex . is_empty ( ) {
false
} else {
match stem [ 0 ] . lex [ 0 ] . grammem . part_of_speech {
mystem ::PartOfSpeech ::Noun = > stem [ 0 ] . lex [ 0 ]
. grammem
. facts
. contains ( & mystem ::Fact ::Case ( Nominative ) ) ,
_ = > false ,
}
2020-12-30 09:24:15 +03:00
}
2020-12-31 01:42:36 +03:00
} )
. map ( | w | w . replace ( | z | z = = '.' | | z = = ',' , " " ) )
. collect ( ) ;
nouns . sort ( ) ;
nouns . dedup ( ) ;
nouns . shuffle ( & mut rand ::thread_rng ( ) ) ;
//debug!("Found {} nouns. {:#?}", nouns.len(), nouns);
2020-12-29 17:01:56 +03:00
2020-12-31 01:42:36 +03:00
let mut verbs_p : Vec < String > = all_msg
. clone ( )
. into_iter ( )
. filter ( | m | re . is_match ( m ) )
. map ( | m | m . split ( ' ' ) . map ( | s | s . to_string ( ) ) . collect ::< Vec < String > > ( ) [ 1 ] . clone ( ) )
. filter ( | m | {
let stem = mystem . stemming ( m . clone ( ) ) . unwrap_or_default ( ) ;
if stem . is_empty ( ) {
false
} else if stem [ 0 ] . lex . is_empty ( ) {
false
} else {
match stem [ 0 ] . lex [ 0 ] . grammem . part_of_speech {
mystem ::PartOfSpeech ::Verb = > stem [ 0 ] . lex [ 0 ]
2020-12-30 14:30:53 +03:00
. grammem
. facts
2020-12-31 01:42:36 +03:00
. contains ( & mystem ::Fact ::Tense ( Past ) ) ,
_ = > false ,
2020-12-30 14:30:53 +03:00
}
2020-12-30 09:24:15 +03:00
}
2020-12-31 01:42:36 +03:00
} )
. map ( | w | w . replace ( | z | z = = '.' | | z = = ',' , " " ) )
. collect ( ) ;
verbs_p . sort ( ) ;
verbs_p . dedup ( ) ;
verbs_p . shuffle ( & mut rand ::thread_rng ( ) ) ;
//debug!("Found {} past verbs. {:#?}", verbs_p.len(), verbs_p);
2020-12-29 17:01:56 +03:00
2020-12-31 01:42:36 +03:00
let mut verbs_i : Vec < String > = all_msg
2020-12-30 15:12:17 +03:00
. clone ( )
. into_iter ( )
. filter ( | m | re . is_match ( m ) )
. map ( | m | m . split ( ' ' ) . map ( | s | s . to_string ( ) ) . collect ::< Vec < String > > ( ) [ 1 ] . clone ( ) )
2020-12-31 01:42:36 +03:00
. filter ( | m | {
2020-12-30 15:12:17 +03:00
let stem = mystem . stemming ( m . clone ( ) ) . unwrap_or_default ( ) ;
if stem . is_empty ( ) {
2020-12-31 01:42:36 +03:00
false
2020-12-30 15:12:17 +03:00
} else if stem [ 0 ] . lex . is_empty ( ) {
2020-12-31 01:42:36 +03:00
false
2020-12-30 15:12:17 +03:00
} else {
match stem [ 0 ] . lex [ 0 ] . grammem . part_of_speech {
mystem ::PartOfSpeech ::Verb = > {
2020-12-31 01:42:36 +03:00
stem [ 0 ] . lex [ 0 ]
2020-12-30 15:12:17 +03:00
. grammem
. facts
2020-12-31 01:42:36 +03:00
. contains ( & mystem ::Fact ::Tense ( Inpresent ) )
& & stem [ 0 ] . lex [ 0 ]
. grammem
. facts
. contains ( & mystem ::Fact ::Person ( First ) )
2020-12-30 15:12:17 +03:00
}
2020-12-31 01:42:36 +03:00
_ = > false ,
2020-12-30 15:12:17 +03:00
}
}
2020-12-30 15:25:33 +03:00
} )
2020-12-31 01:42:36 +03:00
. map ( | w | w . replace ( | z | z = = '.' | | z = = ',' , " " ) )
. collect ( ) ;
verbs_i . sort ( ) ;
verbs_i . dedup ( ) ;
verbs_i . shuffle ( & mut rand ::thread_rng ( ) ) ;
//debug!("Found {} inpresent verbs. {:#?}", verbs_i.len(), verbs_i);
if nouns . is_empty ( ) {
nouns . push ( message . from . first_name . to_string ( ) ) ;
2020-12-29 17:01:56 +03:00
}
2020-12-31 01:42:36 +03:00
let start : Vec < String > = vec! [
" С новым годом" . into ( ) ,
" С НГ тебя" . into ( ) ,
" Поздравляю " . into ( ) ,
" Поздравляю с НГ " . into ( ) ,
] ;
let placeholders : Vec < String > = vec! [
" [ДАННЫЕ УДАЛЕНЫ] " . into ( ) ,
" [С Е К Р Е Т Н О ] " . into ( ) ,
" [Н Е Т ДАННЫХ] " . into ( ) ,
" [ОШИБКА ДОСТУПА] " . into ( ) ,
] ;
//debug!("Nouns: {:#?}", nouns);
//debug!("Verbs: {:#?}", verbs);
2020-12-29 17:01:56 +03:00
2020-12-31 01:42:36 +03:00
let fem = {
let mut fm = 0 ;
let mut mu = 0 ;
all_msg
. clone ( )
. into_iter ( )
. filter ( | m | re . is_match ( m ) )
. map ( | m | m . split ( ' ' ) . map ( | s | s . to_string ( ) ) . collect ::< Vec < String > > ( ) [ 1 ] . clone ( ) )
. map ( | m | {
let stem = mystem . stemming ( m . clone ( ) ) . unwrap_or_default ( ) ;
if stem . is_empty ( ) {
( )
} else if stem [ 0 ] . lex . is_empty ( ) {
( )
} else {
match stem [ 0 ] . lex [ 0 ] . grammem . part_of_speech {
mystem ::PartOfSpeech ::Verb = > {
match stem [ 0 ] . lex [ 0 ]
. grammem
. facts
. contains ( & mystem ::Fact ::Tense ( Past ) )
{
true = > {
if stem [ 0 ] . lex [ 0 ]
. grammem
. facts
. contains ( & mystem ::Fact ::Gender ( Feminine ) )
{
fm = fm + 1 ;
} else {
mu = mu + 1 ;
}
}
false = > ( ) ,
}
}
_ = > ( ) ,
}
}
} )
. collect ::< ( ) > ( ) ;
//debug!("fm - {}, mu - {}", fm, mu);
if fm > = mu {
true
} else {
false
}
} ;
//debug!("Is Feminine - {}", fem);
let result = format! (
" {} {} известн{} как {}, {}, а так же конечно {}. В прошедшем году ты часто давал{} нам знать, что ты {}, {} и {}. Нередко ты говорил{} я {}, я {} или даже я {}. =* " ,
start . choose ( & mut rand ::thread_rng ( ) ) . unwrap ( ) ,
message . from . first_name . to_string ( ) ,
{ if fem { " ая " } else { " ый " } } ,
nouns . pop ( ) . unwrap_or ( placeholders . choose ( & mut rand ::thread_rng ( ) ) . unwrap ( ) . to_string ( ) ) ,
nouns . pop ( ) . unwrap_or ( placeholders . choose ( & mut rand ::thread_rng ( ) ) . unwrap ( ) . to_string ( ) ) ,
nouns . pop ( ) . unwrap_or ( placeholders . choose ( & mut rand ::thread_rng ( ) ) . unwrap ( ) . to_string ( ) ) ,
{ if fem { " а " } else { " " } } ,
verbs_p . pop ( ) . unwrap_or ( placeholders . choose ( & mut rand ::thread_rng ( ) ) . unwrap ( ) . to_string ( ) ) ,
verbs_p . pop ( ) . unwrap_or ( placeholders . choose ( & mut rand ::thread_rng ( ) ) . unwrap ( ) . to_string ( ) ) ,
verbs_p . pop ( ) . unwrap_or ( placeholders . choose ( & mut rand ::thread_rng ( ) ) . unwrap ( ) . to_string ( ) ) ,
{ if fem { " а " } else { " " } } ,
verbs_i . pop ( ) . unwrap_or ( placeholders . choose ( & mut rand ::thread_rng ( ) ) . unwrap ( ) . to_string ( ) ) ,
verbs_i . pop ( ) . unwrap_or ( placeholders . choose ( & mut rand ::thread_rng ( ) ) . unwrap ( ) . to_string ( ) ) ,
verbs_i . pop ( ) . unwrap_or ( placeholders . choose ( & mut rand ::thread_rng ( ) ) . unwrap ( ) . to_string ( ) ) ,
) ;
//debug!("{:?}", result);
match api
. send (
message
. text_reply ( result . trim ( ) )
. parse_mode ( ParseMode ::Html ) ,
)
. await
{
Ok ( _ ) = > debug! ( " /omedeto command sent to {} " , message . chat . id ( ) ) ,
Err ( _ ) = > warn! ( " /omedeto command sent failed to {} " , message . chat . id ( ) ) ,
}
Ok ( ( ) )
2020-12-29 17:09:49 +03:00
}
2020-12-29 17:01:56 +03:00
}