2014-10-17 12 views
5

(Non nativo inglese, mi dispiace per l'inglese probabilmente rotto. Sono anche un principiante alla programmazione).
Ciao, sto provando a connettermi a un server TeamSpeak utilizzando QueryServer per creare un bot. Dopo giorni di lotta con esso ... funziona, con solo 1 problema, e sono bloccato con quello.Come mantenere uno script Python 3 (Bot) in esecuzione

Se avete bisogno di controllare, questo è l'API TeamSpeak che sto usando: http://py-ts3.readthedocs.org/en/latest/api/query.html

e questa è la sintesi di ciò che accade realmente nel mio script:

  1. Si collega.
  2. Si verifica la presenza di ID del canale (ed è proprio ID cliente)
  3. Si unisce il canale
  4. script termina quindi si disconnette.

La mia domanda è: come posso farlo non si disconnette? Come posso far rimanere lo script in uno stato di "attesa" in modo che possa leggere se qualcuno digita "hi bot" nel canale? Tutto il codice necessario per leggere i testi e rispondere a loro sembra facile da programmare, tuttavia mi trovo di fronte a un problema in cui non riesco a "far funzionare" il bot poiché chiude il file non appena termina l'esecuzione dello script.

Maggiori informazioni:
Sto usando Python 3.4.1.
Ho provato ad imparare il threading http://www.tutorialspoint.com/python/python_multithreading.htm ma o sono muto o non funziona nel modo in cui pensavo.
Nell'API esiste una funzione denominata on_event che mi piacerebbe continuare a girare sempre. Il codice bot dovrebbe essere eseguito una sola volta e quindi rimanere "in attesa" fino a quando si verifica un evento. Come dovrei farlo? Nessun indizio.

Codice:

import ts3 
import telnetlib 
import time 

class BotPrincipal: 
    def Conectar(ts3conn): 
     MiID = [i["client_id"] for i in ts3conn.whoami()] 
     ChannelToJoin = "[Pruebas] Bots" 
     ts3conn.on_event = BotPrincipal.EventHappened() 
     try: 
      BuscandoIDCanal = ts3conn.channelfind(pattern=ChannelToJoin) 
      IDCanal = [i["cid"] for i in BuscandoIDCanal] 
      if not IDCanal: 
       print("No channel found with that name") 
       return None 
      else: 
       MiID = str(MiID).replace("'", "") 
       MiID = str(MiID).replace("]", "") 
       MiID = str(MiID).replace("[", "") 
       IDCanal = str(IDCanal).replace("'", "") 
       IDCanal = str(IDCanal).replace("]", "") 
       IDCanal = str(IDCanal).replace("[", "")     
       print("ID de canal " + ChannelToJoin + ": " + IDCanal) 
       print("ID de cliente " + Nickname + ": " + MiID) 
      try: 
       print("Moving you into: " + ChannelToJoin) 
       ts3conn.clientmove(cid=IDCanal, clid=MiID) #entra al canal 
       try: 
        print("Asking for notifications from: " + ChannelToJoin) 
        ts3conn.servernotifyregister(event="channel", id_=IDCanal) 
        ts3conn.servernotifyregister(event="textchannel", id_=IDCanal) 
       except ts3.query.TS3QueryError: 
        print("You have no permission to use the telnet command: servernotifyregister") 
       print("------- Bot Listo -------") 
      except ts3.query.TS3QueryError: 
       print("You have no permission to use the telnet command: clientmove") 
     except ts3.query.TS3QueryError: 
      print("Error finding ID for " + ChannelToJoin + ". telnet: channelfind") 

    def EventHappened(): 
     print("Doesn't work") 

# Data needed # 
USER = "thisisafakename" 
PASS = "something" 
HOST = "111.111.111.111" 
PORT = 10011 
SID = 1 

if __name__ == "__main__":  
    with ts3.query.TS3Connection(HOST, PORT) as ts3conn: 
     ts3conn.login(client_login_name=USER, client_login_password=PASS) 
     ts3conn.use(sid=SID) 
     print("Connected to "+HOST) 
     BotPrincipal.Conectar(ts3conn) 
+1

Come nota a margine, questo non è il modo in cui si utilizzano le classi. Il tuo 'Conectar' dovrebbe prendere un parametro' self', e il tuo codice principale dovrebbe costruire un'istanza 'BotPrincipal' e chiamare il metodo' Conectar' su quell'istanza, ecc. Si tratta di una combinazione di 3 bug che annullano questo tipo di lavoro , che probabilmente non è qualcosa su cui vuoi fare affidamento. – abarnert

+1

Solo aggiungendo alla nota di abarnets, basta dare un'occhiata alla [documentazione ufficiale di Python sulle classi] (https://docs.python.org/3.4/tutorial/classes.html#a-first-look-at-classes) o ad alcuni [diverse esercitazioni] (http://en.wikibooks.org/wiki/A_Beginner's_Python_Tutorial/Classes). – Vyktor

+0

Come non ho mai veramente imparato alcun linguaggio di programmazione e sto facendo del mio meglio con google, posso vedere dove ho fallito. Sto controllando quel sito web in questo momento e sto provando a risolvere i problemi. Apprezzo l'aiuto. – Saelyth

risposta

3

Da un rapido sguardo alla API, sembra che tu abbia bisogno di dire in modo esplicito l'oggetto ts3conn ad aspettare gli eventi. Sembra che ci siano un paio di modi per farlo, ma ts3conn.recv(True) sembra la più ovvia:

blocchi fino a tutte le risposte non recuperato sono stati ricevuti o per sempre, se recv_forever è vero.

Presumibilmente come ogni comando entra, si chiamerà il gestore on_event, poi quando si torna da che andrà di nuovo ad aspettare per sempre per il comando successivo.

Non so se avete bisogno di discussioni qui o no, ma la documentazione per recv_in_thread rendere il suono come si potrebbe:

chiede recv() in un thread. Questo è utile se hai usato servernotifyregister e prevedi di ricevere eventi.

È presumibilmente desidera ottenere entrambi gli eventi servernotify e comandi anche, e credo che il modo in cui questa libreria è scritto è necessario thread per questo? In tal caso, chiama semplicemente ts3conn.recv_in_thread() anziché ts3conn.recv(True). (Se si guarda the source, tutto ciò che fa è avviare una discussione in background e chiamare self.recv(True) su quella discussione.)

+0

Fammi vedere se ho capito questo. Dovrei chiamare ts3conn.recv_in_thread() all'interno di def EventHappened(): e creerà il suo thread, quindi non ho bisogno di farlo da solo? – Saelyth

+0

@Saelyth: non all'interno di "EventHappened", alla fine di 'Conectar', o nel tuo codice principale dopo il ritorno di' Conectar'. E sì, crea il suo thread, quindi non devi. A meno che tu non stia cercando di fare cose nel tuo gestore che si basano su variabili mutanti globali o altrimenti condivise, non dovresti nemmeno preoccuparti del fatto che i thread esistano. – abarnert

+0

Yay! grazie per le risposte: D – Saelyth

Problemi correlati