Skip to content

Commit 7ae61fc

Browse files
committed
feat: support add devices flow
1 parent ff8c930 commit 7ae61fc

File tree

7 files changed

+162
-71
lines changed

7 files changed

+162
-71
lines changed

src/app.py

+36-13
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,60 @@
11
from telegram.ext import CommandHandler, MessageHandler, filters, ConversationHandler
22

3-
from src.device.interface.device import DEVICES, PHOTO, LOCATION, BIO, skip_location, \
4-
location, photo, device, devices, skip_photo, bio
3+
from src.device.interface.device import device, done, ACTIONABLE, show_response, ADD_MAC, add_mac, SAVE_DEVICE, \
4+
save_device
55
from src.device.interface.wifi import wifi
66
from src.payment.interface.payment import payment
77
from src.shared.infrastructure.bot.connector import application
8-
from src.shared.interface.cancel import cancel_conversation
98
from src.shared.interface.messager import message_handler
109
from src.user.interface.login import account
11-
from src.shared.interface.help import help_handler
10+
from src.shared.interface.help import help_handler, start_handler
1211

1312

1413
def start_app():
14+
application.add_handler(CommandHandler(["start"], start_handler))
1515
application.add_handler(CommandHandler(["cuenta"], account))
16-
application.add_handler(CommandHandler(["start"], help_handler))
1716
application.add_handler(CommandHandler(["ayuda"], help_handler))
1817
application.add_handler(CommandHandler(["pago"], payment))
1918
application.add_handler(CommandHandler(["wifi"], wifi))
19+
20+
# Add conversation handler with the states CHOOSING, TYPING_CHOICE and TYPING_REPLY
2021
conv_handler = ConversationHandler(
2122
entry_points=[CommandHandler("dispositivos", device)],
2223
states={
23-
DEVICES: [MessageHandler(filters.Regex("^(Mis dispositivos|Agregar uno nuevo)$"), devices)],
24-
PHOTO: [MessageHandler(filters.PHOTO, photo), CommandHandler("skip", skip_photo)],
25-
LOCATION: [
26-
MessageHandler(filters.LOCATION, location),
27-
CommandHandler("omitir", skip_location),
24+
# CHOOSING: [
25+
# MessageHandler(
26+
# filters.Regex("^(Age|Favourite colour|Number of siblings)$"), regular_choice
27+
# ),
28+
# MessageHandler(filters.Regex("^Something else...$"), custom_choice),
29+
# ],
30+
# TYPING_CHOICE: [
31+
# MessageHandler(
32+
# filters.TEXT & ~(filters.COMMAND | filters.Regex("^Done$")), regular_choice
33+
# )
34+
# ],
35+
ACTIONABLE: [
36+
MessageHandler(
37+
filters.TEXT & ~(filters.COMMAND | filters.Regex("^Done$")),
38+
show_response,
39+
)
40+
],
41+
ADD_MAC: [
42+
MessageHandler(
43+
filters.TEXT & ~(filters.COMMAND | filters.Regex("^Done$")),
44+
add_mac,
45+
)
46+
],
47+
SAVE_DEVICE: [
48+
MessageHandler(
49+
filters.TEXT & ~(filters.COMMAND | filters.Regex("^Done$")),
50+
save_device,
51+
)
2852
],
29-
BIO: [MessageHandler(filters.TEXT & ~filters.COMMAND, bio)],
3053
},
31-
fallbacks=[CommandHandler("cancelar", cancel_conversation)],
54+
fallbacks=[MessageHandler(filters.Regex("^Cancelar$"), done)],
3255
)
33-
3456
application.add_handler(conv_handler)
57+
3558
application.add_handler(MessageHandler(filters.TEXT, message_handler))
3659

3760
application.run_polling()

src/device/interface/device.py

+73-53
Original file line numberDiff line numberDiff line change
@@ -1,91 +1,111 @@
1+
from typing import Dict
2+
13
from telegram import Update, ReplyKeyboardMarkup, ReplyKeyboardRemove
24
from telegram.constants import ChatAction
35
from telegram.ext import ContextTypes, ConversationHandler
46

57
from src.device.application.request_wifi import request_wifi
8+
from src.shared.infrastructure.validators.validate_mac import is_valid_mac_address
9+
10+
ACTIONABLE, ADD_MAC, SAVE_DEVICE = range(3)
11+
options = ["Mis dispositivos", "Agregar uno nuevo"]
612

7-
DEVICES, PHOTO, LOCATION, BIO = range(4)
8-
OPTIONS = ["Mis dispositivos", "Agregar uno nuevo"]
13+
data = {}
914

1015

11-
async def device(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
16+
async def device(update: Update, context: ContextTypes.DEFAULT_TYPE):
1217
"""Starts the conversation and asks the user about their gender."""
13-
reply_keyboard = [OPTIONS]
18+
19+
options = ["Mis dispositivos", "Agregar uno nuevo"]
20+
21+
reply_keyboard = [
22+
options,
23+
]
24+
markup = ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True)
1425

1526
await update.message.reply_text(
16-
"En está sección podrás agregar y ver los dispositivos que has registrado.\n\n"
17-
"Envia /cancelar para terminar la conversación.\n\n"
27+
"🧾 Registra y gestiona tus dispositivos aquí.\n"
1828
"Por favor selecciona una opción para continuar:",
19-
reply_markup=ReplyKeyboardMarkup(
20-
reply_keyboard, one_time_keyboard=True, input_field_placeholder="Elije:"
21-
),
29+
reply_markup=markup,
2230
)
2331

24-
return DEVICES
32+
return ACTIONABLE
33+
2534

35+
async def show_response(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
36+
"""Store info provided by user and ask for the next category."""
37+
text = update.message.text
2638

27-
async def devices(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
28-
"""Stores the selected gender and asks for a photo."""
29-
user = update.message.from_user
30-
message = update.message.text
31-
if message == OPTIONS[0]:
39+
if text == options[0]:
3240
await update.message.reply_text(
33-
f"Elegiste: {message}"
41+
"A continuación te mostraremos tus dispositivos agregados",
42+
reply_markup=ReplyKeyboardRemove()
3443
)
35-
return PHOTO
36-
if update.message.text == OPTIONS[1]:
44+
return ConversationHandler.END
45+
if text == options[1]:
46+
types = ['Telefono', 'PC']
47+
reply_keyboard = [
48+
types,
49+
]
50+
markup = ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True)
3751
await update.message.reply_text(
38-
f"Elegiste: {message}"
52+
"📱 Elige el tipo de dispositivo que agregarás.\n"
53+
"La red se optimizará para el tipo de dispositivo que agregues",
54+
reply_markup=markup,
3955
)
40-
return PHOTO
4156

57+
return ADD_MAC
4258

43-
async def photo(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
44-
"""Stores the photo and asks for a location."""
45-
user = update.message.from_user
46-
photo_file = await update.message.photo[-1].get_file()
47-
await photo_file.download("user_photo.jpg")
48-
await update.message.reply_text(
49-
"Gorgeous! Now, send me your location please, or send /skip if you don't want to."
50-
)
5159

52-
return LOCATION
60+
async def add_mac(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
61+
"""Store info provided by user and ask for the next category."""
62+
63+
type = update.message.text
64+
data[update.message.chat_id] = type
5365

66+
print(type)
5467

55-
async def skip_photo(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
56-
"""Skips the photo and asks for a location."""
57-
user = update.message.from_user
5868
await update.message.reply_text(
59-
"I bet you look great! Now, send me your location please, or send /skip."
69+
"Agregaremos un nuevo dispositivo",
70+
reply_markup=ReplyKeyboardRemove()
71+
)
72+
await update.message.reply_text(
73+
'Escribe la dirección MAC'
6074
)
6175

62-
return LOCATION
76+
return SAVE_DEVICE
6377

6478

65-
async def location(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
66-
"""Stores the location and asks for some info about the user."""
67-
user = update.message.from_user
68-
user_location = update.message.location
69-
await update.message.reply_text(
70-
"Maybe I can visit you sometime! At last, tell me something about yourself."
71-
)
79+
async def save_device(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
80+
"""Store info provided by user and ask for the next category."""
7281

73-
return BIO
82+
mac = update.message.text
83+
print(mac, data.get(update.message.chat_id))
7484

85+
if is_valid_mac_address(mac):
86+
await update.message.reply_text(
87+
'Dirección valida',
88+
reply_markup=ReplyKeyboardRemove()
89+
)
90+
else:
91+
await update.message.reply_text(
92+
'❌ Dirección MAC invalida\nIntenta de nuevo en /dispositivos',
93+
reply_markup=ReplyKeyboardRemove()
94+
)
7595

76-
async def skip_location(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
77-
"""Skips the location and asks for info about the user."""
78-
user = update.message.from_user
79-
await update.message.reply_text(
80-
"You seem a bit paranoid! At last, tell me something about yourself."
81-
)
96+
return ConversationHandler.END
8297

83-
return BIO
8498

99+
async def done(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
100+
"""Display the gathered info and end the conversation."""
101+
user_data = context.user_data
102+
if "choice" in user_data:
103+
del user_data["choice"]
85104

86-
async def bio(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
87-
"""Stores the info about the user and ends the conversation."""
88-
user = update.message.from_user
89-
await update.message.reply_text("Thank you! I hope we can talk again some day.")
105+
await update.message.reply_text(
106+
f"I learned these facts about you: {user_data}Until next time!",
107+
reply_markup=ReplyKeyboardRemove(),
108+
)
90109

110+
user_data.clear()
91111
return ConversationHandler.END

src/shared/application/request_help.py

+15-2
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,24 @@ def request_help(user):
88
response = []
99
if access:
1010
response.append(
11-
f"/cuenta Acerca de tu cuenta\n/pago Tú próximo pago\n/wifi Clave de "
12-
f"internet\n/dispositivos Registra tus dispositivos\n/problemas Reporta un problema\n/garrafones Compra "
11+
f"🪪 /cuenta Acerca de tu cuenta\n💵 /pago Tú próximo pago\n🌐 /wifi Clave de "
12+
f"internet\n📱 /dispositivos Registra tus dispositivos\n📬 /problemas Reporta un problema\n💧 /garrafones Compra "
1313
f"garrafones de "
1414
f"agua")
1515
else:
1616
return get_unnaccess()
1717

1818
return response
19+
20+
21+
def request_start(user):
22+
usr, access, info = GetAccount().execute(permission='settings', chat_id=user.id,
23+
name=user.first_name, username=user.username)
24+
response = []
25+
if access:
26+
response.append(
27+
f"Hola mi nombre es Cerebro tu asistente digital, comienza gestionando tu /cuenta para comenzar. Una vez activa podrás acceder a todas las funcionalidades")
28+
else:
29+
return get_unnaccess()
30+
31+
return response

src/shared/infrastructure/validators/__init__.py

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import re
2+
3+
4+
def is_valid_mac_address(str):
5+
# Regex to check valid
6+
# MAC address
7+
regex = ("^([0-9A-Fa-f]{2}[:-])" +
8+
"{5}([0-9A-Fa-f]{2})|" +
9+
"([0-9a-fA-F]{4}\\." +
10+
"[0-9a-fA-F]{4}\\." +
11+
"[0-9a-fA-F]{4})$")
12+
13+
# Compile the ReGex
14+
p = re.compile(regex)
15+
16+
# If the string is empty
17+
# return false
18+
if str is None:
19+
return False
20+
21+
# Return if the string
22+
# matched the ReGex
23+
if re.search(p, str):
24+
return True
25+
else:
26+
return False

src/shared/interface/help.py

+10-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from telegram.constants import ChatAction
33
from telegram.ext import ContextTypes
44

5-
from src.shared.application.request_help import request_help
5+
from src.shared.application.request_help import request_help, request_start
66

77

88
async def help_handler(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
@@ -12,3 +12,12 @@ async def help_handler(update: Update, context: ContextTypes.DEFAULT_TYPE) -> No
1212

1313
for m in request_help(update.message.from_user):
1414
await update.message.reply_text(m)
15+
16+
17+
async def start_handler(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
18+
await update.message.reply_text("Bienvenid@ ...")
19+
20+
await context.bot.sendChatAction(chat_id=update.message.chat_id, action=ChatAction.TYPING)
21+
22+
for m in request_start(update.message.from_user):
23+
await update.message.reply_text(m)

src/user/application/request_account.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ def request_account(user):
66
usr, access, info = GetAccount().execute(permission='settings', chat_id=user.id,
77
name=user.first_name, username=user.username)
88

9-
response = [f"Nombre: {info.full_name}\nTelefono: {info.phone}\nActivo: {info.verify}"]
9+
response = [f"🧠 Nombre: {info.full_name}\n📱 Telefono: {info.phone}\nActivo: {'🟢' if info.verify else '🔴'}"]
1010

1111
if access:
1212
response.append(
13-
f"Hospedado en {info.room_name.lower()}\nDesde el {info.room_start_date}\n{f'Hasta el {info.room_end_date}' if info.room_end_date is not None else ''}")
13+
f"🏡 Hospedado en {info.room_name.lower()}\nDesde el {info.room_start_date}\n{f'Hasta el {info.room_end_date}' if info.room_end_date is not None else ''}")
1414
response.append(
1515
f"Consulta más acciones en /ayuda")
1616

0 commit comments

Comments
 (0)