]> git.localhorst.tv Git - alttp.git/blob - app/Models/ChatLog.php
fix number and space normalization
[alttp.git] / app / Models / ChatLog.php
1 <?php
2
3 namespace App\Models;
4
5 use App\TwitchBot\TokenizedMessage;
6 use Illuminate\Database\Eloquent\Factories\HasFactory;
7 use Illuminate\Database\Eloquent\Model;
8 use Illuminate\Support\Arr;
9 use Illuminate\Support\Str;
10 use LanguageDetection\Language;
11
12 class ChatLog extends Model {
13
14         use HasFactory;
15
16         public function channel() {
17                 return $this->belongsTo(Channel::class);
18         }
19
20         public function user() {
21                 return $this->belongsTo(User::class);
22         }
23
24         public function tokenize() {
25                 return TokenizedMessage::fromLog($this);
26         }
27
28         public function getTextWithoutEmotes() {
29                 $text = $this->text_content;
30                 if (isset($this->tags['emotes']) && !empty($this->tags['emotes'])) {
31                         $emotes = explode('/', $this->tags['emotes']);
32                         foreach ($emotes as $emote) {
33                                 $set = explode(':', $emote);
34                                 $positions = explode(',', $set[1]);
35                                 foreach ($positions as $position) {
36                                         $coords = explode('-', $position);
37                                         $text = mb_substr($text, 0, $coords[0]).str_repeat(' ', $coords[1] - $coords[0] + 1).mb_substr($text, $coords[1] + 1);
38                                 }
39                         }
40                 }
41                 return trim(preg_replace('/\s+/', ' ', $text));
42         }
43
44         public function evaluate() {
45                 $this->evaluateUser();
46                 $this->evaluateChannel();
47
48                 if (is_null($this->nick)) {
49                         $this->type = 'system';
50                         return;
51                 }
52                 if (in_array($this->nick, ['horstiebot', 'localhorsttv'])) {
53                         $this->type = 'self';
54                         return;
55                 }
56
57                 if ($this->command == 'PRIVMSG') {
58                         if (static::isKnownBot($this->nick)) {
59                                 $this->type = 'bot';
60                         } else if (substr($this->params[0], 0, 1) == '#') {
61                                 $this->type = 'chat';
62                         } else {
63                                 $this->type = 'dm';
64                         }
65                         $this->text_content = $this->params[1];
66                         $this->detectLanguage();
67                         $tokenized = $this->tokenize();
68                         if ($tokenized->isSpammy()) {
69                                 $this->banned = true;
70                         }
71                         $this->classification = $tokenized->classify();
72                         return;
73                 }
74
75                 throw new \Exception('unidentified message');
76         }
77
78         public static function isKnownBot($nick) {
79                 return in_array(strtolower($nick), [
80                         'a_n_i_v',
81                         'birrellthesquirrel',
82                         'funtoon',
83                         'nidbot2000',
84                         'nightbot',
85                         'pokemoncommunitygame',
86                         'sery_bot',
87                         'speedgaming',
88                         'starbase47',
89                         'streamelements',
90                         'wizebot',
91                         'zockerstuebchen',
92                 ]);
93         }
94
95         protected function evaluateUser() {
96         }
97
98         protected function evaluateChannel() {
99                 if (empty($this->params)) {
100                         return;
101                 }
102                 $cname = $this->params[0];
103                 if (substr($cname, 0, 1) != '#') {
104                         $cname = '#'.$cname;
105                 }
106                 $channel = Channel::firstWhere('twitch_chat', '=', $cname);
107                 if (!is_null($channel)) {
108                         $this->channel()->associate($channel);
109                         if (empty($this->twitch_category) && now()->sub(15, 'minute')->isBefore($this->created_at)) {
110                                 $this->twitch_category = $channel->twitch_category;
111                         }
112                 }
113         }
114
115         protected function detectLanguage() {
116                 $languages = ['de', 'en', 'es', 'fr'];
117                 if (!is_null($this->channel)) {
118                         $languages = array_values($this->channel->languages);
119                         if (!in_array('en', $languages)) {
120                                 $languages[] = 'en';
121                         }
122                 }
123                 $detector = (new Language($languages))->detect($this->getTextWithoutEmotes());
124                 $scores = $detector->close();
125                 $lang = strval($detector);
126                 //var_dump($scores, $lang, $this->text_content);
127                 if (!empty($lang) && $scores[$lang] > 0.4) {
128                         $this->detected_language = $lang;
129                 }
130         }
131
132         protected $casts = [
133                 'banned' => 'boolean',
134                 'params' => 'array',
135                 'tags' => 'array',
136                 'user_id' => 'string',
137         ];
138
139         protected $fillable = [
140                 'command',
141                 'nick',
142                 'params',
143                 'tags',
144         ];
145
146 }