Nahrát soubory do „telegram_bot“
This commit is contained in:
parent
6d5cd85408
commit
b467759c09
1
telegram_bot/.env
Normal file
1
telegram_bot/.env
Normal file
@ -0,0 +1 @@
|
|||||||
|
TOKEN=7293191565:AAF70PTx9QgkIvt3BDQGFY64p-ngiaPLAMA
|
12
telegram_bot/Dockerfile
Normal file
12
telegram_bot/Dockerfile
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
FROM python:3.10
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY requirements.txt .
|
||||||
|
RUN pip install --no-cache-dir -r requirements.txt
|
||||||
|
|
||||||
|
COPY . /app
|
||||||
|
COPY static/ ./static/
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
CMD ["python", "bot.py"]
|
97
telegram_bot/bot.py
Normal file
97
telegram_bot/bot.py
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
import os
|
||||||
|
import torch
|
||||||
|
import logging
|
||||||
|
from transformers import AutoModelForSequenceClassification, AutoTokenizer
|
||||||
|
from telegram import Update
|
||||||
|
from telegram.ext import Application, MessageHandler, filters, CommandHandler, CallbackContext
|
||||||
|
from dotenv import load_dotenv
|
||||||
|
import mysql.connector
|
||||||
|
|
||||||
|
|
||||||
|
# Загрузка переменных окружения из .env
|
||||||
|
load_dotenv()
|
||||||
|
TOKEN = os.getenv("TOKEN")
|
||||||
|
|
||||||
|
# Путь к модели
|
||||||
|
MODEL_PATH = "./hate_speech_model/final_model"
|
||||||
|
|
||||||
|
db_config = {
|
||||||
|
"host": "mysql",
|
||||||
|
"user": "root",
|
||||||
|
"password": "0674998280tanya",
|
||||||
|
"database": "telegram_bot"
|
||||||
|
}
|
||||||
|
|
||||||
|
def save_violator(username, message):
|
||||||
|
"""Сохраняет нарушителя в базу данных"""
|
||||||
|
try:
|
||||||
|
conn = mysql.connector.connect(**db_config)
|
||||||
|
cursor = conn.cursor()
|
||||||
|
query = "INSERT INTO violators (username, message) VALUES (%s, %s)"
|
||||||
|
cursor.execute(query, (username, message))
|
||||||
|
conn.commit()
|
||||||
|
cursor.close()
|
||||||
|
conn.close()
|
||||||
|
except mysql.connector.Error as err:
|
||||||
|
logging.error(f"Ошибка MySQL: {err}")
|
||||||
|
|
||||||
|
|
||||||
|
# Настройка логирования
|
||||||
|
logging.basicConfig(
|
||||||
|
format="%(asctime)s - %(levelname)s - %(message)s",
|
||||||
|
level=logging.INFO,
|
||||||
|
handlers=[
|
||||||
|
logging.FileHandler("log.txt"),
|
||||||
|
logging.StreamHandler()
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
# Загрузка модели и токенизатора
|
||||||
|
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
||||||
|
tokenizer = AutoTokenizer.from_pretrained(MODEL_PATH)
|
||||||
|
model = AutoModelForSequenceClassification.from_pretrained(MODEL_PATH).to(device)
|
||||||
|
|
||||||
|
def classify_text(text):
|
||||||
|
"""Функция для классификации текста"""
|
||||||
|
model.eval()
|
||||||
|
inputs = tokenizer(text, return_tensors="pt", truncation=True, padding="max_length", max_length=128).to(device)
|
||||||
|
|
||||||
|
with torch.no_grad():
|
||||||
|
outputs = model(**inputs)
|
||||||
|
|
||||||
|
logits = outputs.logits
|
||||||
|
pred = torch.argmax(logits, dim=-1).item()
|
||||||
|
|
||||||
|
return "🛑 Nenávistná reč" if pred == 1 else "✅ OK"
|
||||||
|
|
||||||
|
async def check_message(update: Update, context: CallbackContext):
|
||||||
|
"""Проверяет сообщения в чате и реагирует на токсичные сообщения"""
|
||||||
|
message_text = update.message.text
|
||||||
|
result = classify_text(message_text)
|
||||||
|
|
||||||
|
if result == "🛑 Nenávistná reč":
|
||||||
|
username = update.message.from_user.username or "unknown"
|
||||||
|
await update.message.reply_text("⚠️ Upozornenie! Dodržiavajte kultúru komunikácie.")
|
||||||
|
await update.message.delete() # Автоматическое удаление токсичных сообщений
|
||||||
|
|
||||||
|
# Логирование токсичного сообщения
|
||||||
|
logging.warning(f"Toxická správa od {update.message.from_user.username}: {message_text}")
|
||||||
|
save_violator(username, message_text)
|
||||||
|
|
||||||
|
async def start(update: Update, context: CallbackContext):
|
||||||
|
"""Отправляет приветственное сообщение при запуске бота"""
|
||||||
|
await update.message.reply_text("Ahoj! Sledujem kultúru komunikácie v chate!")
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""Запуск бота"""
|
||||||
|
app = Application.builder().token(TOKEN).build()
|
||||||
|
|
||||||
|
# Добавление обработчиков команд и сообщений
|
||||||
|
app.add_handler(CommandHandler("start", start))
|
||||||
|
app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, check_message))
|
||||||
|
|
||||||
|
# Запуск бота
|
||||||
|
app.run_polling()
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
24
telegram_bot/deployment.yaml
Normal file
24
telegram_bot/deployment.yaml
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: bot-deployment
|
||||||
|
namespace: botspace
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: bot
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: bot
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: hate-speech-bot
|
||||||
|
image: tetianamohorian/hate-speech-bot:latest
|
||||||
|
env:
|
||||||
|
- name: TOKEN
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: bot-secret
|
||||||
|
key: TOKEN
|
35
telegram_bot/flask-web.yaml
Normal file
35
telegram_bot/flask-web.yaml
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: flask-web
|
||||||
|
namespace: botspace
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: flask-web
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: flask-web
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: flask-container
|
||||||
|
image: tetianamohorian/hate-speech-bot:latest
|
||||||
|
command: ["python"]
|
||||||
|
args: ["web_app.py"]
|
||||||
|
ports:
|
||||||
|
- containerPort: 5000
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: flask-service
|
||||||
|
namespace: botspace
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: flask-web
|
||||||
|
ports:
|
||||||
|
- port: 5000
|
||||||
|
targetPort: 5000
|
||||||
|
protocol: TCP
|
2063
telegram_bot/log.txt
Normal file
2063
telegram_bot/log.txt
Normal file
File diff suppressed because it is too large
Load Diff
12
telegram_bot/prepare-app.sh
Normal file
12
telegram_bot/prepare-app.sh
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
|
||||||
|
# Zostavenie Docker obrazu
|
||||||
|
|
||||||
|
docker build -t tetianamohorian/hate-speech-bot:latest .
|
||||||
|
|
||||||
|
|
||||||
|
# Push obrazu
|
||||||
|
docker push tetianamohorian/hate-speech-bot:latest
|
||||||
|
|
||||||
|
|
6
telegram_bot/requirements.txt
Normal file
6
telegram_bot/requirements.txt
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
python-telegram-bot==20.3
|
||||||
|
transformers
|
||||||
|
torch
|
||||||
|
python-dotenv
|
||||||
|
mysql-connector-python
|
||||||
|
flask
|
11
telegram_bot/service.yaml
Normal file
11
telegram_bot/service.yaml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: mysql
|
||||||
|
namespace: botspace
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: mysql
|
||||||
|
ports:
|
||||||
|
- port: 3306
|
||||||
|
targetPort: 3306
|
13
telegram_bot/start-app.sh
Normal file
13
telegram_bot/start-app.sh
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
kubectl create namespace botspace
|
||||||
|
kubectl create configmap init-sql --from-file=sql/init.sql -n botspace
|
||||||
|
kubectl create secret generic bot-secret --from-literal=TOKEN=7293191565:AAF70PTx9QgkIvt3BDQGFY64p-ngiaPLAMA -n botspace --dry-run=client -o yaml | kubectl apply -f -
|
||||||
|
|
||||||
|
kubectl apply -f statefulset.yaml
|
||||||
|
kubectl apply -f service.yaml
|
||||||
|
kubectl apply -f deployment.yaml
|
||||||
|
kubectl apply -f flask-web.yaml
|
||||||
|
|
||||||
|
echo "🌐 Spúšťam port-forward na http://localhost:8888"
|
||||||
|
kubectl port-forward svc/flask-service 8888:5000 -n botspace
|
||||||
|
|
76
telegram_bot/statefulset.yaml
Normal file
76
telegram_bot/statefulset.yaml
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolume
|
||||||
|
metadata:
|
||||||
|
name: mysql-pv
|
||||||
|
namespace: botspace
|
||||||
|
spec:
|
||||||
|
capacity:
|
||||||
|
storage: 1Gi
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteOnce
|
||||||
|
hostPath:
|
||||||
|
path: "/mnt/data/mysql"
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolumeClaim
|
||||||
|
metadata:
|
||||||
|
name: mysql-pvc
|
||||||
|
namespace: botspace
|
||||||
|
spec:
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteOnce
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: 1Gi
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: StatefulSet
|
||||||
|
metadata:
|
||||||
|
name: mysql
|
||||||
|
namespace: botspace
|
||||||
|
spec:
|
||||||
|
serviceName: "mysql"
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: mysql
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: mysql
|
||||||
|
spec:
|
||||||
|
initContainers:
|
||||||
|
- name: init-sql-copy
|
||||||
|
image: busybox
|
||||||
|
command: ["sh", "-c", "cp /config/init.sql /tmp/init.sql"]
|
||||||
|
volumeMounts:
|
||||||
|
- name: init-sql
|
||||||
|
mountPath: /config
|
||||||
|
- name: tmp-sql
|
||||||
|
mountPath: /tmp
|
||||||
|
containers:
|
||||||
|
- name: mysql
|
||||||
|
image: mysql:8
|
||||||
|
env:
|
||||||
|
- name: MYSQL_ROOT_PASSWORD
|
||||||
|
value: "0674998280tanya"
|
||||||
|
ports:
|
||||||
|
- containerPort: 3306
|
||||||
|
volumeMounts:
|
||||||
|
- name: mysql-storage
|
||||||
|
mountPath: /var/lib/mysql
|
||||||
|
- name: tmp-sql
|
||||||
|
mountPath: /docker-entrypoint-initdb.d
|
||||||
|
volumes:
|
||||||
|
- name: mysql-storage
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: mysql-pvc
|
||||||
|
- name: init-sql
|
||||||
|
configMap:
|
||||||
|
name: init-sql
|
||||||
|
- name: tmp-sql
|
||||||
|
emptyDir: {}
|
3
telegram_bot/stop-app.sh
Normal file
3
telegram_bot/stop-app.sh
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
pkill -f "kubectl port-forward"
|
||||||
|
kubectl delete namespace botspace
|
141
telegram_bot/web_app.py
Normal file
141
telegram_bot/web_app.py
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
from flask import Flask, render_template_string, jsonify
|
||||||
|
import mysql.connector
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
|
||||||
|
DB_CONFIG = {
|
||||||
|
"host": "mysql",
|
||||||
|
"user": "root",
|
||||||
|
"password": "0674998280tanya",
|
||||||
|
"database": "telegram_bot"
|
||||||
|
}
|
||||||
|
|
||||||
|
TEMPLATE = """
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="sk">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Zoznam porušovateľov</title>
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
min-height: 100vh;
|
||||||
|
width: 100vw;
|
||||||
|
background: url('/static/bg.png') no-repeat center center/cover;
|
||||||
|
backdrop-filter: blur(8px);
|
||||||
|
animation: rotateBackground 60s linear infinite;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-family: 'Segoe UI', sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes rotateBackground {
|
||||||
|
0% { background-position: 20% 20%; }
|
||||||
|
50% { background-position: 60% 60%; }
|
||||||
|
100% { background-position: 20% 20%; }
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
background-color: rgba(0, 0, 0, 0.6);
|
||||||
|
padding: 2rem 3rem;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 0 30px rgba(0, 0, 0, 0.8);
|
||||||
|
text-align: center;
|
||||||
|
color: white;
|
||||||
|
max-height: 90vh;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
font-size: 2.5rem;
|
||||||
|
text-shadow: 2px 2px 10px black;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
margin: 0 auto;
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
|
||||||
|
th, td {
|
||||||
|
border: 1px solid #999;
|
||||||
|
padding: 1rem 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
background-color: rgba(255, 255, 255, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
td {
|
||||||
|
color: #eee;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<h1>Zoznam porušovateľov</h1>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr><th>Používateľ</th><th>Správa</th></tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="violators-body">
|
||||||
|
{% for row in data %}
|
||||||
|
<tr><td>{{ row[0] }}</td><td>{{ row[1] }}</td></tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
async function refreshTable() {
|
||||||
|
try {
|
||||||
|
const response = await fetch('/data');
|
||||||
|
const data = await response.json();
|
||||||
|
const tbody = document.getElementById('violators-body');
|
||||||
|
tbody.innerHTML = '';
|
||||||
|
|
||||||
|
data.forEach(row => {
|
||||||
|
const tr = document.createElement('tr');
|
||||||
|
tr.innerHTML = `<td>${row[0]}</td><td>${row[1]}</td>`;
|
||||||
|
tbody.appendChild(tr);
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Nepodarilo sa načítať dáta:", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setInterval(refreshTable, 1000); // každých 5 sekúnd
|
||||||
|
window.onload = refreshTable;
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
"""
|
||||||
|
|
||||||
|
@app.route('/')
|
||||||
|
def index():
|
||||||
|
conn = mysql.connector.connect(**DB_CONFIG)
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute("SELECT username, message FROM violators ORDER BY id DESC")
|
||||||
|
data = cursor.fetchall()
|
||||||
|
cursor.close()
|
||||||
|
conn.close()
|
||||||
|
return render_template_string(TEMPLATE, data=data)
|
||||||
|
|
||||||
|
@app.route('/data')
|
||||||
|
def data():
|
||||||
|
conn = mysql.connector.connect(**DB_CONFIG)
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute("SELECT username, message FROM violators ORDER BY id DESC")
|
||||||
|
data = cursor.fetchall()
|
||||||
|
cursor.close()
|
||||||
|
conn.close()
|
||||||
|
return jsonify(data)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
app.run(host='0.0.0.0', port=5000)
|
Loading…
Reference in New Issue
Block a user