clean history

This commit is contained in:
root 2026-03-18 01:23:25 +03:00
parent 1387ec35c6
commit a45809ff84
8 changed files with 570 additions and 0 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
node_modules/
.env
.env.*
dist/

View File

@ -1,2 +1,10 @@
# sergay
<<<<<<< HEAD
=======
Этот репозиторий создан для унижения Сергея Пидоровича и анального удовлетворения.
Сергей сосал член
This repository was created to humiliate Sergey Pidorovich and anal satisfaction.
Sergay suck dick
>>>>>>> 8bf51d5 (clean history)

4
code/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
node_modules/
.env
.env.*
dist/

13
code/README.md Normal file
View File

@ -0,0 +1,13 @@
# sergay
Здесь будет основной код для унижения,
необходимые pip модули:
```
python-telegram-bot
python-dotenv
```
Here will be the basic code for humiliating,
the necessary pip modules:
```
python-telegram-bot
python-dotenv
```

43
code/add_json.py Normal file
View File

@ -0,0 +1,43 @@
import json
from pathlib import Path
JSON_FILE = "sergay.json"
def add_phrase(text: str):
path = Path(JSON_FILE)
if not path.exists():
print("Файл sergay.json не найден")
return
with path.open("r", encoding="utf-8") as f:
data = json.load(f)
if not isinstance(data, list):
print("JSON должен быть списком")
return
last_id = max(item["id"] for item in data)
new_id = last_id + 1
new_item = {
"id": new_id,
str(new_id): text
}
data.append(new_item)
with path.open("w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=4)
print(f"Добавлено: {new_item}")
if __name__ == "__main__":
phrase = input("Введите новую фразу: ").strip()
if phrase:
add_phrase(phrase)
else:
print("Фраза пустая")

18
code/gitup.sh Executable file
View File

@ -0,0 +1,18 @@
#!/usr/bin/env bash
set -a
source .env
set +a
cd ~/sergay || exit 1
git add .
if ! git diff --cached --quiet; then
git commit -m "update" || exit 1
else
echo "Нет новых изменений"
fi
git pull --rebase "http://usergit.duckdns.org/igor/sergay.git" main || exit 1
git push "http://igor:${GIT}@usergit.duckdns.org/igor/sergay.git"

262
code/sergay.json Normal file
View File

@ -0,0 +1,262 @@
[
{
"id": 1,
"1": "сын шлюхи"
},
{
"id": 2,
"2": "Пидорович"
},
{
"id": 3,
"3": "обосанный мудак"
},
{
"id": 4,
"4": "дрочит в коморке"
},
{
"id": 5,
"5": "свин мертвой шлюхи"
},
{
"id": 6,
"6": "любит когда ему садятся на лицо"
},
{
"id": 7,
"7": "гнида хаченская"
},
{
"id": 8,
"8": "зоофил"
},
{
"id": 9,
"9": "педофил"
},
{
"id": 10,
"10": "ебал прах своей матери"
},
{
"id": 11,
"11": "хуесос с грязной жопой"
},
{
"id": 12,
"12": "иноагент"
},
{
"id": 13,
"13": "снаряд в пушке"
},
{
"id": 14,
"14": "уже мертв"
},
{
"id": 15,
"15": "любит когда ему наступают на яйца"
},
{
"id": 16,
"16": "без члена"
},
{
"id": 17,
"17": "людоед"
},
{
"id": 18,
"18": "сосал член"
},
{
"id": 19,
"19": "имеет желтый член"
},
{
"id": 20,
"20": "не умеет ходить"
},
{
"id": 21,
"21": "пустил по кругу шуру"
},
{
"id": 22,
"22": "стриптезер без оброзавания"
},
{
"id": 23,
"23": "безмозглый пидор"
},
{
"id": 24,
"24": "999999999999999999 сосал и лизал"
},
{
"id": 25,
"25": "колличество оборотов его пропелера не исчесляется"
},
{
"id": 26,
"26": "я хз шо писать"
},
{
"id": 27,
"27": "петушара"
},
{
"id": 28,
"28": "спит у параши"
},
{
"id": 29,
"29": "спидозный"
},
{
"id": 30,
"30": "фембой"
},
{
"id": 31,
"31": "живет на нудистком пляже"
},
{
"id": 32,
"32": "живет в подвале"
},
{
"id": 33,
"33": "пидор со стажем в отлизывание яиц"
},
{
"id": 34,
"34": "увидел ребенка и повысил обороты перпелера"
},
{
"id": 35,
"35": "совал хуй в арбуз"
},
{
"id": 36,
"36": "терпилоид, но не позволит посылать себя нахуй"
},
{
"id": 37,
"37": "модная сиська"
},
{
"id": 38,
"38": "складочка"
},
{
"id": 39,
"39": "любит детскую порнографию духа"
},
{
"id": 40,
"40": "жидко пернул"
},
{
"id": 41,
"41": "ебакрыл"
},
{
"id": 42,
"42": "хуеглот глоп глоп"
},
{
"id": 43,
"43": "еврей"
},
{
"id": 44,
"44": "ебал собак, котов, попугаев, львов, тигров, обезьян, воробьев, хомяков, пантер, лис, кроликов, коз, баранов, ослов, лошадей, оленей"
},
{
"id": 45,
"45": "сосет и его ебали"
},
{
"id": 46,
"46": "объебаный наркошарик"
},
{
"id": 47,
"47": "вялый хуй"
},
{
"id": 48,
"48": "лох цветочный"
},
{
"id": 49,
"49": "украинец с гейскими наклонностями"
},
{
"id": 50,
"50": "обсасывает золотые я\b\b\b\b\b\bх\b"
},
{
"id": 51,
"51": "краник"
},
{
"id": 52,
"52": "нюхал яйца"
},
{
"id": 53,
"53": "фетишист"
},
{
"id": 54,
"54": "говорит гав гав"
},
{
"id": 55,
"55": "9\b лет как под наркозом хуйхуйхуй"
},
{
"id": 56,
"56": "очкастая пизда"
},
{
"id": 57,
"57": "не имеет прав он петух оалклкоал"
},
{
"id": 58,
"58": "зассаный банан"
},
{
"id": 59,
"59": "ZZZ ГОЙДА ПАТРИОТ ZZZ"
},
{
"id": 60,
"60": "варит меф"
},
{
"id": 61,
"61": "следит за тобой"
},
{
"id": 62,
"62": "сидит на дереве с биноклем"
},
{
"id": 63,
"63": "завел канал на пронхабе"
},
{
"id": 64,
"64": "четырехглазый"
},
{
"id": 65,
"65": "поставил водник для раскумара"
}
]

218
code/sergay.py Normal file
View File

@ -0,0 +1,218 @@
import json
import os
import random
import subprocess
from pathlib import Path
from dotenv import load_dotenv
from telegram import Update
from telegram.ext import (
ApplicationBuilder,
CommandHandler,
ContextTypes,
ConversationHandler,
MessageHandler,
filters,
)
PREFIX_WORD = "Сергей"
JSON_FILE = "sergay.json"
SERVICE_NAME = "sergay-bot"
WAITING_NEW_PHRASE = 1
def load_phrases(file_path: str) -> list[str]:
path = Path(file_path)
if not path.exists():
return []
with path.open("r", encoding="utf-8") as f:
data = json.load(f)
phrases = []
if isinstance(data, list):
for item in data:
if isinstance(item, dict):
item_id = item.get("id")
if isinstance(item_id, int):
value = item.get(str(item_id))
if isinstance(value, str) and value.strip():
phrases.append(value.strip())
else:
for value in item.values():
if isinstance(value, str) and value.strip():
phrases.append(value.strip())
elif isinstance(item, str) and item.strip():
phrases.append(item.strip())
return phrases
def load_raw_data(file_path: str) -> list:
path = Path(file_path)
if not path.exists():
return []
with path.open("r", encoding="utf-8") as f:
data = json.load(f)
if not isinstance(data, list):
raise ValueError("JSON должен содержать список")
return data
def save_new_phrase(file_path: str, phrase: str) -> None:
phrase = phrase.strip()
if not phrase:
raise ValueError("Пустую фразу добавлять нельзя")
data = load_raw_data(file_path)
existing_phrases = set()
max_id = 0
for item in data:
if isinstance(item, dict):
item_id = item.get("id")
if isinstance(item_id, int):
max_id = max(max_id, item_id)
value = item.get(str(item_id))
if isinstance(value, str):
existing_phrases.add(value.strip())
if phrase in existing_phrases:
raise ValueError("Такая фраза уже есть в базе")
new_id = max_id + 1
data.append({
"id": new_id,
str(new_id): phrase
})
path = Path(file_path)
with path.open("w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=4)
def restart_service() -> None:
subprocess.Popen(
["systemctl", "restart", SERVICE_NAME],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
start_new_session=True,
)
def run_gitup() -> tuple[bool, str]:
result = subprocess.run(
["bash", "gitup.sh"],
capture_output=True,
text=True,
)
output = (result.stdout or "").strip()
error = (result.stderr or "").strip()
if result.returncode == 0:
return True, output or "gitup выполнен"
return False, error or output or "Ошибка выполнения gitup"
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
text = (
"Вот список команд:\n\n"
"Получить фразу — /phrase\n"
"Добавить фразу — /new\n"
)
await update.message.reply_text(text)
async def phrase(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
try:
phrases = load_phrases(JSON_FILE)
if not phrases:
text = "Фразы пока не добавлены"
else:
phrase_text = random.choice(phrases)
text = f"{PREFIX_WORD} {phrase_text}".strip()
except Exception as e:
text = f"Ошибка: {e}"
await update.message.reply_text(text)
async def new_start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
await update.message.reply_text("Введите фразу:")
return WAITING_NEW_PHRASE
async def new_save(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
phrase_text = (update.message.text or "").strip()
if not phrase_text:
await update.message.reply_text("Фраза пустая. Введите фразу:")
return WAITING_NEW_PHRASE
try:
save_new_phrase(JSON_FILE, phrase_text)
await update.message.reply_text(f"Добавленно {PREFIX_WORD} {phrase_text}")
restart_service()
except Exception as e:
await update.message.reply_text(f"Ошибка: {e}")
return ConversationHandler.END
async def new_cancel(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
await update.message.reply_text("Отменено")
return ConversationHandler.END
async def gitup(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
await update.message.reply_text("Запускаю gitup...")
ok, output = run_gitup()
if len(output) > 3500:
output = output[:3500] + "\n\n...вывод обрезан"
if ok:
await update.message.reply_text(f"gitup выполнен\n\n{output}")
else:
await update.message.reply_text(f"Ошибка gitup\n\n{output}")
def main() -> None:
load_dotenv()
token = os.getenv("TG_TOKEN")
if not token:
raise ValueError("Не найден TG_TOKEN в .env")
app = ApplicationBuilder().token(token).build()
new_handler = ConversationHandler(
entry_points=[CommandHandler("new", new_start)],
states={
WAITING_NEW_PHRASE: [
MessageHandler(filters.TEXT & ~filters.COMMAND, new_save)
],
},
fallbacks=[CommandHandler("cancel", new_cancel)],
)
app.add_handler(CommandHandler("start", start))
app.add_handler(CommandHandler("phrase", phrase))
app.add_handler(CommandHandler("gitup", gitup))
app.add_handler(new_handler)
app.run_polling()
if __name__ == "__main__":
main()