-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathget_resumes_conv.py
422 lines (359 loc) · 15.4 KB
/
get_resumes_conv.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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
from utils import send_single_date_resumes_to_user, return_to_menu, send_cancel_button
from config import get_resume_password, admin_ids, logger
import jdatetime
from telegram import (
Update,
InlineKeyboardButton,
InlineKeyboardMarkup,
)
from telegram.ext import (
CommandHandler,
ConversationHandler,
CallbackQueryHandler,
MessageHandler,
filters,
ContextTypes,
)
from buttons import (
inline_back_button,
SPECIALIZATION_BUTTONS,
DEPARTMENT_BUTTONS,
)
(
PASSWORD,
DEPARTMENT_OR_SPECIALIZATION,
DEPARTMENT,
SPECIALIZATION,
DATE_OR_RANGE,
YEAR,
MONTH,
DAY,
START_YEAR,
START_MONTH,
START_DAY,
END_YEAR,
END_MONTH,
END_DAY,
) = range(14)
def get_reply_markup(
state: int, context: ContextTypes.DEFAULT_TYPE
) -> InlineKeyboardMarkup:
year_buttons = [
[InlineKeyboardButton(f"{i}", callback_data=f"year-{i}")]
for i in range(1400, 1405)
] + [inline_back_button]
month_buttons = [
[InlineKeyboardButton(f"{i}", callback_data=f"month-{i}") for i in range(1, 4)],
[InlineKeyboardButton(f"{i}", callback_data=f"month-{i}") for i in range(4, 7)],
[
InlineKeyboardButton(f"{i}", callback_data=f"month-{i}")
for i in range(7, 10)
],
[
InlineKeyboardButton(f"{i}", callback_data=f"month-{i}")
for i in range(10, 13)
],
] + [inline_back_button]
day_buttons = [
[InlineKeyboardButton(f"{i}", callback_data=f"day-{i}") for i in range(1, 5)],
[InlineKeyboardButton(f"{i}", callback_data=f"day-{i}") for i in range(5, 9)],
[InlineKeyboardButton(f"{i}", callback_data=f"day-{i}") for i in range(9, 13)],
[InlineKeyboardButton(f"{i}", callback_data=f"day-{i}") for i in range(13, 17)],
[InlineKeyboardButton(f"{i}", callback_data=f"day-{i}") for i in range(17, 21)],
[InlineKeyboardButton(f"{i}", callback_data=f"day-{i}") for i in range(21, 25)],
[InlineKeyboardButton(f"{i}", callback_data=f"day-{i}") for i in range(25, 29)],
[InlineKeyboardButton(f"{i}", callback_data=f"day-{i}") for i in range(29, 32)],
] + [inline_back_button]
if state == DEPARTMENT_OR_SPECIALIZATION:
buttons = [
[InlineKeyboardButton("Department 🌿", callback_data="department")],
[InlineKeyboardButton("Specialization 🛠️", callback_data="specialization")],
]
elif state == DEPARTMENT:
buttons = DEPARTMENT_BUTTONS + [inline_back_button]
elif state == SPECIALIZATION:
buttons = SPECIALIZATION_BUTTONS[context.user_data["department"]] + [
inline_back_button
]
elif state == DATE_OR_RANGE:
buttons = [
[InlineKeyboardButton("Date 📅", callback_data="date")],
[InlineKeyboardButton("Range ⏳", callback_data="range")],
] + [inline_back_button]
elif state == YEAR or state == START_YEAR or state == END_YEAR:
buttons = year_buttons
elif state == MONTH or state == START_MONTH or state == END_MONTH:
buttons = month_buttons
elif state == DAY or state == START_DAY or state == END_DAY:
buttons = day_buttons
else:
return None
markup = InlineKeyboardMarkup(buttons)
return markup
async def send_step_message(
state: int, update: Update, context: ContextTypes.DEFAULT_TYPE
):
messages = {
PASSWORD: "🔐 Please enter the password:",
DEPARTMENT_OR_SPECIALIZATION: "📝 Please select one of the options:",
DEPARTMENT: "📂 Please select one of the departments:",
SPECIALIZATION: "🔧 Please select one of the specializations:",
DATE_OR_RANGE: "⏰ Please select one of the options:",
YEAR: "📅 Please select the year:",
MONTH: "📅 Please select the month:",
DAY: "📅 Please select the day:",
START_YEAR: "📅 Please select the start year:",
START_MONTH: "📅 Please select the start month:",
START_DAY: "📅 Please select the start day:",
END_YEAR: "📅 Please select the end year:",
END_MONTH: "📅 Please select the end month:",
END_DAY: "📅 Please select the end day:",
}
markup = get_reply_markup(state, context)
if update.message:
await context.bot.send_message(
update.effective_chat.id, messages[state], reply_markup=markup
)
else:
await update.callback_query.edit_message_text(
messages[state], reply_markup=markup
)
async def get_resumes_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
await send_cancel_button(update)
await send_step_message(PASSWORD, update, context)
context.user_data["current_state"] = PASSWORD
return PASSWORD
async def password_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
await update.message.delete()
if update.message.text != get_resume_password:
await update.message.reply_text("Incorrect password.")
return PASSWORD
await update.message.reply_text("Correct password.")
await send_step_message(DEPARTMENT_OR_SPECIALIZATION, update, context)
context.user_data["current_state"] = DEPARTMENT_OR_SPECIALIZATION
return DEPARTMENT_OR_SPECIALIZATION
async def department_or_specialization_handler(
update: Update, context: ContextTypes.DEFAULT_TYPE
):
context.user_data["current_state"] = DEPARTMENT
context.user_data["department_or_specialization"] = update.callback_query.data
await update.callback_query.edit_message_text(
"You have selected: " + update.callback_query.data
)
await send_step_message(DEPARTMENT, update, context)
return DEPARTMENT
async def department_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
context.user_data["department"] = update.callback_query.data.split("_")[1]
await update.callback_query.edit_message_text(
"Selected department: " + context.user_data["department"]
)
next_step = (
SPECIALIZATION
if context.user_data["department_or_specialization"] == "specialization"
else DATE_OR_RANGE
)
context.user_data["current_state"] = next_step
await send_step_message(next_step, update, context)
return next_step
async def specialization_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
context.user_data["specialization"] = update.callback_query.data.split("-")[1]
await update.callback_query.edit_message_text(
"Selected specialization: " + context.user_data["specialization"]
)
context.user_data["current_state"] = DATE_OR_RANGE
await send_step_message(DATE_OR_RANGE, update, context)
return DATE_OR_RANGE
async def date_or_range_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
context.user_data["date_or_range"] = update.callback_query.data
next_step = YEAR if update.callback_query.data == "date" else START_YEAR
await update.callback_query.edit_message_text(
"You have selected: " + update.callback_query.data
)
context.user_data["current_state"] = next_step
await send_step_message(next_step, update, context)
return next_step
async def year_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
context.user_data["year"] = update.callback_query.data.split("-")[1]
context.user_data["current_state"] = MONTH
await update.callback_query.edit_message_text(
"Selected year: " + context.user_data["year"]
)
await send_step_message(MONTH, update, context)
return MONTH
async def month_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
context.user_data["month"] = update.callback_query.data.split("-")[1]
context.user_data["current_state"] = DAY
await update.callback_query.edit_message_text(
"Selected month: " + context.user_data["month"]
)
await send_step_message(DAY, update, context)
return DAY
async def day_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
context.user_data["day"] = update.callback_query.data.split("-")[1]
context.user_data["current_state"] = None
await update.callback_query.edit_message_text(
"Selected date: "
+ context.user_data["year"]
+ "/"
+ context.user_data["month"]
+ "/"
+ context.user_data["day"]
)
logger.info(f"Searching for resumes on {context.user_data['year']}/{context.user_data['month']}/{context.user_data['day']}")
await context.bot.send_message(update.effective_chat.id, "Resume search started.")
await send_single_date_resumes_to_user(context)
await context.bot.send_message(update.effective_chat.id, "Resume search completed.")
return await return_to_menu(context)
async def start_year_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
context.user_data["start_year"] = update.callback_query.data.split("-")[1]
context.user_data["current_state"] = START_MONTH
await update.callback_query.edit_message_text(
"Selected start year: " + context.user_data["start_year"]
)
await send_step_message(START_MONTH, update, context)
return START_MONTH
async def start_month_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
context.user_data["start_month"] = update.callback_query.data.split("-")[1]
context.user_data["current_state"] = START_DAY
await update.callback_query.edit_message_text(
"Selected start month: " + context.user_data["start_month"]
)
await send_step_message(START_DAY, update, context)
return START_DAY
async def start_day_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
context.user_data["start_day"] = update.callback_query.data.split("-")[1]
context.user_data["current_state"] = END_YEAR
await update.callback_query.edit_message_text(
"Selected start day: " + context.user_data["start_day"]
)
await send_step_message(END_YEAR, update, context)
return END_YEAR
async def end_year_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
context.user_data["end_year"] = update.callback_query.data.split("-")[1]
context.user_data["current_state"] = END_MONTH
await update.callback_query.edit_message_text(
"Selected end year: " + context.user_data["end_year"]
)
await send_step_message(END_MONTH, update, context)
return END_MONTH
async def end_month_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
context.user_data["end_month"] = update.callback_query.data.split("-")[1]
context.user_data["current_state"] = END_DAY
await update.callback_query.edit_message_text(
"Selected end month: " + context.user_data["end_month"]
)
await send_step_message(END_DAY, update, context)
return END_DAY
async def end_day_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
context.user_data["end_day"] = update.callback_query.data.split("-")[1]
context.user_data["current_state"] = None
await update.callback_query.edit_message_text(
"Selected range: "
+ context.user_data["start_year"]
+ "/"
+ context.user_data["start_month"]
+ "/"
+ context.user_data["start_day"]
+ " to "
+ context.user_data["end_year"]
+ "/"
+ context.user_data["end_month"]
+ "/"
+ context.user_data["end_day"]
)
start_date = jdatetime.date(
int(context.user_data["start_year"]),
int(context.user_data["start_month"]),
int(context.user_data["start_day"]),
)
end_date = jdatetime.date(
int(context.user_data["end_year"]),
int(context.user_data["end_month"]),
int(context.user_data["end_day"]),
)
if start_date > end_date:
await update.callback_query.edit_message_text(
"End date must be greater than start date."
)
await send_step_message(START_YEAR, update, context)
return START_DAY
current_date = start_date
logger.info(f"Searching for resumes from {start_date} to {end_date}")
await context.bot.send_message(update.effective_chat.id, "Resume search started.")
while current_date <= end_date:
context.user_data["year"] = current_date.year
context.user_data["month"] = current_date.month
context.user_data["day"] = current_date.day
await send_single_date_resumes_to_user(context)
current_date += jdatetime.timedelta(days=1)
await context.bot.send_message(update.effective_chat.id, "Resume search completed.")
return await return_to_menu(context)
async def cancel_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
await update.message.reply_text("Search canceled.")
return await return_to_menu(context)
def get_previous_state(current_state: int, context: ContextTypes.DEFAULT_TYPE) -> int:
if current_state == START_YEAR:
return DATE_OR_RANGE
elif current_state == DATE_OR_RANGE:
return (
DEPARTMENT
if context.user_data["department_or_specialization"] == "department"
else SPECIALIZATION
)
else:
return current_state - 1
async def back_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
current_state = context.user_data["current_state"]
previous_state = get_previous_state(current_state, context)
await send_step_message(previous_state, update, context)
await update.callback_query.answer("Returned to previous step 🔙")
context.user_data["current_state"] = previous_state
return previous_state
async def send_resume_results_to_user(
update: Update, context: ContextTypes.DEFAULT_TYPE
):
user_id = update.effective_message.caption.split("\n")[0]
await context.bot.send_document(
caption=update.effective_message.caption,
chat_id=user_id,
document=update.effective_message.document,
)
get_resumes_conv = ConversationHandler(
entry_points=[
MessageHandler(
filters.Text("Search Resumes") & filters.User(admin_ids),
get_resumes_command,
)
],
states={
PASSWORD: [MessageHandler(filters.TEXT & ~filters.COMMAND, password_handler)],
DEPARTMENT_OR_SPECIALIZATION: [
CallbackQueryHandler(
department_or_specialization_handler,
pattern="^department$|^specialization$",
)
],
DEPARTMENT: [
CallbackQueryHandler(department_handler, pattern="^department_.*$")
],
SPECIALIZATION: [
CallbackQueryHandler(specialization_handler, pattern="^specialization-.*$")
],
DATE_OR_RANGE: [
CallbackQueryHandler(date_or_range_handler, pattern="^date$|^range$")
],
YEAR: [CallbackQueryHandler(year_handler, pattern="^year-.*$")],
MONTH: [CallbackQueryHandler(month_handler, pattern="^month-.*$")],
DAY: [CallbackQueryHandler(day_handler, pattern="^day-.*$")],
START_YEAR: [CallbackQueryHandler(start_year_handler, pattern="^year-.*$")],
START_MONTH: [CallbackQueryHandler(start_month_handler, pattern="^month-.*$")],
START_DAY: [CallbackQueryHandler(start_day_handler, pattern="^day-.*$")],
END_YEAR: [CallbackQueryHandler(end_year_handler, pattern="^year-.*$")],
END_MONTH: [CallbackQueryHandler(end_month_handler, pattern="^month-.*$")],
END_DAY: [CallbackQueryHandler(end_day_handler, pattern="^day-.*$")],
},
fallbacks=[
CommandHandler("cancel", cancel_handler),
CallbackQueryHandler(back_handler, pattern="^back$"),
],
)