-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathlunch_voting_bot.py
148 lines (118 loc) · 4.63 KB
/
lunch_voting_bot.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Author: Dmitry Shapovalov <dmitry@0fe.ru>
# @Date: 06-07-2017
#
# lunch voting telegram bot
from telegram.ext import Updater, CommandHandler, MessageHandler, Filters
from datetime import datetime, timedelta, time, date
import logging
import re
import os
import sys
# Enable logging
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
level=logging.INFO)
logger = logging.getLogger(__name__)
DELAY_RE = re.compile("^\s*\+\s*(\d+)")
vote_start_time = None
vote_in_progress = False
voters = {}
# secret token from BotFather
SECRET_TOKEN_ENV = os.getenv('LUNCH_VOTING_BOT_SECRET_TOKEN', "")
# chat id
CHAT_ID_ENV = os.getenv('LUNCH_VOTING_BOT_CHAT_ID', "")
CHAT_ID = 0
VOTE_BEGIN_TIME = (8,00)
LUNCH_HOUR_TIME = (12,00)
LUNCH_REMIND = 30 #minutes before lunch
LUNCH_WEEK_DAYS = (0, 1, 2, 3, 4)
MAX_DELAY = 30
VOTE_BEGIN_SILENT = True
VOTE_START_MSG = "Обед в %d:%d\nесть время подумать" % (LUNCH_HOUR_TIME[0],LUNCH_HOUR_TIME[1])
VOTE_REMIND_MSG = "Обед через %d минут" % LUNCH_REMIND
VOTE_STOP_MSG = "Кто не успел, тот опоздал...\nИтог такой:\n"
LUNCH_REMIND_TIME = (datetime.combine(date.today(),time(hour=LUNCH_HOUR_TIME[0], minute=LUNCH_HOUR_TIME[1]))-timedelta(minutes=LUNCH_REMIND)).time()
VOTE_START_TIME = time(hour=VOTE_BEGIN_TIME[0], minute=VOTE_BEGIN_TIME[1])
VOTE_STOP_TIME = time(hour=LUNCH_HOUR_TIME[0], minute=LUNCH_HOUR_TIME[1])
class Voter:
def __init__(self, decision=False, delay=0, name="Anon"):
self.decision = decision
self.delay = delay
self.name = name
def vote(voter,decision,delay=0):
if voter.id in voters:
voters[voter.id].decision = decision
voters[voter.id].delay = delay
else:
voters[voter.id] = Voter(decision=decision, delay=delay, name="%s %s" % (voter.first_name,voter.last_name))
def listen_all(bot, update):
if not vote_in_progress:
return
if update.message.chat.id != CHAT_ID:
return
if update.message.text.strip() == "-":
vote(update.message.from_user,False)
elif update.message.text.strip() == "+":
vote(update.message.from_user,True)
else:
result = DELAY_RE.match(update.message.text)
if result:
delay = result.group(1)
vote(update.message.from_user,True,int(delay))
def error(bot, update, error):
logger.warn('Update "%s" caused error "%s"' % (update, error))
def vote_start(bot, job):
global vote_in_progress
global vote_start_time
voters.clear()
vote_in_progress = True
if not VOTE_BEGIN_SILENT:
bot.send_message(chat_id=CHAT_ID,text=VOTE_START_MSG)
def vote_remind(bot, job):
bot.send_message(chat_id=CHAT_ID,text=VOTE_REMIND_MSG)
def vote_end(bot, job):
global vote_in_progress
vote_in_progress = False
voter_message = ""
for voter in voters.values():
if voter.decision:
if voter.delay > 0:
voter_message += "%s задержится на %d минут\n" % (voter.name, voter.delay)
else:
voter_message += "%s пойдет\n" % voter.name
else:
voter_message += "%s не пойдет\n" % voter.name
bot.send_message(chat_id=CHAT_ID,text=VOTE_STOP_MSG+voter_message)
def main():
global CHAT_ID
if SECRET_TOKEN_ENV == "":
sys.exit("Incorrect token")
if CHAT_ID_ENV == "":
sys.exit("Incorrect chat id")
try:
CHAT_ID = int(CHAT_ID_ENV)
except:
sys.exit("Incorrect chat id")
# Create the EventHandler and pass it your bot's token.
updater = Updater(SECRET_TOKEN_ENV)
# Get the dispatcher to register handlers
dp = updater.dispatcher
# listen all
dp.add_handler(MessageHandler(Filters.text, listen_all))
# log all errors
dp.add_error_handler(error)
updater.job_queue.run_daily(vote_start, VOTE_START_TIME, days=LUNCH_WEEK_DAYS)
updater.job_queue.run_daily(vote_remind, LUNCH_REMIND_TIME, days=LUNCH_WEEK_DAYS)
updater.job_queue.run_daily(vote_end, VOTE_STOP_TIME, days=LUNCH_WEEK_DAYS)
# if VOTE_START_TIME is passed, start vote now
if datetime.now().time() > VOTE_START_TIME and datetime.now().time() < VOTE_STOP_TIME:
updater.job_queue.run_once(vote_start, timedelta(minutes=1))
# Start the Bot
updater.start_polling()
# Run the bot until you press Ctrl-C or the process receives SIGINT,
# SIGTERM or SIGABRT. This should be used most of the time, since
# start_polling() is non-blocking and will stop the bot gracefully.
updater.idle()
if __name__ == '__main__':
main()