fix setup process
This commit is contained in:
251
telegram_bot.py
251
telegram_bot.py
@@ -63,8 +63,8 @@ class UserProfile:
|
||||
self.username = username
|
||||
self.role: Optional[str] = None
|
||||
self.display_name: Optional[str] = None
|
||||
self.channels: List[int] = [] # Canali assegnati
|
||||
self.mixes: List[int] = [] # Mix/aux assegnati
|
||||
self.channel_labels: List[str] = [] # Etichette dei canali assegnati
|
||||
self.mix_labels: List[str] = [] # Etichette dei mix/aux assegnati
|
||||
self.setup_completed = False
|
||||
self.created_at = time.time()
|
||||
self.last_updated = time.time()
|
||||
@@ -76,8 +76,8 @@ class UserProfile:
|
||||
"username": self.username,
|
||||
"role": self.role,
|
||||
"display_name": self.display_name,
|
||||
"channels": self.channels,
|
||||
"mixes": self.mixes,
|
||||
"channel_labels": self.channel_labels,
|
||||
"mix_labels": self.mix_labels,
|
||||
"setup_completed": self.setup_completed,
|
||||
"created_at": self.created_at,
|
||||
"created_at_str": time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(self.created_at)),
|
||||
@@ -91,8 +91,8 @@ class UserProfile:
|
||||
profile = cls(data["user_id"], data["username"])
|
||||
profile.role = data.get("role")
|
||||
profile.display_name = data.get("display_name")
|
||||
profile.channels = data.get("channels", [])
|
||||
profile.mixes = data.get("mixes", [])
|
||||
profile.channel_labels = data.get("channel_labels", [])
|
||||
profile.mix_labels = data.get("mix_labels", [])
|
||||
profile.setup_completed = data.get("setup_completed", False)
|
||||
profile.created_at = data.get("created_at", time.time())
|
||||
profile.last_updated = data.get("last_updated", time.time())
|
||||
@@ -102,36 +102,6 @@ class UserProfile:
|
||||
"""Restituisce le info sul ruolo."""
|
||||
return self.ROLES.get(self.role, {})
|
||||
|
||||
def can_access_channel(self, channel: int) -> bool:
|
||||
"""Verifica se l'utente può accedere a un canale."""
|
||||
if not self.role:
|
||||
return False
|
||||
|
||||
permissions = self.get_role_info().get("permissions", [])
|
||||
|
||||
if "all" in permissions:
|
||||
return True
|
||||
|
||||
if "own_channel" in permissions:
|
||||
return channel in self.channels
|
||||
|
||||
return False
|
||||
|
||||
def can_access_mix(self, mix: int) -> bool:
|
||||
"""Verifica se l'utente può accedere a un mix."""
|
||||
if not self.role:
|
||||
return False
|
||||
|
||||
permissions = self.get_role_info().get("permissions", [])
|
||||
|
||||
if "all" in permissions:
|
||||
return True
|
||||
|
||||
if "own_mix" in permissions:
|
||||
return mix in self.mixes
|
||||
|
||||
return False
|
||||
|
||||
def get_summary(self) -> str:
|
||||
"""Restituisce un riepilogo del profilo."""
|
||||
if not self.setup_completed:
|
||||
@@ -140,15 +110,14 @@ class UserProfile:
|
||||
role_info = self.get_role_info()
|
||||
msg = f"{role_info['emoji']} **{self.display_name}** ({role_info['name']})\n\n"
|
||||
|
||||
if self.channels:
|
||||
msg += f"🎚️ Canali: {', '.join(map(str, self.channels))}\n"
|
||||
if self.channel_labels:
|
||||
msg += f"🎚️ Canali: {', '.join(self.channel_labels)}\n"
|
||||
|
||||
if self.mixes:
|
||||
msg += f"🔊 Mix: {', '.join(map(str, self.mixes))}\n"
|
||||
if self.mix_labels:
|
||||
msg += f"🔊 Mix: {', '.join(self.mix_labels)}\n"
|
||||
|
||||
return msg
|
||||
|
||||
|
||||
class ProfileManager:
|
||||
"""Gestisce i profili utente."""
|
||||
|
||||
@@ -221,7 +190,6 @@ class ProfileManager:
|
||||
|
||||
return profiles
|
||||
|
||||
|
||||
class ConversationManager:
|
||||
"""Gestisce il salvataggio delle conversazioni su file JSON."""
|
||||
|
||||
@@ -289,7 +257,6 @@ class ConversationManager:
|
||||
print(f"❌ Errore nell'eliminazione conversazione {user_id}: {e}")
|
||||
return False
|
||||
|
||||
|
||||
class TelegramBot:
|
||||
"""Bot Telegram base con long polling."""
|
||||
|
||||
@@ -423,7 +390,7 @@ class TF5TelegramBot:
|
||||
self.controller.set_channel_to_mix_level,
|
||||
self.controller.set_channel_to_mix_on_off,
|
||||
self.controller.get_channel_to_mix_info,
|
||||
self.controller.get_full_mix_details, # <-- NUOVA FUNZIONE AGGIUNTA
|
||||
self.controller.get_full_mix_details,
|
||||
],
|
||||
temperature=0,
|
||||
)
|
||||
@@ -568,13 +535,17 @@ Devi essere veloce, chiaro e capire anche richieste approssimative.
|
||||
instruction += f"Nome: {profile.display_name}\n"
|
||||
instruction += f"Ruolo: {role_info['name']} {role_info['emoji']}\n"
|
||||
|
||||
if profile.channels:
|
||||
instruction += f"\nCanali assegnati: {', '.join(map(str, profile.channels))}\n"
|
||||
instruction += "Quando l'utente dice 'il mio canale' o 'il mio mic/strumento', si riferisce a questi.\n"
|
||||
if profile.channel_labels:
|
||||
labels_str = ', '.join([f"'{l}'" for l in profile.channel_labels])
|
||||
instruction += f"\nNomi dei canali assegnati: {labels_str}\n"
|
||||
instruction += "Quando l'utente dice 'il mio canale' o 'il mio mic/strumento', si riferisce a questi. "
|
||||
instruction += "**DEVI usare `search_channels_by_name` con questi nomi per trovare il numero di canale corretto prima di eseguire qualsiasi altra azione.**\n"
|
||||
|
||||
if profile.mixes:
|
||||
instruction += f"\nMix assegnati: {', '.join(map(str, profile.mixes))}\n"
|
||||
instruction += "Quando l'utente dice 'le mie cuffie', 'il mio monitor', 'in cuffia', si riferisce a questi mix.\n"
|
||||
if profile.mix_labels:
|
||||
labels_str = ', '.join([f"'{l}'" for l in profile.mix_labels])
|
||||
instruction += f"\nNomi dei mix assegnati: {labels_str}\n"
|
||||
instruction += "Quando l'utente dice 'le mie cuffie', 'il mio monitor', 'in cuffia', si riferisce a questi mix. "
|
||||
instruction += "**DEVI usare `search_mixes_by_name` con questi nomi per trovare il numero di mix corretto prima di eseguire qualsiasi altra azione.**\n"
|
||||
|
||||
# Istruzioni specifiche per ruolo
|
||||
permissions = role_info.get("permissions", [])
|
||||
@@ -587,77 +558,27 @@ Devi essere veloce, chiaro e capire anche richieste approssimative.
|
||||
else:
|
||||
instruction += f"\n⚠️ LIMITAZIONI DI ACCESSO ({role_info['name']}):\n"
|
||||
|
||||
if "own_channel" in permissions and profile.channels:
|
||||
instruction += f"- Canali controllabili: SOLO {', '.join(map(str, profile.channels))}\n"
|
||||
if "own_channel" in permissions and profile.channel_labels:
|
||||
instruction += f"- Canali controllabili: SOLO quelli che corrispondono ai nomi nel tuo profilo.\n"
|
||||
|
||||
if "own_mix" in permissions and profile.mixes:
|
||||
instruction += f"- Mix controllabili: SOLO {', '.join(map(str, profile.mixes))}\n"
|
||||
instruction += f"- Puoi gestire i send di QUALSIASI canale verso i TUOI mix ({', '.join(map(str, profile.mixes))})\n"
|
||||
if "own_mix" in permissions and profile.mix_labels:
|
||||
instruction += f"- Mix controllabili: SOLO quelli che corrispondono ai nomi nel tuo profilo.\n"
|
||||
instruction += f"- Puoi gestire i send di QUALSIASI canale verso i TUOI mix.\n"
|
||||
|
||||
instruction += "\n❌ NON puoi:\n"
|
||||
if "own_channel" not in permissions:
|
||||
instruction += "- Modificare il volume/stato dei canali\n"
|
||||
if "own_mix" not in permissions:
|
||||
instruction += "- Modificare il volume/stato dei mix\n"
|
||||
instruction += "- Caricare scene (solo i mixeristi)\n"
|
||||
instruction += "- Accedere a canali/mix non assegnati\n"
|
||||
instruction += "- Caricare scene (solo i mixeristi).\n"
|
||||
instruction += "- Accedere a canali/mix non associati al tuo profilo.\n"
|
||||
|
||||
instruction += "\n💡 INTERPRETAZIONE RICHIESTE:\n"
|
||||
instruction += "- 'alzami la chitarra' = alza il send della chitarra nel TUO mix\n"
|
||||
instruction += "- 'più voce' = alza il send della voce nel TUO mix\n"
|
||||
instruction += "- 'meno batteria in cuffia' = abbassa il send della batteria nel TUO mix\n"
|
||||
instruction += "- Se l'utente chiede di fare qualcosa fuori dai suoi permessi, spiega gentilmente che non può e suggerisci di chiedere al mixerista\n"
|
||||
instruction += "- 'alzami la chitarra' = alza il send della chitarra nel TUO mix (identificato dal suo nome).\n"
|
||||
instruction += "- 'più voce' = alza il send della voce nel TUO mix.\n"
|
||||
instruction += "- 'meno batteria in cuffia' = abbassa il send della batteria nel TUO mix.\n"
|
||||
instruction += "- Se l'utente chiede di fare qualcosa fuori dai suoi permessi, spiega gentilmente che non può e suggerisci di chiedere al mixerista.\n"
|
||||
|
||||
instruction += f"\n{'='*70}\n"
|
||||
|
||||
return instruction
|
||||
|
||||
def _check_permission(self, profile: UserProfile, operation: str,
|
||||
channel: Optional[int] = None,
|
||||
mix: Optional[int] = None) -> tuple[bool, str]:
|
||||
"""
|
||||
Verifica se l'utente ha i permessi per un'operazione.
|
||||
Ritorna (permitted, error_message)
|
||||
"""
|
||||
if not profile.setup_completed:
|
||||
return False, "⚠️ Devi prima configurare il tuo profilo con /setup"
|
||||
|
||||
role_info = profile.get_role_info()
|
||||
permissions = role_info.get("permissions", [])
|
||||
|
||||
# Mixeristi possono fare tutto
|
||||
if "all" in permissions:
|
||||
return True, ""
|
||||
|
||||
# Verifica permessi specifici
|
||||
if operation in ["set_channel_level", "set_channel_on_off", "set_channel_pan",
|
||||
"mute_multiple_channels", "unmute_multiple_channels"]:
|
||||
if "own_channel" not in permissions:
|
||||
return False, "❌ Solo i mixeristi possono controllare i canali direttamente"
|
||||
|
||||
if channel and not profile.can_access_channel(channel):
|
||||
return False, f"❌ Non hai accesso al canale {channel}. I tuoi canali: {', '.join(map(str, profile.channels))}"
|
||||
|
||||
if operation in ["set_mix_level", "set_mix_on_off", "get_full_mix_details"]:
|
||||
if "own_mix" not in permissions:
|
||||
return False, "❌ Non hai permessi per controllare i mix"
|
||||
|
||||
if mix and not profile.can_access_mix(mix):
|
||||
return False, f"❌ Non hai accesso al mix {mix}. I tuoi mix: {', '.join(map(str, profile.mixes))}"
|
||||
|
||||
if operation == "recall_scene":
|
||||
return False, "❌ Solo i mixeristi possono caricare scene"
|
||||
|
||||
# Le operazioni di send ai mix sono permesse se hai accesso al mix di destinazione
|
||||
if operation in ["set_channel_to_mix_level", "set_channel_to_mix_on_off"]:
|
||||
if "own_mix" not in permissions:
|
||||
return False, "❌ Non hai permessi per controllare i send ai mix"
|
||||
|
||||
if mix and not profile.can_access_mix(mix):
|
||||
return False, f"❌ Non hai accesso al mix {mix}. I tuoi mix: {', '.join(map(str, profile.mixes))}"
|
||||
|
||||
return True, ""
|
||||
|
||||
def get_profile(self, user_id: int, username: str) -> UserProfile:
|
||||
"""Ottiene il profilo di un utente."""
|
||||
if user_id not in self.profiles:
|
||||
@@ -726,7 +647,6 @@ Devi essere veloce, chiaro e capire anche richieste approssimative.
|
||||
role_info = profile.get_role_info()
|
||||
permissions = role_info.get("permissions", [])
|
||||
|
||||
# Se è mixerista, ha finito
|
||||
if "all" in permissions:
|
||||
profile.setup_completed = True
|
||||
self.profile_manager.save_profile(profile)
|
||||
@@ -740,59 +660,47 @@ Devi essere veloce, chiaro e capire anche richieste approssimative.
|
||||
f"• 'Richiama la scena A10'\n"
|
||||
f"• 'Mostrami tutti i canali'")
|
||||
|
||||
# Altrimenti, chiedi i canali (se necessario)
|
||||
if "own_channel" in permissions:
|
||||
self.bot.send_message(
|
||||
user_id,
|
||||
f"🎚️ Quali canali usi?\n\n"
|
||||
f"Esempi:\n"
|
||||
f"• Un canale: 5\n"
|
||||
f"• Più canali: 5, 7, 12\n"
|
||||
f"• Range: 5-8 (canali 5, 6, 7, 8)\n"
|
||||
f"• Misti: 3, 5-7, 10\n\n"
|
||||
f"(Scrivi 0 se non usi canali diretti)"
|
||||
f"🎚️ **Come si chiama il tuo canale/strumento?**\n\n"
|
||||
f"Scrivi il nome esatto che vedi sull'etichetta del mixer (es: 'VOX Marco', 'CH Acustica').\n"
|
||||
f"Se hai più canali, separali con una virgola (es: 'Tastiera L', 'Tastiera R').\n\n"
|
||||
f"(Scrivi 'nessuno' se non hai un canale specifico)"
|
||||
)
|
||||
self.setup_states[user_id] = {"step": "channels", "role": profile.role}
|
||||
return ""
|
||||
else:
|
||||
# Salta direttamente ai mix
|
||||
self.setup_states[user_id] = {"step": "channels"}
|
||||
elif "own_mix" in permissions:
|
||||
self.bot.send_message(
|
||||
user_id,
|
||||
f"🔊 Quali mix/aux usi per le tue cuffie o uscita?\n\n"
|
||||
f"Esempi:\n"
|
||||
f"• Un mix: 3\n"
|
||||
f"• Più mix: 3, 5\n"
|
||||
f"• Range: 3-5\n"
|
||||
f"• Mix stereo: 9, 10 (in-ear stereo)\n\n"
|
||||
f"(Scrivi 0 se non usi mix specifici)"
|
||||
f"🔊 **Come si chiama il tuo mix per le cuffie/monitor?**\n\n"
|
||||
f"Scrivi il nome esatto (es: 'InEar Marco', 'Cuffia Palco Sx').\n"
|
||||
f"Se usi un mix stereo, scrivi entrambi i nomi separati da virgola (es: 'IEM L', 'IEM R').\n\n"
|
||||
f"(Scrivi 'nessuno' se non usi un mix specifico)"
|
||||
)
|
||||
self.setup_states[user_id] = {"step": "mixes", "role": profile.role}
|
||||
return ""
|
||||
self.setup_states[user_id] = {"step": "mixes"}
|
||||
|
||||
return ""
|
||||
|
||||
# Step: inserimento canali
|
||||
# Step: inserimento etichette canali
|
||||
elif step == "channels":
|
||||
channels = self._parse_channel_list(text)
|
||||
profile.channels = channels
|
||||
labels_text = text.strip()
|
||||
if labels_text.lower() != 'nessuno':
|
||||
profile.channel_labels = [label.strip() for label in labels_text.split(',')]
|
||||
|
||||
role_info = profile.get_role_info()
|
||||
permissions = role_info.get("permissions", [])
|
||||
|
||||
# Chiedi i mix se necessario
|
||||
if "own_mix" in permissions:
|
||||
self.bot.send_message(
|
||||
user_id,
|
||||
f"🔊 Quali mix/aux usi per le tue cuffie o uscita?\n\n"
|
||||
f"Esempi:\n"
|
||||
f"• Un mix: 3\n"
|
||||
f"• Più mix: 3, 5\n"
|
||||
f"• Range: 3-5\n"
|
||||
f"• Mix stereo: 9, 10 (in-ear stereo)\n\n"
|
||||
f"(Scrivi 0 se non usi mix specifici)"
|
||||
f"🔊 **Come si chiama il tuo mix per le cuffie/monitor?**\n\n"
|
||||
f"Scrivi il nome esatto (es: 'InEar Marco', 'Cuffia Palco Sx').\n"
|
||||
f"Se usi un mix stereo, scrivi entrambi i nomi separati da virgola (es: 'IEM L', 'IEM R').\n\n"
|
||||
f"(Scrivi 'nessuno' se non usi un mix specifico)"
|
||||
)
|
||||
self.setup_states[user_id] = {"step": "mixes", "role": profile.role}
|
||||
self.setup_states[user_id] = {"step": "mixes"}
|
||||
return ""
|
||||
else:
|
||||
# Finito
|
||||
profile.setup_completed = True
|
||||
self.profile_manager.save_profile(profile)
|
||||
del self.setup_states[user_id]
|
||||
@@ -803,59 +711,32 @@ Devi essere veloce, chiaro e capire anche richieste approssimative.
|
||||
f"• 'Alza il mio canale'\n"
|
||||
f"• 'Spegni il mio mic'")
|
||||
|
||||
# Step: inserimento mix
|
||||
# Step: inserimento etichette mix
|
||||
elif step == "mixes":
|
||||
mixes = self._parse_channel_list(text) # Stessa logica per i mix
|
||||
profile.mixes = mixes
|
||||
labels_text = text.strip()
|
||||
if labels_text.lower() != 'nessuno':
|
||||
profile.mix_labels = [label.strip() for label in labels_text.split(',')]
|
||||
|
||||
profile.setup_completed = True
|
||||
self.profile_manager.save_profile(profile)
|
||||
del self.setup_states[user_id]
|
||||
|
||||
role_info = profile.get_role_info()
|
||||
|
||||
example_commands = []
|
||||
if profile.channels:
|
||||
example_commands.append("• 'Alza il mio canale'")
|
||||
if profile.mixes:
|
||||
if profile.channel_labels:
|
||||
example_commands.append("• 'Alza il volume del mio canale'")
|
||||
if profile.mix_labels:
|
||||
example_commands.extend([
|
||||
"• 'Alzami la chitarra' (nel tuo mix)",
|
||||
"• 'Alzami la chitarra nel mio monitor'",
|
||||
"• 'Più voce in cuffia'",
|
||||
"• 'Meno batteria'"
|
||||
])
|
||||
|
||||
return (f"✅ Configurazione completata!\n\n"
|
||||
f"{profile.get_summary()}\n"
|
||||
f"Esempi di comandi:\n" + "\n".join(example_commands))
|
||||
f"{profile.get_summary()}\n\n"
|
||||
f"Esempi di comandi che puoi usare:\n" + "\n".join(example_commands))
|
||||
|
||||
return ""
|
||||
|
||||
def _parse_channel_list(self, text: str) -> List[int]:
|
||||
"""Parse una lista di canali/mix dal testo utente."""
|
||||
channels = []
|
||||
|
||||
# Rimuovi spazi e split per virgola
|
||||
parts = [p.strip() for p in text.split(',')]
|
||||
|
||||
for part in parts:
|
||||
# Range (es: 5-8)
|
||||
if '-' in part:
|
||||
try:
|
||||
start, end = map(int, part.split('-'))
|
||||
channels.extend(range(start, end + 1))
|
||||
except:
|
||||
pass
|
||||
# Singolo numero
|
||||
else:
|
||||
try:
|
||||
num = int(part)
|
||||
if num > 0: # Ignora 0
|
||||
channels.append(num)
|
||||
except:
|
||||
pass
|
||||
|
||||
return sorted(list(set(channels))) # Rimuovi duplicati e ordina
|
||||
|
||||
def _get_file_path(self, file_id: str) -> str:
|
||||
"""Richiede a Telegram il percorso di un file."""
|
||||
result = self.bot._make_request("getFile", {"file_id": file_id})
|
||||
@@ -1006,10 +887,10 @@ Devi essere veloce, chiaro e capire anche richieste approssimative.
|
||||
msg += "• 'Analizza il mix 15 per la diretta'\n"
|
||||
else:
|
||||
msg += "**Esempi di comandi:**\n"
|
||||
if profile.channels:
|
||||
if profile.channel_labels:
|
||||
msg += "• 'Alza il mio canale'\n"
|
||||
msg += "• 'Spegni il mio mic'\n"
|
||||
if profile.mixes:
|
||||
if profile.mix_labels:
|
||||
msg += "• 'Alzami la chitarra' (nel tuo mix)\n"
|
||||
msg += "• 'Più voce in cuffia'\n"
|
||||
msg += "• 'Analizza il mio mix per la diretta'\n"
|
||||
|
||||
Reference in New Issue
Block a user