2023-10-27 15:31:53 +02:00
# SPDX-FileCopyrightText: 2023 Egor Guslyancev <electromagneticcyclone@disroot.org>
#
2023-12-04 10:13:56 +01:00
# SPDX-License-Identifier: AGPL-3.0-or-later
2023-10-27 15:31:53 +02:00
import telebot
import re
import time
import datetime as dt
import sys
import signal
import os
import subprocess
import pickle as p
from os import path
from sys import stderr , stdout , stdin
from threading import Thread
db = { }
def save_db ( dbfo = " .db " ) :
global db
try :
with open ( dbfo , " wb " ) as fo :
p . dump ( db , fo )
except :
stderr . write ( " Н е удалось записать базу!" )
sys . exit ( 1 )
def load_db ( dbfi = " .db " ) :
global db
if not path . exists ( dbfi ) :
save_db ( )
return
try :
with open ( dbfi , " rb " ) as fi :
db = p . load ( fi )
except :
stderr . write ( " Н е удалось прочитать базу, пробуем сохранить…" )
save_db ( )
def write_db ( field : str , value : any , data = None ) :
global db
head = False
if data == None :
data = db
head = True
field = field . split ( " . " )
if len ( field ) == 1 :
data [ field [ 0 ] ] = value
else :
if field [ 0 ] not in data or data [ field [ 0 ] ] is None :
data [ field [ 0 ] ] = { }
if type ( data [ field [ 0 ] ] ) is not dict :
raise ValueError ( " Поле не является группой. " )
data [ field [ 0 ] ] = write_db ( ' . ' . join ( field [ 1 : ] ) , value , data [ field [ 0 ] ] )
save_db ( )
if head :
db = data
return data
def read_db ( field : str , default = None , data = None ) - > any :
global db
if data == None :
data = db
field = field . split ( " . " )
if field [ 0 ] not in data :
return default
if len ( field ) == 1 :
return data [ field [ 0 ] ]
else :
return read_db ( ' . ' . join ( field [ 1 : ] ) , default , data [ field [ 0 ] ] )
def pop_db ( field : str ) :
global db
ret = read_db ( field )
field = field . split ( " . " )
val = read_db ( ' . ' . join ( field [ : - 1 ] ) )
if type ( val ) is not dict :
return
val . pop ( field [ - 1 ] )
write_db ( ' . ' . join ( field [ : - 1 ] ) , val )
return ret
load_db ( )
2023-12-04 10:04:07 +01:00
write_db ( " about.version " , " v1.0rc4 " )
2023-10-27 15:31:53 +02:00
write_db ( " about.author " , " electromagneticcyclone " )
write_db ( " about.tester " , " angelbeautifull " )
2023-11-23 15:31:06 +01:00
if ( read_db ( " about.host " ) is None ) and __debug__ :
2023-10-27 15:31:53 +02:00
stdout . write ( " Введите username хоста: " )
stdout . flush ( )
write_db ( " about.host " , stdin . readline ( ) [ : - 1 ] )
try :
bot = None
2023-11-23 15:31:06 +01:00
filename = " token.devel " if __debug__ else " token "
with open ( filename , encoding = " utf-8 " ) as fi :
2023-10-27 15:31:53 +02:00
for i in fi :
i = i . strip ( )
2023-11-19 16:53:07 +01:00
pattern = re . compile ( " ^[ \\ d] {10} :[ \\ w \\ d \\ - \\ + \\ *] {35} $ " )
2023-10-27 15:31:53 +02:00
matches = pattern . fullmatch ( i ) is not None
if matches :
bot = telebot . TeleBot ( i , parse_mode = " MarkdownV2 " )
break
if bot is None :
stderr . write ( " В файле нет токена\n " )
raise Exception
except :
2023-10-28 20:45:14 +02:00
stderr . write ( " Ошибка чтения файла токена \n " )
2023-10-27 15:31:53 +02:00
sys . exit ( 1 )
2023-10-31 10:23:14 +01:00
def get_time ( forum : int ) :
return dt . datetime . now ( dt . UTC ) \
2023-11-01 06:12:22 +01:00
+ dt . timedelta ( hours = read_db ( str ( forum ) + " .settings.timezone " , 3 ) )
2023-10-31 10:23:14 +01:00
def change_phase ( forum : int , date = None ) :
if date is None :
date = get_time ( forum ) . date ( )
2023-10-27 15:31:53 +02:00
phase = read_db ( str ( forum ) + " .schedule.phase " )
phases = read_db ( str ( forum ) + " .schedule.phases " )
last_changed = read_db ( str ( forum ) + " .schedule.last_phase_changing_date " )
if None in ( phase , last_changed , phases ) :
return
now = date
weekday = now . weekday ( )
if not ( now > last_changed and weekday == 0 ) :
return
phase = ( phase + 1 ) % phases
write_db ( str ( forum ) + " .schedule.phase " , phase )
write_db ( str ( forum ) + " .schedule.last_phase_changing_date " , now )
2023-10-31 10:23:14 +01:00
def get_status ( forum : int , date = None ) - > bool :
if date is None :
date = get_time ( forum ) . date ( )
2023-10-29 09:31:10 +01:00
now = date
2023-10-29 09:30:36 +01:00
weekday = now . weekday ( )
if weekday == 6 :
2023-10-31 10:24:55 +01:00
return None
2023-10-27 15:31:53 +02:00
phase = read_db ( str ( forum ) + " .schedule.phase " , 0 )
work_days = read_db ( str ( forum ) + " .schedule.work_days " , [ ] )
skip_days = read_db ( str ( forum ) + " .schedule.skip_days " , [ ] )
days = read_db ( str ( forum ) + " .schedule.days " , ( [ 0 ] * 6 , [ 0 ] * 6 ) )
is_active = read_db ( str ( forum ) + " .is_active " , False )
if is_active :
if now in work_days :
return True
if now in skip_days :
2023-10-31 10:24:55 +01:00
return 0
2023-10-27 15:31:53 +02:00
if days [ phase ] [ weekday ] :
return True
return False
def get_chat ( message , start = False ) :
if type ( message ) is int :
is_forum = True
forum = message
else :
is_forum = message . chat . is_forum
forum = message . chat . id
if ( read_db ( str ( forum ) ) is None or not is_forum ) and not start :
return None
chat = read_db ( str ( forum ) + " .settings.chat " )
if type ( message ) is int :
return chat
if ( chat is None ) or ( chat . id == message . reply_to_message . id ) :
return message . reply_to_message if is_forum else message
else :
return None
def check_if_admin ( message ) - > bool :
forum = message . chat . id
admin = read_db ( str ( forum ) + " .settings.admin " )
if admin is None :
return True
if admin [ " id " ] is None :
return admin [ " username " ] == message . from_user . username
return admin [ " id " ] == message . from_user . id
def mention ( forum : int , user_id : int ) - > str :
user_id = str ( user_id )
if read_db ( str ( forum ) + " .people. " + user_id ) is None :
stderr . write ( " Пользователя с ID " + user_id + " нет в базе. \n " )
return
2023-11-20 06:05:25 +01:00
return " [ " + read_db ( str ( forum ) + " .people. " + user_id + " .name " ) + " " \
+ read_db ( str ( forum ) + " .people. " + user_id + " .surname " ) + \
2023-11-20 06:02:45 +01:00
" ](tg://user?id= " + str ( user_id ) + " ) "
2023-10-27 15:31:53 +02:00
def find_uids ( forum : int , s : str ) :
people = read_db ( str ( forum ) + " .people " )
if people is None :
return
if people is None :
return None
2023-12-04 14:11:48 +01:00
if s [ 0 ] == ' @ ' :
s = s [ 1 : ]
2023-10-27 15:31:53 +02:00
f = [ i for i in people . keys ( ) if len ( [ j for j in people [ i ] . values ( ) if s in j ] ) > 0 ]
if len ( f ) == 0 :
return None
return f
def format_user_info ( forum : int , uid ) :
uid = str ( uid )
person = read_db ( str ( forum ) + " .people. " + uid )
if person is None :
return ' '
r = ' '
r + = " \\ # " + uid + ' \n '
for k , i in person . items ( ) :
r + = ( " ‖ " + ' ' + k + ' \\ = '
+ telebot . formatting . escape_markdown ( i ) + ' \n ' )
return r
2023-12-04 10:04:07 +01:00
def prepend_user ( forum : int , ulist_s : str , uid ) :
uid = str ( uid )
ulist = read_db ( str ( forum ) + " . " + ulist_s , [ ] )
ulist = list ( set ( [ uid ] + ulist ) )
write_db ( str ( forum ) + " . " + ulist_s , ulist )
def append_user ( forum : int , ulist_s : str , uid ) :
uid = str ( uid )
ulist = read_db ( str ( forum ) + " . " + ulist_s , [ ] )
ulist = list ( set ( ulist + [ uid ] ) )
write_db ( str ( forum ) + " . " + ulist_s , ulist )
def pop_user ( forum : int , ulist_s : str , uid ) :
uid = str ( uid )
ulist = read_db ( str ( forum ) + " . " + ulist_s , [ ] )
r = None
if len ( ulist ) > 0 :
r = ulist . pop ( 0 )
write_db ( str ( forum ) + " . " + ulist_s , ulist )
return r
def insert_user_in_current_order ( forum : int , uid ) - > bool :
uid = str ( uid )
order = read_db ( str ( forum ) + " .rookies.order " , [ ] )
people = read_db ( str ( forum ) + " .people " , { } )
current = read_db ( str ( forum ) + " .rookies.current " )
if uid not in people :
return False
order = list ( map ( lambda x : ( x , people [ x ] ) , order ) )
if current is not None :
order = dict ( sorted ( list ( order . items ( ) ) + [ ( current , people [ current ] ) ] , key = lambda item : item [ 1 ] [ " surname " ] ) )
order = dict ( sorted ( list ( order . items ( ) ) + [ uid , people [ uid ] ] , key = lambda item : item [ 1 ] [ " surname " ] ) )
pos = list ( order . keys ( ) ) . index ( current )
if pos == 0 :
return False
else :
write_db ( str ( forum ) + " .rookies.order " , list ( order . keys ( ) ) [ 1 : ] )
return True
2023-10-27 15:31:53 +02:00
timeout = None
caution = True
def antispam ( message , chat , forum ) :
if not check_if_admin ( message ) :
global timeout , caution
if timeout is not None :
period = read_db ( str ( forum ) + " .settings.antispam.period " )
if period is None :
write_db ( str ( forum ) + " .settings.antispam.period " , 600 )
period = 600
if time . time ( ) - timeout < period :
if caution :
bot . reply_to ( chat , " *Хватит спамить \\ ! \\ ! \\ !* " )
caution = False
bot . delete_message ( forum , message . id )
return True
caution = True
timeout = time . time ( )
return False
@bot.message_handler ( commands = [ ' start ' ] )
def start ( message ) :
forum = message . chat . id
chat = get_chat ( message , start )
if chat is not None :
if antispam ( message , chat , forum ) :
return
if message . chat . is_forum :
bot . reply_to ( chat ,
" Привет \\ ! Я бот для управления дежурствами и напоминания о них \\ . Напиши /link, чтобы привязать комнату \\ . " )
else :
bot . reply_to ( chat ,
" Я работаю только на форумах \\ (супергруппах с комнатами \\ ) \\ . Пригласи меня в один из них и напиши /start " )
@bot.message_handler ( commands = [ ' help ' ] )
def help ( message ) :
forum = message . chat . id
chat = get_chat ( message )
if chat is not None :
if antispam ( message , chat , forum ) :
return
if check_if_admin ( message ) :
if read_db ( str ( forum ) + " .settings.delete_messages " ) :
bot . delete_message ( forum , message . id )
bot . reply_to ( chat , " "
+ " /admin \\ [@ \\ ] — переопределить *админа* \n "
+ " /link — привязать комнату \n "
+ " /unlink — отвязать комнату \n "
+ " /cleaner 0/1 — удалять команды \n "
+ " /new @ Имя Фамилия — добавить ~салагу~ студента \n "
+ " /readd \\ # @ — если студент поменял ник, это нужно отметить \n "
+ " /remind — напомнить дежурным подежурить, а новичкам отметится \n "
+ " /forget — забыть всех новичков \n "
+ " /del @/ \\ #/Имя — убрать студента \n "
+ " /list \\ [@/ \\ #/Имя \\ ] — получить информацию по имени/фамиили \n "
+ " /purge — удалить форум из базы * \\ ! \\ ! \\ !ОПАСНО \\ ! \\ ! \\ !* \n "
+ " /timezone ±n — установить часовой пояс по UTC \n "
+ " /days \\ * \\ * \\ * \\ * \\ * \\ * \\ * \\ * \\ * \\ * \\ * \\ * \\ ( \\ * \\ = \\ [ \\ 0/1 \\ ] \\ ) — задать дни недели \\ (ПН \\ -СБ \\ ), когда необходимо дежурство, отдельно для числителей и знаменателей \n "
+ " /calendar \\ [Числитель/знаменатель \\ ] — показать календарь дежурств \n "
+ " /phase \\ [Числитель/знаменатель \\ ] — узнать или скорректировать фазу текущей недели \n "
+ " /skip \\ [00 \\ .00 \\ ] — пропустить сегодняшний или заданный день \n "
+ " /work \\ [00 \\ .00 \\ ] — поработать в сегодняшнем или заданном дне \n "
2023-12-04 10:04:07 +01:00
+ " /honor \\ [ \\ - \\ ]@ — пропуск следующего дежурства, так как студент молодец \n "
+ " /sick @ \\ [дата \\ ] — пропуск дежурства по причине болезни \n "
+ " /force \\ [ \\ - \\ ]@ — провинившийся дежурит как только так сразу \n "
2023-12-06 07:47:46 +01:00
+ " /order — посмотреть очередь дежурств \n "
2023-10-27 15:31:53 +02:00
+ " /stop — остановить дежурства \n "
+ " /begin \\ [@ \\ ] — начать сначала с определённого студента " )
@bot.message_handler ( commands = [ ' exec ' ] )
def exec_bot ( message ) :
2023-11-23 15:31:06 +01:00
if __debug__ :
forum = message . chat . id
chat = get_chat ( message , True )
if chat is not None :
if message . from_user . username == read_db ( " about.host " ) :
bot . reply_to ( chat , telebot . formatting . escape_markdown (
str ( eval ( ' ' . join ( message . text . split ( ' ' ) [ 1 : ] ) ) ) ) )
else :
bot . delete_message ( forum , message . id )
2023-10-27 15:31:53 +02:00
def pretty ( d , indent = 0 ) :
for key , value in d . items ( ) :
print ( ' ' * indent + str ( key ) )
if isinstance ( value , dict ) :
pretty ( value , indent + 1 )
else :
print ( ' ' * ( indent + 1 ) + str ( value ) )
@bot.message_handler ( commands = [ ' info ' ] )
def info ( message ) :
2023-11-23 15:31:06 +01:00
if __debug__ :
forum = message . chat . id
chat = get_chat ( message , True )
if chat is not None :
bot . delete_message ( forum , message . id )
if message . from_user . username == read_db ( " about.host " ) :
pretty ( db )
2023-10-27 15:31:53 +02:00
@bot.message_handler ( commands = [ ' fuck ' , ' fuck_you ' , ' fuck-you ' , ' fuckyou ' ] )
def rude ( message ) :
forum = message . chat . id
chat = get_chat ( message , True )
if chat is not None :
bot . delete_message ( forum , message . id )
@bot.message_handler ( commands = [ ' backup ' ] )
def backup_db ( message ) :
forum = message . chat . id
chat = get_chat ( message , True )
if chat is not None :
bot . delete_message ( forum , message . id )
if message . from_user . username == read_db ( " about.host " ) :
args = message . text . split ( ) [ 1 : ]
if len ( args ) == 0 :
args . append ( ' ' )
save_db ( args [ 0 ] + " .backup.db " )
@bot.message_handler ( commands = [ ' restore ' ] )
def restore_db ( message ) :
forum = message . chat . id
chat = get_chat ( message , True )
if chat is not None :
bot . delete_message ( forum , message . id )
if message . from_user . username == read_db ( " about.host " ) :
args = message . text . split ( ) [ 1 : ]
if len ( args ) == 0 :
args . append ( ' ' )
load_db ( args [ 0 ] + " .backup.db " )
@bot.message_handler ( commands = [ ' link ' ] )
def link ( message ) :
forum = message . chat . id
chat = get_chat ( message , True )
if chat is not None :
if antispam ( message , chat , forum ) :
return
if check_if_admin ( message ) :
write_db ( str ( forum ) + " .settings.chat " , message . reply_to_message )
if read_db ( str ( forum ) + " .settings.delete_messages " ) :
bot . delete_message ( forum , message . id )
bot . reply_to ( message . reply_to_message ,
" Комната \" " + str ( message . reply_to_message . forum_topic_created . name ) + " \" привязана \\ . "
2023-11-02 08:48:02 +01:00
+ " Чек-лист того, что нужно написать в первую очередь: \n "
+ " /admin \\ [@ \\ ], чтобы задать админа \n "
+ " /help, чтобы узнать, что я умею \n "
+ " /tz, чтобы задать часовой пояс \n "
+ " /phase \\ [Числитель/знаменатель \\ ], чтобы задать недельную фазу \n "
+ " /days \\ * \\ * \\ * \\ * \\ * \\ * \\ * \\ * \\ * \\ * \\ * \\ * \\ ( \\ * \\ = \\ [ \\ 0/1 \\ ] \\ ), чтобы задать дни дежурств \n "
+ " /new @ Имя Фамилия, чтобы добавить ~салаг~ студетов \n "
+ " /begin \\ [@ \\ ], чтобы начать дежурство " )
2023-10-27 15:31:53 +02:00
@bot.message_handler ( commands = [ ' unlink ' ] )
def unlink ( message ) :
forum = message . chat . id
chat = get_chat ( message )
if chat is not None :
if antispam ( message , chat , forum ) :
return
if check_if_admin ( message ) :
write_db ( str ( forum ) + " .settings.chat " , None )
if read_db ( str ( forum ) + " .settings.delete_messages " ) :
bot . delete_message ( forum , message . id )
bot . reply_to ( chat ,
" Комната отвязана " )
@bot.message_handler ( commands = [ ' purge ' ] )
def purge_db_people ( message ) :
forum = message . chat . id
chat = get_chat ( message )
if chat is not None :
if antispam ( message , chat , forum ) :
return
if check_if_admin ( message ) :
if message . text == " /purge ДА УДАЛЯЙ ДАВАЙ " :
write_db ( str ( forum ) , None )
if read_db ( str ( forum ) + " .settings.delete_messages " ) :
bot . delete_message ( forum , message . id )
bot . reply_to ( chat ,
" База студентов удалена " )
else :
if read_db ( str ( forum ) + " .settings.delete_messages " ) :
bot . delete_message ( forum , message . id )
bot . reply_to ( chat ,
" Чтобы подтвердить свои благие намерения, напиши \n "
+ " `/purge ДА УДАЛЯЙ ДАВАЙ` " )
@bot.message_handler ( commands = [ ' forget ' ] )
def forget_db_pending ( message ) :
forum = message . chat . id
chat = get_chat ( message )
if chat is not None :
if antispam ( message , chat , forum ) :
return
if check_if_admin ( message ) :
empty = read_db ( str ( forum ) + " .pending " ) is None
write_db ( str ( forum ) + " .pending " , None )
if read_db ( str ( forum ) + " .settings.delete_messages " ) :
bot . delete_message ( forum , message . id )
bot . reply_to ( chat ,
" База новичков удалена "
+ ( " , хоть и была уже пустая… " if empty else " " ) )
@bot.message_handler ( commands = [ ' admin ' ] )
def set_admin ( message ) :
forum = message . chat . id
chat = get_chat ( message )
if chat is not None :
if antispam ( message , chat , forum ) :
return
if check_if_admin ( message ) :
admin = [ i for i in message . text . split ( ) if i [ 0 ] == ' @ ' ]
if len ( admin ) == 0 :
uid = read_db ( str ( forum ) + " .settings.admin.id " )
if uid == message . from_user . id :
bot . reply_to ( chat , " Ты уже тут главный " )
return
write_db ( str ( forum ) + " .settings.admin.id " , message . from_user . id )
write_db ( str ( forum ) + " .settings.admin.username " , message . from_user . username )
if read_db ( str ( forum ) + " .settings.delete_messages " ) :
bot . delete_message ( forum , message . id )
bot . reply_to ( chat ,
" Рад познакомиться, " + message . from_user . first_name + " \\ ! " )
else :
admin = admin [ 0 ] [ 1 : ]
uadmin = read_db ( str ( forum ) + " .settings.admin.username " )
if uadmin == admin :
bot . reply_to ( chat , " Ты уже тут главный " )
return
write_db ( str ( forum ) + " .settings.admin.id " , None )
write_db ( str ( forum ) + " .settings.admin.username " , admin )
if read_db ( str ( forum ) + " .settings.delete_messages " ) :
bot . delete_message ( forum , message . id )
bot . reply_to ( chat ,
" Теперь @ " + telebot . formatting . escape_markdown ( admin ) + " тут царь и б о г \\ ! \n "
+ " Напиши /admin в чат, чтобы я знал тебя в лицо " )
@bot.message_handler ( commands = [ ' list ' ] )
def list_users ( message ) :
forum = message . chat . id
chat = get_chat ( message )
if chat is not None :
if antispam ( message , chat , forum ) :
return
if check_if_admin ( message ) :
s = message . text . split ( ) [ 1 : ]
if len ( s ) == 0 :
s = [ ' ' ]
r = [ ]
for i in s :
f = find_uids ( forum , i )
if f is not None :
r + = f
if len ( r ) == 0 :
bot . reply_to ( chat , " Никого не нашёл " )
return
if read_db ( str ( forum ) + " .settings.delete_messages " ) :
bot . delete_message ( forum , message . id )
res = [ ]
for i in r :
res . append ( format_user_info ( forum , i ) )
bot . reply_to ( chat , ' \n ' . join ( res ) )
@bot.message_handler ( commands = [ ' remind ' ] )
def remind_users ( message ) :
auto = False
if type ( message ) is int :
auto = True
forum = message
else :
forum = message . chat . id
chat = get_chat ( message )
if chat is not None :
if not auto and antispam ( message , chat , forum ) :
return
if auto or check_if_admin ( message ) :
pending = read_db ( str ( forum ) + " .pending " , { } )
r = " "
if len ( pending . keys ( ) ) == 0 :
if not auto and read_db ( str ( forum ) + " .settings.delete_messages " ) :
bot . delete_message ( forum , message . id )
else :
for i in pending . keys ( ) :
r + = " @ " + telebot . formatting . escape_markdown ( i ) + " "
r + = " нужно нажать /new \n "
status = get_status ( forum )
if status :
current = read_db ( str ( forum ) + " .rookies.current " )
if current is not None :
rookie = read_db ( str ( forum ) + " .people. " + current )
if rookie is not None :
r + = mention ( forum , current ) + " сегодня дежурит "
if not auto and read_db ( str ( forum ) + " .settings.delete_messages " ) :
bot . delete_message ( forum , message . id )
if r == " " :
if not auto :
bot . reply_to ( chat , " Дежурств сегодня нет " )
else :
bot . reply_to ( chat , r )
@bot.message_handler ( commands = [ ' del ' ] )
def del_person ( message ) :
forum = message . chat . id
chat = get_chat ( message )
if chat is not None :
if antispam ( message , chat , forum ) :
return
if check_if_admin ( message ) :
args = message . text . split ( ) [ 1 : ]
if len ( args ) < 1 :
bot . reply_to ( chat , " Давай хоть кого \\ -нибудь удалим " )
return
if len ( args ) > 1 :
bot . reply_to ( chat , " Давай удалять их по очереди " )
return
user = args [ 0 ]
if user [ 1 : ] == bot . get_me ( ) . username :
if read_db ( str ( forum ) + " .settings.delete_messages " ) :
bot . delete_message ( forum , message . id )
bot . reply_to ( chat , " Ты сейчас быканул \\ ? " )
return
f = find_uids ( forum , user )
if f is None :
bot . reply_to ( chat , " Никого не нашёл " )
return
if len ( f ) > 1 :
bot . reply_to ( chat , " Немогу определиться… " )
list_users ( message )
bot . reply_to ( chat , " Конкретезируй плиз " )
return
if read_db ( str ( forum ) + " .settings.delete_messages " ) :
bot . delete_message ( forum , message . id )
bot . reply_to ( chat , " Скатертью дорога, " + mention ( forum , f [ 0 ] ) + " \\ ! " )
pop_db ( str ( forum ) + " .people. " + f [ 0 ] )
@bot.message_handler ( commands = [ ' cleaner ' ] )
def cleaner ( message ) :
forum = message . chat . id
chat = get_chat ( message )
if chat is not None :
if antispam ( message , chat , forum ) :
return
if check_if_admin ( message ) :
args = message . text . split ( ) [ 1 : ]
if len ( args ) != 1 :
bot . reply_to ( chat , " Нужно указать `0` или `1` " )
return
if args [ 0 ] not in ( ' 0 ' , ' 1 ' ) :
bot . reply_to ( chat , " Нужно указать `0` или `1` " )
return
state = ( args [ 0 ] == ' 1 ' )
write_db ( str ( forum ) + " .settings.delete_messages " , state )
if state :
bot . delete_message ( forum , message . id )
bot . reply_to ( chat , " Очистка команд " + ( " включена " if state else " отключена " ) + (
" \n Чтобы чистка работала, мне нужно дать право удалять сообщения " if state else " " ) )
@bot.message_handler ( commands = [ ' new ' ] )
def add_new ( message ) :
forum = message . chat . id
chat = get_chat ( message )
if chat is not None :
args = message . text . split ( ) [ 1 : ]
if len ( args ) == 0 :
pending = read_db ( str ( forum ) + " .pending " )
if pending is None :
antispam ( message , chat , forum )
return
user = message . from_user . username
if user not in pending . keys ( ) :
antispam ( message , chat , forum )
return
uid = str ( message . from_user . id )
write_db ( str ( forum ) + " .people. " + uid + " .username " , user )
write_db ( str ( forum ) + " .people. " + uid + " .name " , pending [ user ] [ " name " ] )
write_db ( str ( forum ) + " .people. " + uid + " .surname " , pending [ user ] [ " surname " ] )
if read_db ( str ( forum ) + " .settings.delete_messages " ) :
bot . delete_message ( forum , message . id )
bot . reply_to ( chat ,
" Рад познакомиться, " + mention ( forum , uid ) + " \\ ! " )
pop_db ( str ( forum ) + " .pending. " + user )
elif check_if_admin ( message ) :
if len ( args ) != 3 :
bot . reply_to ( chat , " Нужно указать @, имя и фамилию \n Н е больше, не меньше" )
return
user = args [ 0 ]
if user [ 0 ] != ' @ ' :
bot . reply_to ( chat , " Пользователей нужно помянуть через `@` " )
return
user = user [ 1 : ]
if user == bot . get_me ( ) . username :
if read_db ( str ( forum ) + " .settings.delete_messages " ) :
bot . delete_message ( forum , message . id )
bot . reply_to ( chat , " Я тебе не салага \\ ! " )
return
people = read_db ( str ( forum ) + " .people " , [ ] )
pending = read_db ( str ( forum ) + " .pending " , { } )
if any ( [ people [ i ] [ " username " ] == user for i in people ]
+ [ user in pending . keys ( ) ] ) :
bot . reply_to ( chat , " Пользователь с таким ником уже в базе " )
return
name = args [ 1 ]
surname = args [ 2 ]
write_db ( str ( forum ) + " .pending. " + user + " .name " , name )
write_db ( str ( forum ) + " .pending. " + user + " .surname " , surname )
if read_db ( str ( forum ) + " .settings.delete_messages " ) :
bot . delete_message ( forum , message . id )
bot . reply_to ( chat ,
" Добро пожаловать, @ " + telebot . formatting . escape_markdown ( user )
+ " \\ ( " + name + " " + surname + " \\ ) \\ ! \n "
+ " Первое твоё обязательство — написать /new " )
@bot.message_handler ( commands = [ ' readd ' ] )
def readd ( message ) :
forum = message . chat . id
chat = get_chat ( message )
if chat is not None :
if antispam ( message , chat , forum ) :
return
if check_if_admin ( message ) :
args = message . text . split ( ) [ 1 : ]
if len ( args ) != 2 :
bot . reply_to ( chat , " Нужно указать id и новый ник \n Н е больше, не меньше" )
return
uid = args [ 0 ]
try :
int ( uid )
except :
bot . reply_to ( chat , " ID — это число \n Н а буквах пока считать не научились" )
return
if read_db ( str ( forum ) + " .people. " + uid ) is None :
bot . reply_to ( chat , " Такого пользователя нет в базе " )
return
user = args [ 1 ]
if user [ 0 ] != ' @ ' :
bot . reply_to ( chat , " Пользователей нужно помянуть через `@` " )
return
user = user [ 1 : ]
if user == bot . get_me ( ) . username :
bot . reply_to ( chat , " Я тебе не салага \\ ! " )
return
write_db ( str ( forum ) + " .people. " + uid + " .username " , user )
if read_db ( str ( forum ) + " .settings.delete_messages " ) :
bot . delete_message ( forum , message . id )
bot . reply_to ( chat , " @ " + telebot . formatting . escape_markdown ( user ) + " от меня не скроется \\ ! " )
@bot.message_handler ( commands = [ ' days ' ] )
def days ( message ) :
forum = message . chat . id
chat = get_chat ( message )
if chat is not None :
if antispam ( message , chat , forum ) :
return
if check_if_admin ( message ) :
args = message . text . split ( ) [ 1 : ]
if len ( args ) != 2 :
bot . reply_to ( chat , " Мне нужно два двоичных числа " )
return
num1 = args [ 0 ]
num2 = args [ 1 ]
if len ( num1 ) != 6 :
bot . reply_to ( chat , " В первом числе не 6 цифр" )
return
if len ( num2 ) != 6 :
bot . reply_to ( chat , " В о втором числе не 6 цифр" )
return
if not all ( [ i == ' 0 ' or i == ' 1 ' for i in num1 ] ) :
bot . reply_to ( chat , " Цифры двоичные должны быть в первом " )
return
if not all ( [ i == ' 0 ' or i == ' 1 ' for i in num2 ] ) :
bot . reply_to ( chat , " Цифры двоичные должны быть во втором " )
return
write_db ( str ( forum ) + " .schedule.days " , ( [ True if num1 [ i ] == ' 1 ' else False for i in range ( 6 ) ] ,
[ True if num2 [ i ] == ' 1 ' else False for i in range ( 6 ) ] ) )
message . text = " "
calendar ( message )
@bot.message_handler ( commands = [ ' calendar ' ] )
def calendar ( message ) :
forum = message . chat . id
chat = get_chat ( message )
if chat is not None :
if antispam ( message , chat , forum ) :
return
args = message . text . split ( ) [ 1 : ]
if len ( args ) > 1 :
bot . reply_to ( chat , " Многа букав " )
return
en1 , en2 = False , False
if len ( args ) == 1 :
en1 = args [ 0 ] . lower ( ) in " числитель "
en2 = args [ 0 ] . lower ( ) in " знаменатель "
if en1 == en2 == False :
en1 , en2 = True , True
days = read_db ( str ( forum ) + " .schedule.days " , ( [ False ] * 6 , [ False ] * 6 ) )
skip = read_db ( str ( forum ) + " .schedule.skip_days " , [ ] )
work = read_db ( str ( forum ) + " .schedule.work_days " , [ ] )
if read_db ( str ( forum ) + " .settings.delete_messages " ) :
bot . delete_message ( forum , message . id )
bot . reply_to ( chat ,
" ` \\ |# \\ |Пн \\ |Вт \\ |С р \\ |Чт \\ |Пт \\ |С б \\ | \n "
+ ( " Ч " + ' ' . join ( [ " " + ( " X " if days [ 0 ] [ i ] else " " ) + " " for i in range ( 6 ) ] ) + ' \n ' if en1 else " " )
+ ( " З " + ' ' . join ( [ " " + ( " X " if days [ 1 ] [ i ] else " " ) + " " for i in range ( 6 ) ] ) if en2 else " " )
+ ' ` '
+ ' \n \n '
+ " *Пропуски:* \n " + telebot . formatting . escape_markdown (
" \n " . join ( [ ' . ' . join ( map ( str , ( d . day , d . month , d . year ) ) ) for d in skip ] ) )
+ ' \n \n '
+ " *Рабочие:* \n " + telebot . formatting . escape_markdown (
" \n " . join ( [ ' . ' . join ( map ( str , ( d . day , d . month , d . year ) ) ) for d in work ] ) ) )
2023-12-04 14:21:21 +01:00
def parse_dates ( forum : int , args ) :
2023-10-27 15:31:53 +02:00
dates = [ ]
OK = True
for a in args :
2023-12-06 07:54:35 +01:00
if a . lower ( ) == " сегодня " :
dates . append ( get_time ( forum ) . date ( ) )
continue
if a . lower ( ) == " завтра " :
dates . append ( get_time ( forum ) . date ( ) + dt . timedelta ( days = 1 ) )
continue
if a . lower ( ) == " послезавтра " :
dates . append ( get_time ( forum ) . date ( ) + dt . timedelta ( days = 2 ) )
continue
if a . lower ( ) == " вчера " :
dates . append ( get_time ( forum ) . date ( ) - dt . timedelta ( days = 1 ) )
continue
if a . lower ( ) == " позавчера " :
dates . append ( get_time ( forum ) . date ( ) - dt . timedelta ( days = 2 ) )
continue
2023-10-27 15:31:53 +02:00
d = a . split ( ' . ' )
a_dates = [ ]
if len ( d ) in ( 2 , 3 ) :
try :
d = list ( map ( int , d ) )
except :
print ( " Ne ok " )
OK = False
if OK :
2023-10-31 10:23:14 +01:00
cur_date = get_time ( forum ) . date ( ) - dt . timedelta ( days = 1 )
2023-10-27 15:31:53 +02:00
cur_year = cur_date . year
if len ( d ) == 2 :
years = [ cur_year , cur_year + 1 ]
else :
years = [ ( cur_year / / 100 * 100 ) + d [ 2 ] if ( d [ 2 ] < 100 ) else d [ 2 ] ]
for y in years :
try :
a_dates . append ( dt . datetime ( y , d [ 1 ] , d [ 0 ] ) . date ( ) )
except :
pass
a_dates = sorted ( filter ( lambda x : cur_date + dt . timedelta ( days = 120 ) > x > cur_date , a_dates ) )
if len ( a_dates ) == 0 :
OK = False
else :
OK = False
if OK :
dates . append ( a_dates [ 0 ] )
else :
return a
return dates
def mod_days ( message , target , neighbour ) :
forum = message . chat . id
chat = get_chat ( message )
if chat is not None :
if antispam ( message , chat , forum ) :
return
if check_if_admin ( message ) :
args = message . text . split ( ) [ 1 : ]
if len ( args ) == 0 :
2023-10-31 10:23:14 +01:00
dates = [ get_time ( forum ) . date ( ) ]
2023-10-27 15:31:53 +02:00
else :
2023-12-04 14:21:21 +01:00
dates = parse_dates ( forum , args )
2023-10-27 15:31:53 +02:00
if type ( dates ) is str :
bot . reply_to ( chat , telebot . formatting . escape_markdown ( dates )
+ " — это точно дата из ближайшего будущего? " )
return
if dates is None :
bot . reply_to ( chat , " Нечего добавлять " )
return
t = read_db ( target )
if t is None :
t = [ ]
n = read_db ( neighbour )
if n is None :
n = [ ]
write_db ( neighbour , list ( filter ( lambda x : x not in dates , n ) ) )
write_db ( target , list ( sorted ( set ( t + dates ) ) ) )
if read_db ( str ( forum ) + " .settings.delete_messages " ) :
bot . delete_message ( forum , message . id )
bot . reply_to ( chat ,
" Добавил " + telebot . formatting . escape_markdown (
" , " . join ( [ ' . ' . join ( map ( str , ( d . day , d . month , d . year ) ) ) for d in dates ] ) ) )
@bot.message_handler ( commands = [ ' skip ' ] )
def skip_days ( message ) :
forum = message . chat . id
mod_days ( message , str ( forum ) + " .schedule.skip_days " , str ( forum ) + " .schedule.work_days " )
@bot.message_handler ( commands = [ ' work ' ] )
def work_days ( message ) :
forum = message . chat . id
mod_days ( message , str ( forum ) + " .schedule.work_days " , str ( forum ) + " .schedule.skip_days " )
@bot.message_handler ( commands = [ ' stop ' ] )
def stop_queue ( message ) :
forum = message . chat . id
chat = get_chat ( message )
if chat is not None :
if antispam ( message , chat , forum ) :
return
if check_if_admin ( message ) :
status = read_db ( str ( forum ) + " .is_active " )
if status is None or not status :
if read_db ( str ( forum ) + " .settings.delete_messages " ) :
bot . delete_message ( forum , message . id )
bot . reply_to ( chat , " Держурство уже не идёт " )
return
status = False
write_db ( str ( forum ) + " .is_active " , status )
if read_db ( str ( forum ) + " .settings.delete_messages " ) :
bot . delete_message ( forum , message . id )
bot . reply_to ( chat , " Держурство остановлено " )
2023-12-04 10:04:07 +01:00
@bot.message_handler ( commands = [ ' honor ' ] )
def add_honor ( message ) :
forum = message . chat . id
chat = get_chat ( message )
if chat is not None :
if antispam ( message , chat , forum ) :
return
if check_if_admin ( message ) :
args = message . text . split ( ) [ 1 : ]
if len ( args ) != 1 :
bot . reply_to ( chat , " Нужно указать человека " )
return
user = args [ 0 ]
if user [ 1 : ] == bot . get_me ( ) . username :
bot . reply_to ( chat , " Рад, что всегда в почёте " )
return
f = find_uids ( forum , user )
if f is None :
bot . reply_to ( chat , " Никого не нашёл " )
return
if len ( f ) > 1 :
bot . reply_to ( chat , " Немогу определиться… " )
list_users ( message )
bot . reply_to ( chat , " Конкретезируй плиз " )
return
user = f [ 0 ]
force = read_db ( str ( forum ) + " .rookies.force_order " , [ ] )
honor = read_db ( str ( forum ) + " .rookies.honor_order " , [ ] )
2023-12-04 14:11:48 +01:00
people = read_db ( str ( forum ) + " .people " )
2023-12-04 10:04:07 +01:00
honor . append ( user )
for i in people :
if ( i in force ) and ( i in honor ) :
force . remove ( i )
honor . remove ( i )
write_db ( str ( forum ) + " .rookies.force_order " , force )
write_db ( str ( forum ) + " .rookies.honor_order " , honor )
if read_db ( str ( forum ) + " .settings.delete_messages " ) :
bot . delete_message ( forum , message . id )
2023-12-06 13:15:29 +01:00
bot . reply_to ( chat , " Вы в почёте, " + telebot . formatting . escape_markdown (
people [ user ] [ ' name ' ] + " " + people [ user ] [ ' surname ' ] ) )
2023-12-04 10:04:07 +01:00
@bot.message_handler ( commands = [ ' force ' ] )
def add_force ( message ) :
forum = message . chat . id
chat = get_chat ( message )
if chat is not None :
if antispam ( message , chat , forum ) :
return
if check_if_admin ( message ) :
args = message . text . split ( ) [ 1 : ]
if len ( args ) != 1 :
bot . reply_to ( chat , " Нужно указать человека " )
return
user = args [ 0 ]
if user [ 1 : ] == bot . get_me ( ) . username :
bot . reply_to ( chat , " Рад, что всегда в почёте " )
return
f = find_uids ( forum , user )
if f is None :
bot . reply_to ( chat , " Никого не нашёл " )
return
if len ( f ) > 1 :
bot . reply_to ( chat , " Немогу определиться… " )
list_users ( message )
bot . reply_to ( chat , " Конкретезируй плиз " )
return
user = f [ 0 ]
force = read_db ( str ( forum ) + " .rookies.force_order " , [ ] )
honor = read_db ( str ( forum ) + " .rookies.honor_order " , [ ] )
2023-12-04 14:11:48 +01:00
people = read_db ( str ( forum ) + " .people " )
2023-12-04 10:04:07 +01:00
force . append ( user )
for i in people :
if ( i in force ) and ( i in honor ) :
force . remove ( i )
honor . remove ( i )
write_db ( str ( forum ) + " .rookies.force_order " , force )
write_db ( str ( forum ) + " .rookies.honor_order " , honor )
if read_db ( str ( forum ) + " .settings.delete_messages " ) :
bot . delete_message ( forum , message . id )
2023-12-06 13:15:29 +01:00
bot . reply_to ( chat , " Отрабатывай, " + telebot . formatting . escape_markdown (
people [ user ] [ ' name ' ] + " " + people [ user ] [ ' surname ' ] ) )
2023-12-04 10:04:07 +01:00
@bot.message_handler ( commands = [ ' sick ' ] )
def add_sick ( message ) :
forum = message . chat . id
chat = get_chat ( message )
if chat is not None :
if antispam ( message , chat , forum ) :
return
if check_if_admin ( message ) :
args = message . text . split ( ) [ 1 : ]
if len ( args ) not in ( 1 , 2 ) :
bot . reply_to ( chat , " Нужно указать человека и дату выздоровления " )
return
user = args [ 0 ]
if user [ 1 : ] == bot . get_me ( ) . username :
if read_db ( str ( forum ) + " .settings.delete_messages " ) :
bot . delete_message ( forum , message . id )
bot . reply_to ( chat , " Ты сейчас быканул \\ ? " )
return
f = find_uids ( forum , user )
if f is None :
bot . reply_to ( chat , " Никого не нашёл " )
return
if len ( f ) > 1 :
bot . reply_to ( chat , " Немогу определиться… " )
list_users ( message )
bot . reply_to ( chat , " Конкретезируй плиз " )
return
user = f [ 0 ]
if len ( args ) > 1 :
2023-12-04 14:21:21 +01:00
dates = parse_dates ( forum , args [ 1 : ] )
2023-12-04 10:04:07 +01:00
if type ( dates ) is str :
bot . reply_to ( chat , telebot . formatting . escape_markdown ( dates )
+ " — это точно дата из ближайшего будущего? " )
return
if dates is None :
bot . reply_to ( chat , " Нечего добавлять " )
return
date = dates [ 0 ]
else :
date = get_time ( forum ) . date ( ) + dt . timedelta ( days = 30 )
sicks = read_db ( str ( forum ) + " .rookies.sick_order " , { } )
2023-12-06 13:11:59 +01:00
people = read_db ( str ( forum ) + " .people " )
2023-12-04 10:04:07 +01:00
sicks [ user ] = ( date , False )
write_db ( str ( forum ) + " .rookies.sick_order " , sicks )
if read_db ( str ( forum ) + " .settings.delete_messages " ) :
bot . delete_message ( forum , message . id )
2023-12-06 07:46:55 +01:00
bot . reply_to ( chat ,
2023-12-06 13:15:29 +01:00
telebot . formatting . escape_markdown (
people [ user ] [ ' name ' ] + " " + people [ user ] [ ' surname ' ] )
+ " болеет до " + telebot . formatting . escape_markdown (
' . ' . join ( map ( str , ( date . day , date . month , date . year ) ) ) ) )
2023-12-04 10:04:07 +01:00
2023-12-06 07:47:46 +01:00
@bot.message_handler ( commands = [ ' order ' ] )
def view_order ( message ) :
forum = message . chat . id
chat = get_chat ( message )
if chat is not None :
if antispam ( message , chat , forum ) :
return
args = message . text . split ( ) [ 1 : ]
if len ( args ) > 0 :
bot . reply_to ( chat , " Многа букав " )
return
order = read_db ( str ( forum ) + " .rookies.order " , [ ] )
force = read_db ( str ( forum ) + " .rookies.force_order " , [ ] )
honor = read_db ( str ( forum ) + " .rookies.honor_order " , [ ] )
sicks = read_db ( str ( forum ) + " .rookies.sick_order " , { } )
people = read_db ( str ( forum ) + " .people " )
if read_db ( str ( forum ) + " .settings.delete_messages " ) :
bot . delete_message ( forum , message . id )
bot . reply_to ( chat ,
" *Очередь:* \n " + telebot . formatting . escape_markdown (
" \n " . join ( [ people [ u ] [ " surname " ] + " " + people [ u ] [ " name " ] for u in order ] ) )
+ ' \n \n '
+ " *Почитаемые:* \n " + telebot . formatting . escape_markdown (
" \n " . join ( [ people [ u ] [ " surname " ] + " " + people [ u ] [ " name " ] for u in honor ] ) )
2023-12-06 21:04:41 +01:00
+ ' \n '
2023-12-06 07:47:46 +01:00
+ " *Виноватые:* \n " + telebot . formatting . escape_markdown (
" \n " . join ( [ people [ u ] [ " surname " ] + " " + people [ u ] [ " name " ] for u in force ] ) )
2023-12-06 21:04:41 +01:00
+ ' \n '
2023-12-06 07:47:46 +01:00
+ " *Больные:* \n " + telebot . formatting . escape_markdown (
" \n " . join ( [ people [ u ] [ " surname " ] + " " + people [ u ] [ " name " ]
+ " до " + ' . ' . join ( map ( str ,
( sicks [ u ] [ 0 ] . day , sicks [ u ] [ 0 ] . month , sicks [ u ] [ 0 ] . year ) ) )
2023-12-06 21:04:41 +01:00
for u in sicks ] ) ) )
2023-12-06 07:47:46 +01:00
2023-10-27 15:31:53 +02:00
@bot.message_handler ( commands = [ ' begin ' ] )
def begin_queue ( message ) :
forum = message . chat . id
chat = get_chat ( message )
if chat is not None :
if antispam ( message , chat , forum ) :
return
if check_if_admin ( message ) :
args = message . text . split ( ) [ 1 : ]
if len ( args ) > 1 :
bot . reply_to ( chat , " Нужно указать человека, с которого начнётся дежурство " )
return
if len ( args ) == 1 :
user = args [ 0 ]
if user [ 1 : ] == bot . get_me ( ) . username :
if read_db ( str ( forum ) + " .settings.delete_messages " ) :
bot . delete_message ( forum , message . id )
bot . reply_to ( chat , " Ты сейчас быканул \\ ? " )
return
f = find_uids ( forum , user )
if f is None :
bot . reply_to ( chat , " Никого не нашёл " )
return
if len ( f ) > 1 :
bot . reply_to ( chat , " Немогу определиться… " )
list_users ( message )
bot . reply_to ( chat , " Конкретезируй плиз " )
return
start_with = f [ 0 ]
else :
2023-10-28 21:05:45 +02:00
start_with = None
2023-10-27 15:31:53 +02:00
phase = read_db ( str ( forum ) + " .schedule.phase " )
if phase is None :
bot . reply_to ( chat , " Задай фазу с помощью /phase " )
return
status = read_db ( str ( forum ) + " .is_active " )
if status :
if read_db ( str ( forum ) + " .settings.delete_messages " ) :
bot . delete_message ( forum , message . id )
bot . reply_to ( chat , " Держурство уже идёт " )
return
status = True
write_db ( str ( forum ) + " .is_active " , status )
stack_update ( forum , start_with )
2023-10-31 10:23:14 +01:00
now_date = get_time ( forum ) . date ( )
2023-10-29 09:28:01 +01:00
start_with = read_db ( str ( forum ) + " .rookies.order " , [ None ] ) [ 0 ]
if start_with is None :
bot . reply_to ( chat , " Людей нет " )
return
2023-10-27 15:31:53 +02:00
write_db ( str ( forum ) + " .schedule.last_stack_update_date " , now_date )
write_db ( str ( forum ) + " .schedule.last_notification_date " , now_date )
if read_db ( str ( forum ) + " .settings.delete_messages " ) :
bot . delete_message ( forum , message . id )
bot . reply_to ( chat ,
" Держурство начнёт "
+ read_db ( str ( forum ) + " .people. " + start_with + " .name " ) + " "
+ read_db ( str ( forum ) + " .people. " + start_with + " .surname " ) + " " )
@bot.message_handler ( commands = [ ' phase ' ] )
def phase ( message ) :
forum = message . chat . id
chat = get_chat ( message )
if chat is not None :
if antispam ( message , chat , forum ) :
return
if check_if_admin ( message ) :
args = message . text . split ( ) [ 1 : ]
if len ( args ) > 1 :
bot . reply_to ( chat , " Многа букав " )
return
2023-10-28 21:00:58 +02:00
else :
en2 = False
2023-10-29 09:25:19 +01:00
if len ( args ) == 1 :
2023-10-28 21:00:58 +02:00
en1 = args [ 0 ] . lower ( ) in " числитель "
en2 = args [ 0 ] . lower ( ) in " знаменатель "
if en1 == en2 :
bot . reply_to ( chat , " Это числитель или знаменатель? " )
return
2023-10-31 10:23:14 +01:00
now = get_time ( forum ) . date ( )
2023-10-27 15:31:53 +02:00
phase = int ( bool ( en2 ) )
phases = 2
write_db ( str ( forum ) + " .schedule.phase " , phase )
write_db ( str ( forum ) + " .schedule.phases " , phases )
write_db ( str ( forum ) + " .schedule.last_phase_changing_date " , now )
phase = read_db ( str ( forum ) + " .schedule.phase " , 0 )
phases = read_db ( str ( forum ) + " .schedule.phase " , 2 )
if read_db ( str ( forum ) + " .settings.delete_messages " ) :
bot . delete_message ( forum , message . id )
bot . reply_to ( chat ,
" Текущая неделя: " + ( " знаменатель " if phase else " числитель " ) )
@bot.message_handler ( commands = [ ' timezone ' , ' tz ' ] )
def set_timezone ( message ) :
forum = message . chat . id
chat = get_chat ( message )
if chat is not None :
if antispam ( message , chat , forum ) :
return
if check_if_admin ( message ) :
args = message . text . split ( ) [ 1 : ]
if len ( args ) > 1 :
bot . reply_to ( chat , " Многа букав " )
return
if len ( args ) == 1 :
try :
args [ 0 ] = args [ 0 ] . lower ( )
if " utc " in args [ 0 ] :
args [ 0 ] = args [ 0 ] [ 3 : ]
tz = int ( args [ 0 ] )
if tz not in range ( - 12 , 14 + 1 ) :
raise ValueError
except ValueError :
bot . reply_to ( chat , " Нужно указать [смещение по UTC](https://ru.wikipedia.org/wiki/ % D0 %92% D1 %81% D0 % B5 % D0 % BC % D0 % B8 % D1 %80% D0 % BD % D0 % BE % D0 % B5_ % D0 % BA % D0 % BE % D0 % BE % D1 %80% D0 % B4 % D0 % B8 % D0 % BD % D0 % B8 % D1 %80% D0 % BE % D0 % B2 % D0 % B0 % D0 % BD % D0 % BD % D0 % BE % D0 % B5_ % D0 % B2 % D1 %80% D0 % B5 % D0 % BC % D1 %8F ) " )
return
write_db ( str ( forum ) + " .settings.timezone " , tz )
tz = read_db ( str ( forum ) + " .settings.timezone " , 3 )
if read_db ( str ( forum ) + " .settings.delete_messages " ) :
bot . delete_message ( forum , message . id )
bot . reply_to ( chat ,
" Часовой пояс: UTC " + ( " \\ + " if tz > = 0 else " " ) +
telebot . formatting . escape_markdown ( str ( tz ) ) )
def get_hours ( forum : int ) - > list :
utc_range = ( 8 , 20 )
2023-10-31 10:23:14 +01:00
return utc_range
# Obsoleted by `get_time`
# tz = read_db(str(forum) + ".settings.timezone", 3)
# utc_range = tuple(map(lambda x: (x - tz) % 24, utc_range))
# if utc_range[0] > utc_range[1]:
# return list(range(utc_range[0], 24)) + list(range(0, utc_range[1]))
# else:
# return list(range(utc_range[0], utc_range[1]))
2023-10-27 15:31:53 +02:00
def stack_update ( forum : int , force_reset = False ) :
2023-12-04 10:04:07 +01:00
now = get_time ( forum )
now_date = now . date ( )
2023-10-27 15:31:53 +02:00
order = read_db ( str ( forum ) + " .rookies.order " , [ ] )
force = read_db ( str ( forum ) + " .rookies.force_order " , [ ] )
honor = read_db ( str ( forum ) + " .rookies.honor_order " , [ ] )
2023-12-04 10:04:07 +01:00
sicks = read_db ( str ( forum ) + " .rookies.sick_order " , { } )
2023-10-27 15:31:53 +02:00
people = read_db ( str ( forum ) + " .people " , { } )
2023-12-04 10:04:07 +01:00
for i in sicks :
if now_date > = sicks [ i ] [ 0 ] :
if sicks [ i ] [ 1 ] :
prepend_user ( forum , " .rookies.force_order " , i )
sicks . pop ( i )
write_db ( str ( forum ) + " .rookies.sick_order " , sicks )
for i in people :
if ( i in force ) and ( i in honor ) :
force . remove ( i )
honor . remove ( i )
write_db ( str ( forum ) + " .rookies.force_order " , force )
write_db ( str ( forum ) + " .rookies.honor_order " , honor )
2023-10-27 15:31:53 +02:00
for i in order :
if i not in people . keys ( ) :
order . remove ( i )
if len ( order ) == 0 or force_reset != False :
order = list ( dict ( sorted ( people . items ( ) , key = lambda item : item [ 1 ] [ " surname " ] ) ) . keys ( ) )
2023-12-04 10:04:07 +01:00
if force_reset != False :
write_db ( str ( forum ) + " .rookies.force_order " , [ ] )
write_db ( str ( forum ) + " .rookies.honor_order " , [ ] )
write_db ( str ( forum ) + " .rookies.sick_order " , { } )
2023-10-27 15:31:53 +02:00
if force_reset is not None :
try :
order = order [ order . index ( force_reset ) : ]
except :
pass
2023-12-04 10:04:07 +01:00
write_db ( str ( forum ) + " .rookies.order " , order )
2023-10-27 15:31:53 +02:00
if len ( order ) == 0 :
return
2023-10-29 09:28:01 +01:00
if force_reset == False :
2023-12-04 10:04:07 +01:00
if len ( force ) > 0 :
write_db ( str ( forum ) + " .rookies.current " , pop_user ( forum , " rookies.force_order " ) )
else :
current = pop_user ( forum , " rookies.order " )
if current in honor :
honor . remove ( current )
write_db ( str ( forum ) + " .rookies.honor_order " , honor )
stack_update ( forum )
elif any ( [ ( sicks [ i ] [ 1 ] == False ) and ( i == current ) for i in sicks ] ) :
skipped = list ( sicks [ current ] )
skipped [ 1 ] = True
sicks [ current ] = tuple ( skipped )
write_db ( str ( forum ) + " .rookies.sick_order " , sicks )
stack_update ( forum )
else :
write_db ( str ( forum ) + " .rookies.current " , pop_user ( forum , " rookies.order " ) )
2023-10-27 15:31:53 +02:00
2023-11-01 07:15:28 +01:00
def clean_old_dates ( date , array : str ) :
a = read_db ( array )
for i in range ( len ( a ) ) :
if a [ i ] < date :
a [ i ] = None
a = [ i for i in a if i is not None ]
write_db ( array , a )
2023-10-27 15:31:53 +02:00
def update ( forum : int ) :
2023-10-31 10:23:14 +01:00
now = get_time ( forum )
2023-10-27 15:31:53 +02:00
now_date = now . date ( )
now_time = now . time ( )
last_notif = read_db ( str ( forum ) + " .schedule.last_notification_date " )
last_upd_stack = read_db ( str ( forum ) + " .schedule.last_stack_update_date " )
is_active = get_status ( forum , now_date )
hours_range = get_hours ( forum )
change_phase ( forum , now_date )
2023-11-01 07:15:28 +01:00
clean_old_dates ( now_date , str ( forum ) + " .schedule.work_days " )
clean_old_dates ( now_date , str ( forum ) + " .schedule.skip_days " )
2023-10-27 15:31:53 +02:00
if is_active and ( last_upd_stack is None or now_date > last_upd_stack ) :
write_db ( str ( forum ) + " .schedule.last_stack_update_date " , now_date )
stack_update ( forum )
print ( now_time . hour , hours_range )
if now_time . hour in hours_range :
if last_notif is None or now_date > last_notif :
print ( " Notified " )
write_db ( str ( forum ) + " .schedule.last_notification_date " , now_date )
remind_users ( forum )
def process1 ( ) :
bot . infinity_polling ( none_stop = True )
def process2 ( ) :
period = 120
prev_time = time . time ( ) - period
while True :
cur_time = time . time ( )
if cur_time - prev_time > = period :
prev_time = cur_time
stdout . write ( " Update \n " )
for i in db . keys ( ) :
try :
update ( int ( i ) )
except ValueError :
pass
funcs = [ process1 , process2 ]
threads = map ( lambda x : Thread ( target = x ) , funcs )
for i in threads :
i . daemon = True
i . start ( )
while True :
time . sleep ( 1 )