Merge pull request #2 from kr0sh512/develop

Develop
This commit is contained in:
Dmitrii Gudov
2024-09-14 14:06:16 +03:00
committed by GitHub
11 changed files with 1191 additions and 628 deletions
+11 -2
View File
@@ -1,4 +1,13 @@
__pycache__
users.json users.json
schedule.json schedule.json
settings.json json/students.json
json/schedule_2sem.json
test_json
json_remake
script.py
nohup.out
config.yaml
old_files/
yaml_groups/*
!yaml_groups/202.yaml
+81 -2
View File
@@ -1,2 +1,81 @@
# Telegram-bot-schedule # Telegram Bot Schedule
Прямо сейчас бот работает здесь: https://t.me/vmk_schedule_bot This project is a Telegram bot designed to manage and display schedules. The bot can help users keep track of their daily activities, appointments, and events.
## Features
- View preloaded schedules
- Group schedules for better organization
- Receive reminders for upcoming events
- User-friendly commands and interface
## Installation
1. Clone the repository:
```sh
git clone https://github.com/yourusername/Telegram-bot-schedule.git
```
2. Navigate to the project directory:
```sh
cd Telegram-bot-schedule
```
3. Install the required dependencies:
```sh
pip install -r requirements.txt
```
## Usage
1. Create a new bot on Telegram and get the API token.
2. Set the API token in the environment variables or in a configuration file.
3. You need to create schedules files for groups.
4. Run the bot:
```sh
python bot.py
```
## Commands
- `/start` - используй, чтобы сменить номер группы.
- `/schedule` - используй, чтобы получить расписание на сегодня.
- `/random` - сделай очередь из людей
- `/info` - используй, чтобы узнать твои настройки бота
- `/pause` - используй, чтобы прекратить получать сообщения от бота
- `/thread` - используй в нужном чате канала, чтобы бот отправлял сообщения именно туда
- `/timeout` - настрой время, когда бот будет присылать тебе сообщение
- `/request` - используй, чтобы отправить разработчику какой-то запрос
- `/source` - Страница бота на Github
- `/restart` - перезапуск бота (admin only).
- `/update` - обновление schedule задач (admin only)
- `/stats` - получание статистики (admin only)
- `/json` - получить файл пользователей и расписания (admin only)
- `/info` <i>id_пользователя</i> - узнать настройки пользователя (admin only)
- `/spam` - сделать рассылку (admin only)
- `/pause_all` - приостановить бота для всех (каникулы/выходные) (admin only)
- `/stop` <i>id_пользователя</i> - приостановить отправку сообщений для пользователя (admin only)
## Contributing
Contributions are welcome! Please fork the repository and create a pull request with your changes.
## Contact
For any questions or suggestions, please open an issue or contact the project maintainer at [gudovdo@my.msu.ru].
## Target Audience
This bot is particularly useful for students to track their lessons and manage their academic schedules effectively.
## Limitations
- Cannot create or edit schedule entities directly
- Only works with preloaded schedules and groups
+14 -6
View File
@@ -1,12 +1,15 @@
import schedules as bot import schedules as bot
admin_id = '856850518' admin_id = "856850518"
def admin_command(func): def admin_command(func):
def wrapper(*args, **kwargs): def wrapper(*args, **kwargs):
message = args[0] message = args[0]
if str(message.from_user.id) != admin_id: if str(message.from_user.id) != admin_id:
bot.send_message(message.from_user.id, 'Команда доступна только администратору') bot.send_message(
message.from_user.id, "Команда доступна только администратору"
)
return return
func(*args, **kwargs) func(*args, **kwargs)
@@ -14,15 +17,20 @@ def admin_command(func):
return wrapper return wrapper
def is_admin(message): def is_admin(message):
if str(message.from_user.id) == admin_id and message.from_user.id == message.chat.id: if (
str(message.from_user.id) == admin_id
and message.from_user.id == message.chat.id
):
return True return True
return False return False
def send_admin_message(text): def send_admin_message(text):
bot.send_message(admin_id, '🛑 ' + text) bot.send_message(admin_id, "🛑 " + text)
def send_admin_document(file): def send_admin_document(file):
bot.send_document(admin_id, file, '🛑 Admin file') bot.send_document(admin_id, file, "🛑 Admin file")
+40
View File
@@ -0,0 +1,40 @@
import os
import json
import yaml
def convert_json_to_yaml(json_dir, yaml_dir):
# Iterate over all files in the directory
for filename in os.listdir(json_dir):
if filename.endswith(".json"):
json_path = os.path.join(json_dir, filename)
# Read JSON file
with open(json_path, "r", encoding="utf-8") as json_file:
data = json.load(json_file)
# Convert to YAML
yaml_data = yaml.dump(
data,
default_flow_style=None,
encoding="utf-8",
allow_unicode=True,
width=float("inf"),
sort_keys=False,
)
# Write YAML file
yaml_path = os.path.join(yaml_dir, filename.replace(".json", ".yaml"))
with open(yaml_path, "wb") as yaml_file:
yaml_file.write(yaml_data)
print("Conversion completed.")
if __name__ == "__main__":
json_dir = "json_remake"
yaml_dir = "yaml_groups"
convert_json_to_yaml(json_dir, yaml_dir)
pass
+201 -95
View File
@@ -1,29 +1,32 @@
#!/usr/bin/python3.3 #!/usr/bin/python3.3
import json, schedule import json, yaml, schedule
import schedules as bot import schedules as bot
from datetime import datetime from datetime import datetime
path_users = "json/users.json" # Нужный путь до json файлов path_users = "json/users.json" # Нужный путь до json файлов
path_schedule = "json/schedule.json" path_schedule = "yaml_groups/{}.yaml"
path_students = "json/students.json"
path_groups = "json/groups.json"
allow_update = True allow_update = True
def save_user(infos): def save_user(infos):
for i in range(len(infos)): for i in range(len(infos)):
if type(infos[i]) == type(None): if type(infos[i]) == type(None):
infos[i] = '' infos[i] = ""
infos[i] = str(infos[i]) infos[i] = str(infos[i])
infos = { infos = {
"id" : infos[0], "id": infos[0],
"first_name" : infos[1], "first_name": infos[1],
"last_name" : infos[2], "last_name": infos[2],
"username" : infos[3], "username": infos[3],
"group" : infos[4] "group": infos[4],
} }
data = {} data = {}
with open(path_users, 'r', encoding='utf-8') as json_file: with open(path_users, "r", encoding="utf-8") as json_file:
data = json.load(json_file) data = json.load(json_file)
data[infos["id"]] = { data[infos["id"]] = {
@@ -33,162 +36,265 @@ def save_user(infos):
"group": infos["group"], "group": infos["group"],
"timeout": "10", "timeout": "10",
"allow_message": "yes", "allow_message": "yes",
"thread": "General" "thread": "General",
} }
with open(path_users, 'w', encoding='utf-8') as json_file: with open(path_users, "w", encoding="utf-8") as json_file:
json.dump(data, json_file, ensure_ascii=False, indent=4) json.dump(data, json_file, ensure_ascii=False, indent=4)
create_schedule_tasks() create_schedule_tasks()
return return
def change_user_param(id, key, value): def change_user_param(id, key, value):
id = str(id) id = str(id)
data = {} data = {}
with open(path_users, 'r', encoding='utf-8') as json_file: with open(path_users, "r", encoding="utf-8") as json_file:
data = json.load(json_file) data = json.load(json_file)
data[id][key] = value data[id][key] = value
with open(path_users, 'w', encoding='utf-8') as json_file: with open(path_users, "w", encoding="utf-8") as json_file:
json.dump(data, json_file, ensure_ascii=False, indent=4) json.dump(data, json_file, ensure_ascii=False, indent=4)
create_schedule_tasks() create_schedule_tasks()
# bot.send_admin_message(
# "Изменения:\
# \n<i>user:</i> @{}\
# \n<i>id:</i> <code>{}</code>\
# \n<i>key:</i> <code>{}</code>\
# \n<i>value:</i> <code>{}</code>".format(
# data[id]["username"], id, key, value
# )
# )
return return
def parse_lesson(time, lesson):
text = ''
start, end = time.split("-")
if len(lesson["infos"].split('|')) == 2: def parse_lesson(lesson: dict[str, str]) -> str:
teacher = lesson["infos"].split('|')[0] text = ""
room = lesson["infos"].split('|')[1] start, end = lesson["begin"], lesson["end"]
text = '{}-{} | {}\
if not lesson["name"]:
return ""
if len(lesson["teacher.room"]) == 1:
text = "{}-{} | {}\
\n<b>{}</b>\ \n<b>{}</b>\
\n<i>{}</i>'.format(start, end, room, lesson["name"], teacher) \n<i>{}</i>".format(
elif len(lesson["infos"].split('|')) == 4: start,
infos = lesson["infos"].split('|') end,
text = '{}-{}\ lesson["teacher.room"][0]["r"],
\n<b>{}</b>\ lesson["name"],
\n({}) <i>{}</i>\ lesson["teacher.room"][0]["t"],
\n({}) <i>{}</i>'.format(start, end, lesson["name"], )
infos[1],
infos[0],
infos[3],
infos[2])
elif len(lesson["infos"].split('|')) == 1:
text = '{}-{}\
\n<b>{}</b>'.format(start, end, lesson["name"])
else: else:
print("что-то не так") text = "{}-{}\
print(lesson["name"]) \n<b>{}</b>".format(
start,
end,
lesson["name"],
)
for tr in lesson["teacher.room"]:
if not tr["t"] and not tr["r"]:
continue
text += "\n({}) <i>{}</i>".format(tr["r"], tr["t"])
return text return text
def create_schedule_tasks(manual=False): def create_schedule_tasks(manual=False):
global allow_update global allow_update
if not manual: if not manual:
bot.send_admin_message('Произошёл auto-update')
if not allow_update: if not allow_update:
return return
# bot.send_admin_message("Произошёл auto-update")
allow_update = True allow_update = True
schedule.clear() schedule.clear()
users = {} users = {}
schdl = {} schdl = {}
with open(path_users, 'r', encoding='utf-8') as json_file: with open(path_users, "r", encoding="utf-8") as json_file:
users = json.load(json_file) users = json.load(json_file)
with open(path_schedule, 'r', encoding='utf-8') as json_file:
schdl = json.load(json_file)
for id, params in users.items(): for id, params in users.items():
if params['allow_message'] != 'yes': if params["allow_message"] != "yes":
continue continue
group = params['group'] group = params["group"]
if group == 'other': if group == "other":
continue
timeout = params['timeout']
for day in schdl[group]:
for i, lesson in schdl[group][day].items():
if lesson["name"] == "": # Неправильный формат schedule
continue continue
start = i.split("-")[0] with open(path_schedule.format(group), "r", encoding="utf-8") as json_file:
text = parse_lesson(i, lesson) # schdl = json.load(json_file)["schedule"]
schdl = yaml.safe_load(json_file)["schedule"]
if text == '': for day in schdl:
for lesson in schdl[day]:
if not lesson["name"]: # Неправильный формат schedule
continue
start = lesson["begin"]
text = parse_lesson(lesson)
if not text:
continue continue
thread_id = params["thread"] thread_id = params["thread"]
delta = '00:' + params["timeout"] delta = "00:" + params["timeout"]
format = '%H:%M' format = "%H:%M"
start_task = datetime.strptime(start, format) - datetime.strptime(delta, format) start_task = datetime.strptime(start, format) - datetime.strptime(
tmp = '' delta, format
for i in str(start_task).split(':'): )
tmp += (('0' + i ) if len(i) < 2 else i) + ":" tmp = ""
for i in str(start_task).split(":"):
tmp += (("0" + i) if len(i) < 2 else i) + ":"
start_task = tmp[:-1] start_task = tmp[:-1]
if day == 'mon': if day == "mon":
schedule.every().monday.at(start_task).do(bot.send_message, id, text, thread_id) schedule.every().monday.at(start_task).do(
elif day == 'tue': bot.send_message, id, text, thread_id, lesson["parity"]
schedule.every().tuesday.at(start_task).do(bot.send_message, id, text, thread_id) )
elif day == 'wed': elif day == "tue":
schedule.every().wednesday.at(start_task).do(bot.send_message, id, text, thread_id) schedule.every().tuesday.at(start_task).do(
elif day == 'thu': bot.send_message, id, text, thread_id, lesson["parity"]
schedule.every().thursday.at(start_task).do(bot.send_message, id, text, thread_id) )
elif day == 'fri': elif day == "wed":
schedule.every().friday.at(start_task).do(bot.send_message, id, text, thread_id) schedule.every().wednesday.at(start_task).do(
elif day == 'sat': bot.send_message, id, text, thread_id, lesson["parity"]
schedule.every().saturday.at(start_task).do(bot.send_message, id, text, thread_id) )
elif day == "thu":
schedule.every().thursday.at(start_task).do(
bot.send_message, id, text, thread_id, lesson["parity"]
)
elif day == "fri":
schedule.every().friday.at(start_task).do(
bot.send_message, id, text, thread_id, lesson["parity"]
)
elif day == "sat":
schedule.every().saturday.at(start_task).do(
bot.send_message, id, text, thread_id, lesson["parity"]
)
return return
def groups_in_json():
schdl = {}
with open(path_schedule, 'r', encoding='utf-8') as json_file:
schdl = json.load(json_file)
return schdl.keys() def groups_in_json() -> list[str]:
groups = {}
with open(path_groups, "r", encoding="utf-8") as json_file:
groups = json.load(json_file)
def return_infos(id): return groups
def students_in_group(group) -> list[str]:
group = str(group)
data = {}
with open(path_users, "r", encoding="utf-8") as json_file:
data = json.load(json_file)
students = []
for i in data.keys():
if data[i]["group"] == group:
students.append(i)
return students
def students_in_json(id: str, key: str = "") -> list[str] | None:
id = str(id)
group = {}
with open(path_users, "r", encoding="utf-8") as json_file:
group = json.load(json_file)
group = group[id]["group"]
stud = {}
with open(path_students, "r", encoding="utf-8") as json_file:
stud = json.load(json_file)
stud = stud.get(group)
if stud == None:
return None
if key == "":
return list(stud.keys())
return stud[key]
def return_infos(id) -> dict[str, str] | None:
id = str(id) id = str(id)
data = {} data = {}
with open(path_users, 'r', encoding='utf-8') as json_file: with open(path_users, "r", encoding="utf-8") as json_file:
data = json.load(json_file) data = json.load(json_file)
data = data[id] data = data.get(id)
return data return data
def pause_bot(): def pause_bot():
schedule.clear()
global allow_update global allow_update
if allow_update:
schedule.clear()
allow_update = False allow_update = False
bot.send_admin_message("Бот больше не отправляет расписание")
else:
create_schedule_tasks(True)
allow_update = True
bot.send_admin_message("Бот возобновил рассылку!")
return return
def get_schedule(id, day):
id = str(id)
if day == 'sun':
day = 'mon'
days = ['mon', 'tue', 'wed', 'thu', 'fri', 'sat']
russian_days = ['понедельник', 'вторник', 'среду', 'четверг', 'пятницу', 'субботу']
text = '<u>Расписание на {}</u>:\n\n'.format(russian_days[days.index(day)]) def get_schedule(id: str, day: str) -> str:
id = str(id)
if day == "sun":
day = "mon"
days = ["mon", "tue", "wed", "thu", "fri", "sat"]
russian_days = ["понедельник", "вторник", "среду", "четверг", "пятницу", "субботу"]
text = "<u>Расписание на {}</u>:\n\n".format(russian_days[days.index(day)])
schdl_today = {} schdl_today = {}
with open(path_schedule, 'r', encoding='utf-8') as schedule_file:
group = ''
with open(path_users, 'r', encoding='utf-8') as user_file:
group = json.load(user_file)[id]['group']
if (group == 'other'): group = ""
return 'У тебя не выбрана группа для рассылки сообщений' with open(path_users, "r", encoding="utf-8") as user_file:
group = json.load(user_file)[id]["group"]
if group == "other":
return "У тебя не выбрана группа для рассылки сообщений"
try: try:
schdl_today = json.load(schedule_file)[group][day] with open(path_schedule.format(group), "r", encoding="utf-8") as schedule_file:
try:
# schdl_today = json.load(schedule_file)["schedule"][day]
schdl_today = yaml.safe_load(schedule_file)["schedule"][day]
except: except:
return 'Расписания твоей группы на {} нет'.format(russian_days[days.index(day)]) return "Расписания твоей группы на {} нет".format(
russian_days[days.index(day)]
)
for i, lesson in schdl_today.items(): for lesson in schdl_today:
text += '' + parse_lesson(i, lesson) + '\n\n' str_lesson = parse_lesson(lesson)
if str_lesson:
text += "" + str_lesson + "\n\n"
except:
return "Расписания твоей группы нет"
return text return text
if __name__ == "__main__":
print(groups_in_json())
pass
+46
View File
@@ -0,0 +1,46 @@
[
"101",
"102",
"103",
"104",
"105",
"106",
"107",
"108",
"109",
"110",
"111",
"112",
"113",
"114",
"115",
"116",
"117",
"118",
"119",
"120",
"141",
"142",
"201",
"202",
"203",
"204",
"205",
"206",
"219",
"207",
"208",
"209",
"210",
"211",
"212",
"213",
"214",
"215",
"216",
"217",
"218",
"220",
"241",
"242"
]
-282
View File
@@ -1,282 +0,0 @@
{
"102": {
"mon": {
"8:45-10:20": {
"name": "Алгоритмы и алгоритмические языки",
"infos": "Белеванцев Андрей Андреевич|П-6"
},
"10:30-12:05": {
"name": "Английский язык",
"infos": "Шубина Юлия Витальевна|73|Бим Мария Моисеевна|735"
},
"12:50-14:25": {
"name": "Математический анализ",
"infos": "Лапонин Владислав Сергеевич|606"
},
"15:00-16:30": {
"name": "Физическая культура",
"infos": ""
},
"16:45-18:15": {
"name": "Консультация. Алгебра и геометрия",
"infos": "Руднев Сергей Геннадьевич|???"
}
},
"tue": {
"10:30-12:05": {
"name": "Алгебра и геометрия",
"infos": "Тыртышников Евгений Евгеньевич|П-6"
},
"12:50-14:25": {
"name": "Математический анализ",
"infos": "Садовничая Инна Викторовна|П-6"
},
"14:35-16:10": {
"name": "Алгебра и геометрия",
"infos": "Руднев Сергей Геннадьевич|682"
},
"16:20-17:55": {
"name": "Практикум на ЭВМ",
"infos": "Цыбров Евгений Германович|371|Кулагин Алексей Владимирович|МЗ-0"
}
},
"wed": {
"8:45-10:20": {
"name": "Алгоритмы и алгоритмические языки",
"infos": "Белеванцев Андрей Андреевич|П-6"
},
"10:30-12:05": {
"name": "Математический анализ",
"infos": "Лапонин Владислав Сергеевич|606"
},
"12:50-14:25": {
"name": "Английский язык",
"infos": "Шубина Юлия Витальевна|735|Бим Мария Моисеевна|71"
}
},
"thu": {
"8:45-10:20": {
"name": "Алгебра и геометрия",
"infos": "Тыртышников Евгений Евгеньевич|П-6"
},
"10:30-12:05": {
"name": "Математический анализ",
"infos": "Садовничая Инна Викторовна|П-6"
},
"12:50-14:25": {
"name": "История России",
"infos": "Чубыкин Игорь Валерьевич|523"
},
"14:35-16:10": {
"name": "Алгебра и геометрия",
"infos": "Руднев Сергей Геннадьевич|606"
},
"16:20-17:55": {
"name": "История России",
"infos": "Чубыкин Игорь Валерьевич|П-6"
}
},
"fri": {
"9:00-10:30": {
"name": "Физическая культура",
"infos": ""
},
"10:40-12:15": {
"name": "Безопасность жизнедеятельности",
"infos": "Сладкова Наталья Валерьевна|609"
},
"12:50-14:25": {
"name": "Практикум на ЭВМ",
"infos": "Цыбров Евгений Германович|371|Кулагин Алексей Владимирович|МЗ-0"
}
}
},
"103": {
"mon": {
"8:45-10:20": {
"name": "Алгоритмы и алгоритмические языки",
"infos": "Белеванцев Андрей Андреевич|П-6"
},
"10:30-12:05": {
"name": "Математический анализ",
"infos": "Зайцева Наталья Владимировна|71"
},
"12:50-14:25": {
"name": "Практикум на ЭВМ",
"infos": "Кузьменкова Евгения Анатольевна|731|Малышев Никита Евгеньевич|778"
},
"15:00-16:30": {
"name": "Физическая культура",
"infos": ""
}
},
"tue": {
"8:45-10:20": {
"name": "Консультация. Алгебра и геометрия",
"infos": "Будак Александр Борисович|612"
},
"10:30-12:05": {
"name": "Алгебра и геометрия",
"infos": "Тыртышников Евгений Евгеньевич|П-6"
},
"12:50-14:25": {
"name": "Математический анализ",
"infos": "Садовничая Инна Викторовна|П-6"
},
"14:35-16:10": {
"name": "Английский язык",
"infos": "Плиева Сима Ивановна|783|Дзампова Татьяна Борисовна|736"
},
"16:20-17:55": {
"name": "Английский язык",
"infos": "Дзампова Татьяна Борисовна|736"
}
},
"wed": {
"8:45-10:20": {
"name": "Алгоритмы и алгоритмические языки",
"infos": "Белеванцев Андрей Андреевич|П-6"
},
"10:30-12:05": {
"name": "Математический анализ",
"infos": "Зайцева Наталья Владимировна|72"
},
"12:50-14:25": {
"name": "Алгебра и геометрия",
"infos": "Будак Александр Борисович|605"
}
},
"thu": {
"8:45-10:20": {
"name": "Алгебра и геометрия",
"infos": "Тыртышников Евгений Евгеньевич|П-6"
},
"10:30-12:05": {
"name": "Математический анализ",
"infos": "Садовничая Инна Викторовна|П-6"
},
"12:50-14:25": {
"name": "Алгебра и геометрия",
"infos": "Будак Александр Борисович|605"
},
"14:35-16:10": {
"name": "Английский язык",
"infos": "Плиева Сима Ивановна|783"
},
"16:20-17:55": {
"name": "История России",
"infos": "Чубыкин Игорь Валерьевич|П-6"
}
},
"fri": {
"9:00-10:30": {
"name": "Физическая культура",
"infos": ""
},
"10:40-12:15": {
"name": "Безопасность жизнедеятельности",
"infos": "Гимишли Николай Федосеевич|614"
},
"12:50-14:25": {
"name": "Практикум на ЭВМ",
"infos": "Кузьменкова Евгения Анатольевна|248|Малышев Никита Евгеньевич|780"
},
"14:35-16:10": {
"name": "История России",
"infos": "Чубыкин Игорь Валерьевич|523"
}
}
},
"105": {
"mon": {
"8:45-10:20": {
"name": "Алгоритмы и алгоритмические языки",
"infos": "Белеванцев Андрей Андреевич|П-6"
},
"10:30-12:05": {
"name": "Математический анализ",
"infos": "Никитин Алексей Антонович|72"
},
"12:15-13:40": {
"name": "Алгебра и геометрия",
"infos": "Лебедева Ольга Сергеевна|508|Замарашкин Николай Леонидович|508"
},
"15:00-16:30": {
"name": "Физическая культура",
"infos": ""
}
},
"tue": {
"10:30-12:05": {
"name": "Алгебра и геометрия",
"infos": "Тыртышников Евгений Евгеньевич|П-6"
},
"12:50-14:25": {
"name": "Математический анализ",
"infos": "Садовничая Инна Викторовна|П-6"
},
"14:35-16:10": {
"name": "Английский язык",
"infos": "Лаптинова Анастасия Ильинична|73|Кашелкина Ольга Александровна|790"
},
"16:20-17:55": {
"name": "Практикум на ЭВМ",
"infos": "Русол Андрей Владимирович|МЗ-4|Гуляев Анатолий Викторович|574"
}
},
"wed": {
"8:45-10:20": {
"name": "Алгоритмы и алгоритмические языки",
"infos": "Белеванцев Андрей Андреевич|П-6"
},
"10:30-12:05": {
"name": "Математический анализ",
"infos": "Никитин Алексей Антонович|778"
},
"12:50-14:25": {
"name": "Алгебра и геометрия",
"infos": "Лебедева Ольга Сергеевна|506|Замарашкин Николай Леонидович|506"
}
},
"thu": {
"8:45-10:20": {
"name": "Алгебра и геометрия",
"infos": "Тыртышников Евгений Евгеньевич|П-6"
},
"10:30-12:05": {
"name": "Математический анализ",
"infos": "Садовничая Инна Викторовна|П-6"
},
"12:50-14:25": {
"name": "История России",
"infos": "Чубыкин Игорь Валерьевич|523"
},
"14:35-16:10": {
"name": "Английский язык",
"infos": "Лаптинова Анастасия Ильинична|71|Кашелкина Ольга Александровна|736"
},
"16:20-17:55": {
"name": "История России",
"infos": "Чубыкин Игорь Валерьевич|П-6"
}
},
"fri": {
"9:00-10:30": {
"name": "Физическая культура",
"infos": ""
},
"10:40-12:15": {
"name": "Консультация. Математический анализ",
"infos": "Никитин Алексей Антонович|72"
},
"12:50-14:25": {
"name": "Практикум на ЭВМ",
"infos": "Русол Андрей Владимирович|МЗ-4|Гуляев Анатолий Викторович|574"
},
"14:35-16:10": {
"name": "Безопасность жизнедеятельности",
"infos": "Гимишли Николай Федосеевич|614"
}
}
}
}
+2 -2
View File
@@ -3,8 +3,8 @@
"username": "kr0sh_512", "username": "kr0sh_512",
"first_name": "Дмитрий", "first_name": "Дмитрий",
"last_name": "", "last_name": "",
"group": "102", "group": "117",
"timeout": "12", "timeout": "10",
"allow_message": "yes", "allow_message": "yes",
"thread": "General" "thread": "General"
} }
+4
View File
@@ -0,0 +1,4 @@
python-telegram-bot==13.7
requests==2.26.0
python-dotenv==0.19.0
schedule==1.1.0
+501 -149
View File
@@ -1,5 +1,5 @@
#!/usr/bin/python3.3 #!/usr/bin/python3.3
import threading, telebot, schedule, time import threading, telebot, schedule, time, random, yaml
from datetime import datetime from datetime import datetime
import os, sys import os, sys
from telebot import types from telebot import types
@@ -7,44 +7,52 @@ from telegram.constants import ParseMode
import for_json import for_json
from admin import admin_command, is_admin, send_admin_message, send_admin_document from admin import admin_command, is_admin, send_admin_message, send_admin_document
bot = telebot.TeleBot("TOKEN_API") config = yaml.safe_load(open("config.yaml"))
bot = telebot.TeleBot(config["test_token"])
parity_FIRST = 1
@bot.message_handler(commands=["help", "faq"])
@bot.message_handler(commands=['help', 'faq'])
def help(message): def help(message):
help_msg = 'Мои команды:\ help_msg = "Мои команды:\
\n/start - используй, чтобы сменить номер группы.\ \n/start - используй, чтобы сменить номер группы.\
\n/schedule - используй, чтобы получить расписание на сегодня.\ \n/schedule - используй, чтобы получить расписание на сегодня.\
\n/random - сделай очередь из людей\
\n/info - используй, чтобы узнать твои настройки бота\ \n/info - используй, чтобы узнать твои настройки бота\
\n/pause - используй, чтобы прекратить получать сообщения от бота\ \n/pause - используй, чтобы прекратить получать сообщения от бота\
\n/thread - используй в нужном чате канала, чтобы бот отправлял сообщения именно туда\ \n/thread - используй в нужном чате канала, чтобы бот отправлял сообщения именно туда\
\n/timeout - настрой время, когда бот будет присылать тебе сообщение\ \n/timeout - настрой время, когда бот будет присылать тебе сообщение\
\n/request - используй, чтобы отправить разработчику какой-то запрос\ \n/request - используй, чтобы отправить разработчику какой-то запрос\
\n/source - Страница бота на Github\ \n/source - Страница бота на Github\
\n\nИли же можно всегда написать напрямую: @Kr0sH_512' \n\nИли же можно всегда написать напрямую: @Kr0sH_512"
send_message(message.chat.id, help_msg) send_message(message.chat.id, help_msg)
if is_admin(message): if is_admin(message):
admin_help_msg = 'И команды только для админа:\ admin_help_msg = "И команды только для админа:\
\n/restart - перезапуск бота.\ \n/restart - перезапуск бота.\
\n/update - обновление schedule задач\ \n/update - обновление schedule задач\
\n/stats - получание статистики\
\n/json - получить файл пользователей и расписания\ \n/json - получить файл пользователей и расписания\
\n/info <i>id_пользователя</i> - узнать настройки пользователя\ \n/info <i>id_пользователя</i> - узнать настройки пользователя\
\n/spam - сделать рассылку\
\n/pause_all - приостановить бота для всех (каникулы/выходные)\ \n/pause_all - приостановить бота для всех (каникулы/выходные)\
\n/stop <i>id_пользователя</i> - приостановить отправку сообщений для пользователя' \n/stop <i>id_пользователя</i> - приостановить отправку сообщений для пользователя"
send_admin_message(admin_help_msg) send_admin_message(admin_help_msg)
return return
### --//-- ### --//--
@bot.message_handler(commands=['test'])
@bot.message_handler(commands=["test", "t"])
@admin_command @admin_command
def update_schedules(message): def test(message):
text = '<b>Жирный текст</b>\ text = '<b>Жирный текст</b>\
\n<i>Курсивный текст</i>\ \n<i>Курсивный текст</i>\
\n<u>Подчёркнутый</u>\
\n<s>Перечёркнутый текст</s>\ \n<s>Перечёркнутый текст</s>\
\n<a href="google.com">Ссылка</a>\ \n<a href="google.com">Ссылка</a>\
\n<code>Моноширинный текст</code>\ \n<code>Моноширинный текст</code>\
@@ -54,269 +62,585 @@ def update_schedules(message):
return return
@bot.message_handler(commands=['restart'])
@bot.message_handler(commands=["restart", "r"])
@admin_command @admin_command
def restart_bot(message): def restart_bot(message):
send_admin_message('bye') send_admin_message("bye")
os.execv(sys.executable, ['python'] + sys.argv) os.execv(sys.executable, ["python3", "-u"] + sys.argv)
@bot.message_handler(commands=['update'])
@bot.message_handler(commands=["update"])
@admin_command @admin_command
def update_schedules(message): def update_schedules(message):
for_json.create_schedule_tasks(manual=True) for_json.create_schedule_tasks(manual=True)
send_admin_message('Произошёл update') send_admin_message("Произошёл update")
return return
@bot.message_handler(commands=['json'])
@bot.message_handler(commands=["stats"])
@admin_command
def send_stat(message):
text = "<u>Статистика:</u>\
\n(группа: всего/откл. увед./беседы)"
sum_users = 0
sum_dis_not = 0
sum_chats = 0
groups = list(for_json.groups_in_json())
groups.append("other")
for i in groups:
users = for_json.students_in_group(i)
sum_users += len(users)
dis_not = len(
[
i
for i, x in enumerate(users)
if for_json.return_infos(x)["allow_message"] == "no"
]
)
sum_dis_not += dis_not
chats = len([i for i, x in enumerate(users) if x[0] == "-"])
sum_chats += chats
text += "\n{}: {} / {} / {}".format(i, len(users), dis_not, chats)
text += "\n\nВсего: {} / {} / {}".format(sum_users, sum_dis_not, sum_chats)
send_admin_message(text)
return
@bot.message_handler(commands=["json"])
@admin_command @admin_command
def send_json(message): def send_json(message):
with open(for_json.path_users, 'rb') as json_file: with open(for_json.path_users, "rb") as json_file:
send_admin_document(json_file) send_admin_document(json_file)
with open(for_json.path_schedule, 'rb') as json_file: with open(for_json.path_schedule, "rb") as json_file:
send_admin_document(json_file)
with open(for_json.path_students, "rb") as json_file:
send_admin_document(json_file) send_admin_document(json_file)
return return
# info user_id # info user_id
@bot.message_handler(commands=['pause_all'])
@bot.message_handler(commands=["spam"])
@admin_command
def spam(message):
send_admin_message(
"Пришли мне id, номер группы или <i>all</i> для рассылки сообщения этим пользователям"
)
bot.register_next_step_handler(message, spam_msg)
return
def spam_msg(message):
if message.text == "stop" or message.text == "стоп" or message.text[0] == "/":
send_admin_message("Отмена отправки")
return
send_admin_message("Пришли мне текст для рассылки сообщения этим пользователям")
bot.register_next_step_handler(message, spam_cnf, message.text)
return
def spam_cnf(message, data):
if message.text == "stop" or message.text == "стоп" or message.text[0] == "/":
send_admin_message("Отмена отправки")
return
global text_spam
text_spam = message.text
text = "Пожалуйста, проверь итоговое сообщение и подтверди отправку:\
\n\nКому: "
if data == "all":
text += "<u>всем</u>"
elif data in for_json.groups_in_json():
text += "{} группе".format(data)
elif for_json.return_infos(data) != None:
text += "пользователю @{}".format(for_json.return_infos(data)["username"])
else:
send_admin_message("Ошибка при выборе пользователей")
return
text += "\n\nСообщение: {}".format(message.text)
markup = types.InlineKeyboardMarkup()
markup.add(
types.InlineKeyboardButton(text="", callback_data="spam#{}".format(data)),
types.InlineKeyboardButton(text="", callback_data="spam_no"),
)
bot.send_message(
message.from_user.id, text, parse_mode=ParseMode.HTML, reply_markup=markup
)
return
@bot.callback_query_handler(func=lambda call: "spam" in call.data)
def spam_send(call):
if call.data == "spam_no":
send_admin_message("Отмена отправки")
return
tmp, data = call.data.split("#")
global text_spam
text = text_spam
users = []
if data == "all":
groups = for_json.groups_in_json()
for group in groups:
users += for_json.students_in_group(group)
users += for_json.students_in_group("other")
elif data in for_json.groups_in_json():
users = for_json.students_in_group(data)
elif for_json.return_infos(data) != None:
users = [data]
for i in users:
send_message(i, text)
bot.edit_message_text(
chat_id=call.message.chat.id,
message_id=call.message.message_id,
text="Успешно!",
parse_mode=ParseMode.HTML,
)
return
@bot.message_handler(commands=["pause_all"])
@admin_command @admin_command
def pause_bot(message): def pause_bot(message):
for_json.pause_bot() for_json.pause_bot()
send_admin_message('Бот больше не отправляет расписание')
return return
@bot.message_handler(commands=['stop'])
@bot.message_handler(commands=["stop"])
@admin_command @admin_command
def pause_bot(message): def stop_msg(message):
if len(str(message.text).split(' ')) != 2: if len(str(message.text).split(" ")) != 2:
send_admin_message('Эта команда вида /stop <i>id_пользователя</i>') send_admin_message("Эта команда вида /stop <i>id_пользователя</i>")
return return
for_json.change_user_param(str(message.text).split(' ')[1], 'allow_message', 'no')
send_admin_message('Успешно') for_json.change_user_param(str(message.text).split(" ")[1], "allow_message", "no")
send_admin_message("Успешно")
return return
### --//-- ### --//--
@bot.message_handler(commands=['start'])
@bot.message_handler(commands=["start"])
def start(message): def start(message):
start_txt = 'Привет! Это бот, который будет кидать тебе сообщения перед нужной парой с номером кабинета/фамилией препода\ start_txt = "Привет! Это бот, который будет кидать тебе сообщения перед нужной парой с номером кабинета/фамилией препода\
\n\nТы можешь настроить отправку сообщений в лс или добавить меня в группу, куда я буду присылать расписание\ \n\nТы можешь настроить отправку сообщений в лс или добавить меня в группу, куда я буду присылать расписание\
\n\nCreated by: @Kr0sH_512' \n\nCreated by: @Kr0sH_512"
if message.chat.type == "supergroup": if message.chat.type == "supergroup":
if len(message.text.split(' ')) != 2: if len(message.text.split(" ")) != 2:
send_message(message.chat.id, start_txt) send_message(message.chat.id, start_txt)
send_message(message.chat.id, 'Похоже, что этот бот добавлен в группу. Чтобы он присылал расписание в чат, \ send_message(
message.chat.id,
"Похоже, что этот бот добавлен в группу. Чтобы он присылал расписание в чат, \
укажите вместе с /start@vmk_schedule_bot номер своей группы.\ укажите вместе с /start@vmk_schedule_bot номер своей группы.\
\nПример:\n/start@vmk_schedule_bot 102') \nПример:\n/start@vmk_schedule_bot 102",
)
else: else:
temp = message.text.split(' ')[1] temp = message.text.split(" ")[1]
if temp.isdigit(): if temp.isdigit():
infos = [ infos = [
message.chat.id, message.chat.id,
message.chat.title, message.chat.title,
'', "",
message.from_user.username, message.from_user.username,
temp temp,
] ]
if temp in for_json.groups_in_json(): if temp in for_json.groups_in_json():
send_message(message.chat.id, send_message(
'Отлично! Теперь я буду присылать вам расписание {} группы'.format(temp)) message.chat.id,
"Отлично! Теперь я буду присылать вам расписание {} группы".format(
temp
),
)
else: else:
send_message(message.chat.id, 'Похоже, что расписания для этой группы ещё не существует. \ send_message(
\nРазработчик уже пинается, но можете дополнительно написать ему: @Kr0sH_512') message.chat.id,
"Похоже, что расписания для этой группы ещё не существует. \
\nРазработчик уже пинается, но можете дополнительно написать ему: @Kr0sH_512",
)
send_admin_message('В группе {} был запрос на {} группу.\ send_admin_message(
\nid: {}'.format(message.chat.title, temp, message.chat.id)) "В группе {} был запрос на {} группу.\
temp = 'other' \nid: {}".format(
message.chat.title, temp, message.chat.id
)
)
temp = "other"
for_json.save_user(infos) for_json.save_user(infos)
else: else:
send_message(message.chat.id, 'Введено не число. Попробуйте снова.\ send_message(
\nПример:\n/start@vmk_schedule_bot 102') message.chat.id,
"Введено не число. Попробуйте снова.\
\nПример:\n/start@vmk_schedule_bot 102",
)
return return
send_message(message.chat.id, start_txt) send_message(message.chat.id, start_txt)
markup = types.InlineKeyboardMarkup() markup = types.InlineKeyboardMarkup()
for i in for_json.groups_in_json(): # for i in for_json.groups_in_json():
markup.add(types.InlineKeyboardButton(text=i, callback_data=i)) # markup.add(types.InlineKeyboardButton(text=i, callback_data=i))
markup.add(types.InlineKeyboardButton(text="Моей группы нет в этом списке", callback_data="other")) markup.add(types.InlineKeyboardButton(text="1 курс", callback_data="1course"))
bot.send_message(message.chat.id, 'Пожалуйста, выбери свою группу', parse_mode=ParseMode.HTML, reply_markup=markup) markup.add(types.InlineKeyboardButton(text="2 курс", callback_data="2course"))
bot.send_message(
message.chat.id,
"Пожалуйста, выбери свой курс",
parse_mode=ParseMode.HTML,
reply_markup=markup,
)
return return
@bot.callback_query_handler(func=lambda call: not(call.data in ['left', 'right']))
@bot.callback_query_handler(
func=lambda call: call.data in for_json.groups_in_json()
or call.data in ["other", "1course", "2course"]
)
def callback_inline(call): def callback_inline(call):
if "course" in call.data:
course = call.data[0]
markup = types.InlineKeyboardMarkup()
for i in [i for i in for_json.groups_in_json() if i[0] == course]:
markup.add(types.InlineKeyboardButton(text=i, callback_data=i))
markup.add(
types.InlineKeyboardButton(
text="Моей группы нет в этом списке", callback_data="other"
)
)
bot.edit_message_text(
text="Пожалуйста, выбери свою группу",
chat_id=call.message.chat.id,
message_id=call.message.message_id,
reply_markup=markup,
)
# bot.edit_message_reply_markup(
# call.message.chat.id, call.message.message_id, reply_markup=markup
# )
return
infos = [ infos = [
call.from_user.id, call.from_user.id,
call.from_user.first_name, call.from_user.first_name,
call.from_user.last_name, call.from_user.last_name,
call.from_user.username, call.from_user.username,
call.data call.data,
] ]
for_json.save_user(infos) for_json.save_user(infos)
if call.data == 'other': if call.data == "other":
bot.edit_message_text(chat_id=call.message.chat.id, bot.edit_message_text(
chat_id=call.message.chat.id,
message_id=call.message.message_id, message_id=call.message.message_id,
text='Используй команду /request \ text="Используй команду /request и напиши номер группы, которую хочешь добавить\
и напиши номер группы, которую хочешь добавить\ \nПосле создания расписания для твоей группы, я пришлю тебе сообщение",
\nПосле создания расписания для твоей группы, я пришлю тебе сообщение', parse_mode=ParseMode.HTML,
parse_mode=ParseMode.HTML) )
else: else:
bot.edit_message_text(chat_id=call.message.chat.id, bot.edit_message_text(
chat_id=call.message.chat.id,
message_id=call.message.message_id, message_id=call.message.message_id,
text='Отлично, теперь тебе будут приходить сообщения!', text="Отлично, теперь тебе будут приходить сообщения!",
parse_mode=ParseMode.HTML) parse_mode=ParseMode.HTML,
)
return return
@bot.message_handler(commands=["schedule"])
@bot.message_handler(commands=['schedule'])
def send_schedule(message): def send_schedule(message):
text = 'К сожалению, бот не может отправить тебе расписание твоей группы на сегодня :(' text = (
"К сожалению, бот не может отправить тебе расписание твоей группы на сегодня :("
)
try: try:
day = datetime.today().strftime('%A').lower()[:3] # mon tue ... day = datetime.today().strftime("%A").lower()[:3] # mon tue ...
text = for_json.get_schedule(message.chat.id, day) text = for_json.get_schedule(message.chat.id, day)
except Exception as e: except Exception as e:
send_admin_message('Schedule error from: {} \n\n {}'.format(message.chat.id, e)) # send_admin_message(
# "Schedule error from: {} \n\n {}".format(message.chat.id, str(e))
# )
bot.send_message(
message.chat.id,
"Пожалуйста, проверь, что ты зарегестрировался с помощью команды /start",
ParseMode.HTML,
message_thread_id=message.message_thread_id,
)
markup = types.InlineKeyboardMarkup() markup = types.InlineKeyboardMarkup()
markup.add(types.InlineKeyboardButton(text="◀️", callback_data="left"), markup.add(
types.InlineKeyboardButton(text="", callback_data="right")) types.InlineKeyboardButton(text="", callback_data="left"),
bot.send_message(message.chat.id, text, ParseMode.HTML, reply_markup=markup) types.InlineKeyboardButton(text="▶️", callback_data="right"),
)
bot.send_message(
message.chat.id,
text,
ParseMode.HTML,
reply_markup=markup,
message_thread_id=message.message_thread_id,
)
return return
@bot.callback_query_handler(func=lambda call: call.data in ['left', 'right'])
@bot.callback_query_handler(func=lambda call: call.data in ["left", "right"])
def change_schedule(call): def change_schedule(call):
days = ['mon', 'tue', 'wed', 'thu', 'fri', 'sat'] days = ["mon", "tue", "wed", "thu", "fri", "sat"]
russian_days = ['понедельник', 'вторник', 'среду', 'четверг', 'пятницу', 'субботу'] russian_days = ["понедельник", "вторник", "среду", "четверг", "пятницу", "субботу"]
i = 6 # выходной i = 6 # выходной
for day in russian_days: for day in russian_days:
if day in call.message.text: if day in call.message.text:
i = russian_days.index(day) i = russian_days.index(day)
break break
delta = (1) if (call.data == 'right') else (-1) delta = (1) if (call.data == "right") else (-1)
ind = ((i + delta) % 6) if (i + delta > 0) else (i + delta) ind = ((i + delta) % 6) if (i + delta > 0) else (i + delta)
text = for_json.get_schedule(call.message.chat.id, days[ind]) text = for_json.get_schedule(call.message.chat.id, days[ind])
markup = types.InlineKeyboardMarkup() markup = types.InlineKeyboardMarkup()
markup.add(types.InlineKeyboardButton(text="◀️", callback_data="left"), markup.add(
types.InlineKeyboardButton(text="", callback_data="right")) types.InlineKeyboardButton(text="", callback_data="left"),
types.InlineKeyboardButton(text="▶️", callback_data="right"),
)
bot.edit_message_text(text, call.message.chat.id, call.message.message_id, bot.edit_message_text(
parse_mode=ParseMode.HTML, reply_markup=markup) text,
call.message.chat.id,
call.message.message_id,
parse_mode=ParseMode.HTML,
reply_markup=markup,
)
return return
@bot.message_handler(commands=["random"])
def random_people(message):
list_of_num = ["1️⃣", "2️⃣", "3️⃣", "4️⃣", "5️⃣", "6", "7", "8", "9"]
@bot.message_handler(commands=['info']) list_of_var = for_json.students_in_json(message.chat.id)
text = "Для вашей группы эта команда не настроена.\n\nНапиши запрос через /request"
if list_of_var == None:
send_message(message.chat.id, text)
send_admin_message(
"Запрос на random команду от {}".format(
for_json.return_infos(message.chat.id)["group"]
)
)
return
text = "• Выбери как именно мне перемешать вас:\n"
l = []
for i, val in enumerate(list_of_var):
text += "\n{} {}".format(list_of_num[i], val)
l.append(
types.InlineKeyboardButton(text=list_of_num[i], callback_data="rand#" + val)
)
l = [l]
markup = types.InlineKeyboardMarkup(l)
bot.send_message(message.chat.id, text, ParseMode.HTML, reply_markup=markup)
return
@bot.callback_query_handler(func=lambda call: "rand#" in call.data)
def make_random(call):
list_of_stud = for_json.students_in_json(
call.message.chat.id, call.data.split("#")[1]
)
random.shuffle(list_of_stud)
text = "<b><u>{}</u></b>:\n\n".format(call.data.split("#")[1])
for i, name in enumerate(list_of_stud):
text += "<code>{}{}</code>. {}\n".format(" " if i + 1 < 10 else "", i + 1, name)
bot.edit_message_text(
"Хорошо, вот ваше распределение!",
call.message.chat.id,
call.message.message_id,
parse_mode=ParseMode.HTML,
)
send_message(call.message.chat.id, text)
return
@bot.message_handler(commands=["info"])
def send_info(message): def send_info(message):
if len(message.text.split(' ')) == 2 and is_admin(message): if len(message.text.split(" ")) == 2 and is_admin(message):
send_admin_message('Окей, держи настройки <code>{}</code>'.format(message.text.split(' ')[1])) send_admin_message(
infos = for_json.return_infos(message.text.split(' ')[1]) "Окей, держи настройки <code>{}</code>".format(message.text.split(" ")[1])
text = '<i>Никнейм</i>: <b>@{}</b>\ )
infos = for_json.return_infos(message.text.split(" ")[1])
text = "<i>Никнейм</i>: <b>@{}</b>\
\n<i>Имя</i>: <b>{} {}</b>\ \n<i>Имя</i>: <b>{} {}</b>\
\n<i>Выбранная группа</i>: <b>{}</b>\ \n<i>Выбранная группа</i>: <b>{}</b>\
\n<i>Время напоминания до урока</i>: <b>{}</b>\ \n<i>Время напоминания до урока</i>: <b>{}</b>\
\n<i>Разрешены ли напоминания</i>: <b>{}</b>'.format(infos['username'], infos['first_name'], infos['last_name'], \n<i>Разрешены ли напоминания</i>: <b>{}</b>".format(
(infos['group'] if infos['group'] != 'other' else 'не выбрана'), infos["username"],
infos['timeout'], infos["first_name"],
('да' if infos['allow_message'] == 'yes' else 'нет')) infos["last_name"],
(infos["group"] if infos["group"] != "other" else "не выбрана"),
infos["timeout"],
("да" if infos["allow_message"] == "yes" else "нет"),
)
send_admin_message(text) send_admin_message(text)
return return
send_message(message.chat.id, 'Хорошо, вот твои настройки:') send_message(message.chat.id, "Хорошо, вот твои настройки:")
infos = for_json.return_infos(message.chat.id) infos = for_json.return_infos(message.chat.id)
text = '<i>Выбранная группа</i>: <b>{}</b>\ text = "<i>Выбранная группа</i>: <b>{}</b>\
\n<i>Время напоминания до урока</i>: <b>{}</b>\ \n<i>Время напоминания до урока</i>: <b>{}</b>\
\n<i>Разрешены ли напоминания</i>: <b>{}</b>'.format((infos['group'] if infos['group'] != 'other' else 'не выбрана'), \n<i>Разрешены ли напоминания</i>: <b>{}</b>".format(
infos['timeout'], (infos["group"] if infos["group"] != "other" else "не выбрана"),
('да' if infos['allow_message'] == 'yes' else 'нет')) infos["timeout"],
("да" if infos["allow_message"] == "yes" else "нет"),
)
send_message(message.chat.id, text) send_message(message.chat.id, text)
return return
@bot.message_handler(commands=["pause"])
@bot.message_handler(commands=['pause'])
def pause_schedule(message): def pause_schedule(message):
infos = for_json.return_infos(message.chat.id)['allow_message'] infos = for_json.return_infos(message.chat.id)["allow_message"]
if infos == 'yes': if infos == "yes":
for_json.change_user_param(str(message.chat.id), 'allow_message', 'no') for_json.change_user_param(str(message.chat.id), "allow_message", "no")
send_message(message.chat.id, 'Рассылка сообщений преращена. \ send_message(
\nДля возобновления воспользуйтесь командой\n/pause') message.chat.id,
"Рассылка сообщений прекращена. \
\nДля возобновления воспользуйтесь командой\n/pause",
)
else: else:
for_json.change_user_param(str(message.chat.id), 'allow_message', 'yes') for_json.change_user_param(str(message.chat.id), "allow_message", "yes")
send_message(message.chat.id, 'Рассылка сообщений возоблена!') send_message(message.chat.id, "Рассылка сообщений возоблена!")
return return
@bot.message_handler(commands=["thread"])
@bot.message_handler(commands=['thread'])
def change_thread(message): def change_thread(message):
thread_id = '' thread_id = ""
try: try:
thread_id = message.reply_to_message.message_thread_id thread_id = message.reply_to_message.message_thread_id
except AttributeError: except AttributeError:
thread_id = "General" thread_id = "General"
for_json.change_user_param(str(message.chat.id), 'thread', thread_id) for_json.change_user_param(str(message.chat.id), "thread", thread_id)
send_message(message.chat.id, 'Хорошо, теперь я буду отправлять сообщения в этот чат', thread_id) send_message(
message.chat.id,
"Хорошо, теперь я буду отправлять сообщения в этот чат",
thread_id,
)
return return
@bot.message_handler(commands=["timeout"])
@bot.message_handler(commands=['timeout'])
def set_timeout(message): def set_timeout(message):
send_message(message.chat.id, 'Пришли мне число от 1 до 60. \ send_message(
\nЭто будет количество минут, за которое я буду присылать тебе напоминание о уроке (По умолчанию: 10)') message.chat.id,
"Пришли мне число от 1 до 59. \
\nЭто будет количество минут, за которое я буду присылать тебе напоминание о паре (По умолчанию: 10)",
)
bot.register_next_step_handler(message, save_timeout) bot.register_next_step_handler(message, save_timeout)
return return
def save_timeout(message): def save_timeout(message):
if str(message.text).isdigit() and int(message.text) <= 60 and int(message.text) >= 1: if (
for_json.change_user_param(message.chat.id, 'timeout', str(message.text)) str(message.text).isdigit()
send_message(message.chat.id, and int(message.text) <= 59
'Хорошо, теперь ты будешь получать напоминания за {} минут до урока'.format(str(message.text))) and int(message.text) >= 1
):
for_json.change_user_param(message.chat.id, "timeout", str(message.text))
send_message(
message.chat.id,
"Хорошо, теперь ты будешь получать напоминания за {} минут до урока".format(
str(message.text)
),
)
else: else:
send_message(message.chat.id, send_message(
'Пожалуйста, пришли <u>число</u> от 1 до 60. \ message.chat.id,
\nПо умолчанию: 10') "Пожалуйста, пришли <u>число</u> от 1 до 59. \
send_message(message.chat.id, 'Изменения не были внесены') \nПо умолчанию: 10",
)
send_message(message.chat.id, "Изменения не были внесены")
return return
@bot.message_handler(commands=["request"])
@bot.message_handler(commands=['request'])
def request(message): def request(message):
send_message(message.from_user.id, 'Отправь мне сообщение и я перешлю его разработчику\ send_message(
\n(или напиши stop, чтобы отменить отправку)') message.from_user.id,
"Отправь мне сообщение и я перешлю его разработчику\
\n(или напиши stop, чтобы отменить отправку)",
)
bot.register_next_step_handler(message, send_request) bot.register_next_step_handler(message, send_request)
return return
def send_request(message): def send_request(message):
if message.text == "stop" or message.text == "стоп" or message.text[0] == '/': if message.text == "stop" or message.text == "стоп" or message.text[0] == "/":
send_message(message.from_user.id, 'Отмена отпраки') send_message(message.from_user.id, "Отмена отправки")
return return
infos = [ infos = [
@@ -324,59 +648,87 @@ def send_request(message):
message.from_user.first_name, message.from_user.first_name,
message.from_user.last_name, message.from_user.last_name,
message.from_user.username, message.from_user.username,
message.text message.text,
] ]
for i in range(len(infos)): for i in range(len(infos)):
if type(infos[i]) == type(None): if type(infos[i]) == type(None):
infos[i] = '' infos[i] = ""
admin_text = 'Сообщение от {} {} (@{}):\n\n{}\nid: {}'.format(infos[1], infos[2], infos[3], infos[4], infos[0]) admin_text = "Сообщение от {} {} (@{}):\n\n{}\nid: <code>{}</code>".format(
infos[1], infos[2], infos[3], infos[4], infos[0]
)
send_admin_message(admin_text) send_admin_message(admin_text)
send_message(message.from_user.id, 'Ваше сообщение успешно доставлено!') send_message(message.from_user.id, "Ваше сообщение успешно доставлено!")
return return
@bot.message_handler(commands=["source"])
@bot.message_handler(commands=['source'])
def send_source(message): def send_source(message):
bot.send_message(message.chat.id, 'https://github.com/kr0sh512/Telegram-bot-schedule', parse_mode=ParseMode.HTML) bot.send_message(
message.chat.id,
"https://github.com/kr0sh512/Telegram-bot-schedule",
parse_mode=ParseMode.HTML,
)
return return
@bot.message_handler(content_types=["text"])
@bot.message_handler(content_types=['text'])
def text_message(message): def text_message(message):
if message.chat.type == "supergroup": if message.chat.type == "supergroup" or is_admin(message):
return return
send_message(message.from_user.id, 'К сожалению, я ещё не умею обрабатывать сообщения.\ send_message(
\nИспользуй команды из меню или напиши /help.') message.from_user.id,
"К сожалению, я ещё не умею обрабатывать сообщения.\
\nИспользуй команды из меню или напиши /help.",
)
return return
def send_message(id, text, thread_id="General", parity=None):
def send_message(id, text, thread_id='General'): if thread_id == "General":
if thread_id == 'General':
thread_id = None thread_id = None
if parity:
count_of_weeks = (datetime.now() - datetime(2024, 2, 5)).days // 7
is_odd = (count_of_weeks + 1) % 2 == parity_FIRST
if is_odd != bool(parity):
return
try: try:
bot.send_message(chat_id=id, text=text, parse_mode=ParseMode.HTML, message_thread_id=thread_id,disable_web_page_preview=True) bot.send_message(
chat_id=id,
text=text,
parse_mode=ParseMode.HTML,
message_thread_id=thread_id,
disable_web_page_preview=True,
)
except Exception as e: except Exception as e:
time.sleep(5) time.sleep(5)
try: try:
bot.send_message(chat_id=id, text=text, parse_mode=ParseMode.HTML, message_thread_id=thread_id,disable_web_page_preview=True) bot.send_message(
chat_id=id,
text=text,
parse_mode=ParseMode.HTML,
message_thread_id=thread_id,
disable_web_page_preview=True,
)
except Exception as e: except Exception as e:
text_error = 'Error from user: <code>{}</code>\n{}'.format(id, str(e)) text_error = "Error from user: @{} <code>{}</code>\n{}".format(
send_admin_message(text_error) for_json.return_infos(id)["username"], id, str(e)
print(id, e) )
# send_admin_message(text_error)
print(f"--- {text_error} ---")
return return
def send_document(id, file, text = ''):
def send_document(id, file, text=""):
try: try:
bot.send_document(id, file, caption=text) bot.send_document(id, file, caption=text)
except Exception as e: except Exception as e:
@@ -384,21 +736,22 @@ def send_document(id, file, text = ''):
try: try:
bot.send_document(id, file, caption=text) bot.send_document(id, file, caption=text)
except Exception as e: except Exception as e:
text_error = 'Error from user: <code>{}</code>\n{}'.format(id, str(e)) text_error = "Error from user: <code>{}</code>\n{}".format(id, str(e))
send_admin_message(text_error) send_admin_message(text_error)
print(id, e) print(id, e)
return return
if __name__ == "__main__":
for_json.create_schedule_tasks(True)
if __name__ == '__main__': send_admin_message("Я перезапустился!")
for_json.create_schedule_tasks()
send_admin_message('Я перезапустился!')
print("-------------------------") print("-------------------------")
threading.Thread(target=bot.infinity_polling, name='bot_infinity_polling', daemon=True).start() threading.Thread(
target=bot.infinity_polling, name="bot_infinity_polling", daemon=True
).start()
while True: while True:
try: try:
@@ -407,4 +760,3 @@ if __name__ == '__main__':
except Exception as e: except Exception as e:
print(e) print(e)
time.sleep(10) time.sleep(10)
+201
View File
@@ -0,0 +1,201 @@
studies.begin: {y: 2024, m: 9, d: 1}
studies.end: null
schedule:
mon:
- begin: '8:45'
end: '10:20'
name: Английский язык
teacher.room:
- {t: Бим М.М., r: '735'}
- {t: ' Шубина Ю.В.', r: '73'}
type: seminar
parity: null
- begin: '10:30'
end: '12:05'
name: Практикум на ЭВМ
teacher.room:
- {t: Тюляева В.В., r: МЗ-4}
- {t: '', r: null}
type: seminar
parity: null
- begin: '12:15'
end: '13:50'
name: Классическая механика
teacher.room:
- {t: Брандт Н.Н., r: '659'}
type: seminar
parity: null
- begin: '15:00'
end: '16:30'
name: Физическая культура
teacher.room: []
type: null
parity: null
tue:
- begin: '8:45'
end: '10:20'
name: Теория вероятностей и математическая статистика
teacher.room:
- {t: профессор Королёв Виктор Юрьевич, r: П-13}
type: lecture
parity: null
- begin: '10:30'
end: '12:05'
name: Математический анализ
teacher.room:
- {t: доцент Крицков Леонид Владимирович, r: П-11}
type: lecture
parity: null
- begin: '12:15'
end: '13:50'
name: Математический анализ
teacher.room:
- {t: Сычугов Д.Ю., r: '606'}
type: seminar
parity: null
- begin: '14:35'
end: '16:10'
name: Обыкновенные дифференциальные ур-я
teacher.room:
- {t: Дмитриева И.В., r: '607'}
type: seminar
parity: null
- begin: '16:20'
end: '17:55'
name: null
teacher.room: []
type: seminar
parity: null
wed:
- begin: '8:45'
end: '10:20'
name: Практикум на ЭВМ
teacher.room:
- {t: Тюляева В.В., r: '507'}
type: seminar
parity: null
- begin: '10:30'
end: '12:05'
name: Математический анализ
teacher.room:
- {t: доцент Крицков Леонид Владимирович, r: П-6}
type: lecture
parity: null
- begin: '12:15'
end: '13:50'
name: Обыкновенные дифференциальные уравнения
teacher.room:
- {t: профессор Денисов Александр Михайлович, r: П-6}
type: lecture
parity: null
- begin: '15:10'
end: '18:50'
name: Межфакультетские курсы
teacher.room: []
type: seminar
parity: null
thu:
- begin: '8:45'
end: '10:20'
name: Операционные системы
teacher.room:
- {t: профессор Машечкин Игорь Валерьевич, r: П-13}
type: lecture
parity: null
- begin: '10:30'
end: '12:05'
name: Операционные системы
teacher.room:
- {t: профессор Машечкин Игорь Валерьевич, r: П-13}
type: lecture
parity: null
- begin: '12:15'
end: '13:50'
name: Английский язык
teacher.room:
- {t: Бим М.М., r: '71'}
- {t: '', r: null}
type: seminar
parity: null
- begin: '14:35'
end: '16:10'
name: Введение в численные методы
teacher.room:
- {t: доцент Нефёдов Владимир Вадимович, r: П-5}
type: lecture
parity: null
- begin: '16:20'
end: '17:55'
name: null
teacher.room: []
type: seminar
parity: null
fri:
- begin: '8:45'
end: '10:20'
name: Английский язык
teacher.room:
- {t: Шубина Ю.В., r: '506'}
type: seminar
parity: null
- begin: '10:50'
end: '12:20'
name: Физическая культура
teacher.room: []
type: null
parity: null
- begin: '12:50'
end: '14:25'
name: Теория вероятностей и математич. статистика
teacher.room:
- {t: Шевцова И.Г., r: '504'}
type: seminar
parity: null
- begin: '14:35'
end: '16:10'
name: Математический анализ
teacher.room:
- {t: Сычугов Д.Ю., r: '615'}
type: seminar
parity: null
- begin: '16:20'
end: '17:55'
name: null
teacher.room: []
type: seminar
parity: null
sat:
- begin: '8:45'
end: '10:20'
name: Философия
teacher.room:
- {t: профессор Девятова Светлана Владимировна, r: П-14}
type: lecture
parity: null
- begin: '10:30'
end: '12:05'
name: Философия Девятова С.В.
teacher.room:
- {t: null, r: '508'}
type: seminar
parity: null
- begin: '12:15'
end: '13:50'
name: null
teacher.room: []
type: seminar
parity: null
- begin: '14:35'
end: '16:10'
name: Операционные системы
teacher.room:
- {t: профессор Машечкин Игорь Валерьевич, r: П-13}
type: lecture
parity: null
- begin: '16:20'
end: '17:55'
name: Операционные системы
teacher.room:
- {t: профессор Машечкин Игорь Валерьевич, r: П-13}
type: lecture
parity: null