Skip to content

Commit 6ed763c

Browse files
committed
Add meal scheduling functionality and improve slot management
- Introduced meal time definitions in the scheduling process. - Updated the slot creation logic to accommodate meal types. - Enhanced the display of scheduled slots to differentiate between meals and projects. - Modified database export to exclude meal slots from project optimization.
1 parent c1b17df commit 6ed763c

3 files changed

Lines changed: 324 additions & 248 deletions

File tree

src/pycamp_bot/commands/schedule.py

Lines changed: 89 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,29 @@
88

99

1010
DAY_SLOT_TIME = {
11-
'day':[], # Guarda el codigo del dia ej: ['A','B']
12-
'slot':[], # Guarda la cantidad de slots del dia iterado ej [5] (se sobreescribe)
13-
'time':[], # Guarda la hora a la que empieza el dia iterado [15] (se sobreescribe)
11+
'day': [], # Guarda el codigo del dia ej: ['A','B']
12+
'slot': [], # Guarda la cantidad de slots del dia iterado ej [5] (se sobreescribe)
13+
'time': [], # Guarda la hora a la que empieza el dia iterado [15] (se sobreescribe)
14+
'meals': [] # Guarda los horarios de las comidas (strings, hora entera)
1415
}
1516

17+
COMIDAS = ['Desayuno', 'Almuerzo', 'Merienda', 'Cena']
18+
19+
20+
def _slots_ordered_query():
21+
"""Orden A1…A9,A10 sin orden lexicográfico incorrecto."""
22+
return sorted(
23+
Slot.select(),
24+
key=lambda s: (s.code[0], int(s.code[1:])) if len(s.code) > 1 else (s.code[0], 0),
25+
)
26+
1627

1728
async def cancel(update, context):
1829
await context.bot.send_message(
1930
chat_id=update.message.chat_id,
2031
text="Has cancelado la carga de slots")
2132
return ConversationHandler.END
2233

23-
2434
@admin_needed
2535
async def define_slot_days(update, context):
2636
# TODO: filtrar proyectos por pycamp activo.
@@ -52,7 +62,7 @@ async def define_slot_days(update, context):
5262
return 1
5363

5464

55-
async def define_slot_ammount(update, context):
65+
async def define_meal_times(update, context):
5666
global DAY_SLOT_TIME
5767
text = update.message.text
5868
if text not in ["1", "2", "3", "4", "5", "6", "7"]:
@@ -61,26 +71,42 @@ async def define_slot_ammount(update, context):
6171
text="mmm eso no parece un numero de dias razonable, de nuevo?"
6272
)
6373
return 1
74+
DAY_SLOT_TIME['day'] = list(string.ascii_uppercase[0:int(text)])
75+
await context.bot.send_message(
76+
chat_id=update.message.chat_id,
77+
text="Ingresa los horarios de comidas\nEj: 9, 13, 17, 21")
78+
return 2
6479

65-
66-
DAY_SLOT_TIME['day'] =list(string.ascii_uppercase[0:int(text)])
6780

81+
async def define_slot_ammount(update, context):
82+
global DAY_SLOT_TIME
83+
raw = [item.strip() for item in update.message.text.split(',') if item.strip()]
84+
try:
85+
DAY_SLOT_TIME['meals'] = [str(int(h)) for h in raw]
86+
except ValueError:
87+
await context.bot.send_message(
88+
chat_id=update.message.chat_id,
89+
text="Cada horario debe ser un número entero, ej: 9, 13, 17, 21",
90+
)
91+
return 2
92+
day_name = get_slot_weekday_name(DAY_SLOT_TIME['day'][0])
6893
await context.bot.send_message(
6994
chat_id=update.message.chat_id,
70-
text="Cuantos slots tiene tu dia {}".format(DAY_SLOT_TIME['day'][0])
95+
text="Cuantos slots tiene tu dia {}?".format(day_name)
7196
)
72-
return 2
97+
return 3
7398

7499

75100
async def define_slot_times(update, context):
76101
text = update.message.text
77-
day = DAY_SLOT_TIME['day'][0]
102+
103+
day_name = get_slot_weekday_name(DAY_SLOT_TIME['day'][0])
78104
await context.bot.send_message(
79105
chat_id=update.message.chat_id,
80-
text="A que hora empieza tu dia {}".format(day)
106+
text="A que hora empieza tu dia {}?".format(day_name)
81107
)
82108
DAY_SLOT_TIME['slot'] = [text]
83-
return 3
109+
return 4
84110

85111

86112
async def create_slot(update, context):
@@ -89,29 +115,37 @@ async def create_slot(update, context):
89115
text = update.message.text
90116

91117
DAY_SLOT_TIME['time'] = [text]
92-
slot_amount = DAY_SLOT_TIME['slot'][0]
93-
times = list(range(int(slot_amount)+1))[1:]
118+
slot_amount = int(DAY_SLOT_TIME['slot'][0])
119+
times = list(range(slot_amount + 1))[1:]
94120
starting_hour = int(text)
121+
meals = DAY_SLOT_TIME['meals']
95122

96-
while len(times) > 0:
97-
new_slot = Slot(code=str(DAY_SLOT_TIME['day'][0]+str(times[0])))
98-
new_slot.start = starting_hour
123+
pycampista = Pycampista.get_or_create(username=username, chat_id=chat_id)[0]
99124

100-
pycampista = Pycampista.get_or_create(username=username, chat_id=chat_id)[0]
125+
for t in times:
126+
new_slot = Slot(code=str(DAY_SLOT_TIME['day'][0] + str(t)))
127+
new_slot.start = starting_hour
101128
new_slot.current_wizard = pycampista
102129

130+
hkey = str(starting_hour)
131+
if hkey in meals:
132+
idx = meals.index(hkey)
133+
new_slot.meal_type = COMIDAS[idx]
134+
else:
135+
new_slot.meal_type = None
136+
103137
new_slot.save()
104-
times.pop(0)
105138
starting_hour += 1
106139

107140
DAY_SLOT_TIME['day'].pop(0)
108141

109142
if len(DAY_SLOT_TIME['day']) > 0:
143+
day_name = get_slot_weekday_name(DAY_SLOT_TIME['day'][0])
110144
await context.bot.send_message(
111145
chat_id=update.message.chat_id,
112-
text="Cuantos slots tiene tu dia {}".format(DAY_SLOT_TIME['day'][0])
146+
text="Cuantos slots tiene tu dia {}?".format(day_name)
113147
)
114-
return 2
148+
return 3
115149
else:
116150
await context.bot.send_message(
117151
chat_id=update.message.chat_id,
@@ -130,9 +164,11 @@ async def make_schedule(update, context):
130164
data_json = export_db_2_json()
131165
my_schedule = export_scheduled_result(data_json)
132166

133-
for relationship in my_schedule:
134-
slot = Slot.get(Slot.code == relationship[1])
135-
project = Project.get(Project.name == relationship[0])
167+
for project_name, slot_code in my_schedule:
168+
slot = Slot.get(Slot.code == slot_code)
169+
if slot.meal_type:
170+
continue
171+
project = Project.get(Project.name == project_name)
136172
project.slot = slot.id
137173
project.save()
138174

@@ -144,7 +180,7 @@ async def make_schedule(update, context):
144180

145181
async def check_day_tab(slot, prev_slot, cronograma):
146182
def append_day_name():
147-
cronograma.append(f'*{get_slot_weekday_name(slot.code[0])}:*')
183+
cronograma.append(f'*{escape_markdown(get_slot_weekday_name(slot.code[0]))}:*')
148184

149185
if prev_slot is None:
150186
append_day_name()
@@ -154,19 +190,30 @@ def append_day_name():
154190

155191

156192
async def show_schedule(update, context):
157-
slots = Slot.select()
158-
projects = Project.select()
193+
slots = _slots_ordered_query()
194+
projects = list(Project.select())
159195
cronograma = []
160196

161197
prev_slot = None
162198

163-
for i, slot in enumerate(slots):
199+
for slot in slots:
164200
await check_day_tab(slot, prev_slot, cronograma)
165201

166-
for project in projects:
167-
if project.slot_id == slot.id:
168-
cronograma.append(f'{slot.start}:00 *{escape_markdown(project.name)}*')
169-
cronograma.append(f'Owner: @{escape_markdown(project.owner.username)}')
202+
if slot.meal_type:
203+
h = slot.start_hour_display()
204+
cronograma.append(
205+
f'*{h}:00hs* — *{escape_markdown(slot.meal_type)}*'
206+
)
207+
else:
208+
for project in projects:
209+
if project.slot_id == slot.id:
210+
h = slot.start_hour_display()
211+
cronograma.append(
212+
f'*{h}:00hs* — *{escape_markdown(project.name.capitalize())}*'
213+
)
214+
cronograma.append(
215+
f'A cargo de @{escape_markdown(project.owner.username)}'
216+
)
170217

171218
prev_slot = slot
172219

@@ -199,6 +246,12 @@ async def change_slot(update, context):
199246
if project.name == project_name:
200247
for slot in slots:
201248
if slot.code == text[-1]:
249+
if slot.meal_type:
250+
await context.bot.send_message(
251+
chat_id=update.message.chat_id,
252+
text="Ese slot está reservado para comidas; elegí otro código."
253+
)
254+
return
202255
found = True
203256
project.slot = slot.id
204257
project.save()
@@ -217,9 +270,10 @@ async def change_slot(update, context):
217270
load_schedule_handler = ConversationHandler(
218271
entry_points=[CommandHandler('cronogramear', define_slot_days)],
219272
states={
220-
1: [MessageHandler(filters.TEXT, define_slot_ammount)],
221-
2: [MessageHandler(filters.TEXT, define_slot_times)],
222-
3: [MessageHandler(filters.TEXT, create_slot)]},
273+
1: [MessageHandler(filters.TEXT, define_meal_times)],
274+
2: [MessageHandler(filters.TEXT, define_slot_ammount)],
275+
3: [MessageHandler(filters.TEXT, define_slot_times)],
276+
4: [MessageHandler(filters.TEXT, create_slot)]},
223277
fallbacks=[CommandHandler('cancel', cancel)])
224278

225279

0 commit comments

Comments
 (0)