Wpp1State.py 9.36 KB
import requests, json, config, datetime, smtplib

class StatePhoneWs():
    """Esta clase consulta el estado de los telefonos y los cachea
    la consulta tiene 30 segundos de valides, para mejorar la perfrmance"""
    
    def __init__(self):
        self.Consultas = {}#{telefono:{"hora": datetime.datetime.now, "estado": self.chequear_stado_WB(telefono)},}

    def chequear_stado_WB(self, telefono):
        if not len(telefono) == 13:
            return({'error': 'Mal cargado el numero de telefono'}) 
        consulta = """{}{}?token={}""".format(config.WS_Status,
        telefono, config.WS_token)
        r = requests.get(consulta)
        j = r.json()
        return(j)

    def ChequearTelefono(self, telefono):
        """Chequea estado es el server remoto si esta conectado se almasena la
        respuesta en cache durante 60 segundos para mejorar performance y si no esta
        disponible no se almasena y la proxima respuesta debera hacerse contra el server
        remoto para asegurarme de q se solucione el problema"""
        test = self.revisarCache(telefono)
        if not test == False:
            return(test)
        W = self.chequear_stado_WB(telefono)
        if "error" in W.keys():#si hay algun error no actualiso el estado en cache
            return(W)
        hora = datetime.datetime.now() + datetime.timedelta(seconds=60)
        self.Consultas[telefono] = {"hora": hora,
        "estado": W}
        print("Chequeando telefono saliente", W)
        return(W)

    def revisarCache(self, telefono):
        if not telefono in self.Consultas.keys():
            return(False)
        cel = self.Consultas[telefono]
        if datetime.datetime.now() < cel["hora"]:
            return(cel["estado"])
        return(False)

class StateMail():
    """Esta clase consulta el estado de los mail server y los cachea
    la consulta tiene 60 segundos de valides, para mejorar la perfrmance
    y la cantidad de mails enviado por dia para no superar el limite de emision"""
    
    def __init__(self):
        self.Consultas = {}#{MailUSer-pass-host-str(port):{"hora": datetime.datetime.now, "estado": self.chequear_stado_WB(telefono)},}
        self.MailRompedor = []
        self.MailsEnviado = {}#"MAIL@HOST": n 
        self.MailsBloqueados = {}#"MAIL@HOST": datetimeDeDesbloqueo

    def ChequearCuentaBlockeadaYEnviar(self, mail, smtphost):
        """Chequeo la cuenta para ver si esta llegando al limite de bloqueo
        o si ya paso suficiente tiempo para volver a usarla"""
        if False == self.CuentaBloqueada(mail):
            return(False)
        limite = self.MailEnviado(mail, smtphost)
        if limite == False:
            self.BloquearCuenta(mail)
        return(limite)

    def BloquearCuenta(self, mail):
        """Bloquea cuenta por un dia"""
        tiempo = datetime.datetime.now() + datetime.timedelta(days=1)
        self.MailsBloqueados[mail] = tiempo
        self.MailsEnviado[mail] = []
        return(True)

    def CuentaBloqueada(self, mail):
        """si la cuenta esta bloqueada devuelve False
        sino True.
        Si esta bloqueada y paso el dia la desbloquea y devuelve True"""
        try:
            Fecha = self.MailsBloqueados[mail]
        except:
            return(True)#Si no esta en la lissta de bloqueados devuelvo True
        if Fecha < datetime.datetime.now():#si paso el dia
            self.MailsBloqueados.pop(mail, None)#Remuevo el mail de los bloqueados
            return(True)
        return(False)

    def MailEnviado(self, mail, smtphost):
        habilitado = True
        if self._sumarMail(mail) > self.ArmarListadoLimitesHost(smtphost):
            habilitado = False
        return(habilitado)

    def _sumarMail(self, mail):
        """Se agrega al dicionario si no existe si existe se le agrega 
        devuelve el resultado"""
        try:
            self.MailsEnviado[mail].append(datetime.datetime.now())
        except:
            self.MailsEnviado[mail] = []
            self.MailsEnviado[mail].append(datetime.datetime.now())
        #print("linea 94", self.MailsEnviado[mail])
        LOG = []
        for MAIL in self.MailsEnviado[mail]:
            #print("linea 97", MAIL)
            #print("linea 98", MAIL, datetime.datetime.now() + datetime.timedelta(days=1))
            if MAIL < datetime.datetime.now() + datetime.timedelta(days=1):
                LOG.append(MAIL)
        self.MailsEnviado[mail] = LOG
        #try:
        #    self.MailsEnviado[mail] = self.MailsEnviado[mail] + 1
        #except:
        #    self.MailsEnviado[mail] = 0
        resultado = len(self.MailsEnviado[mail])
        print(resultado)
        return(resultado)
        

    def LimpiarListaMailEnviados(self):
        self.MailsEnviado = {}
        return("True")

    def ArmarListadoLimitesHost(self, host):
        """Devuelve la cantidad de mails que se puede enviar diariamente
        La lista de donde se toma esta informacion esta en un json
        Mira la configuracion"""
        try: 
            n = 200
            with open(config.ArchivoLimitesHosts) as json_file:
                data = json.load(json_file)
                n = data[host]
        except:
            n = config.LimiteDiario
        return(n)
        

    def chequear_stado_Server(self, User, Pass, Port, Host):
        try:
            self.SMTPcliente(User, Pass, Port, Host)
            consulta = True
        except:
            consulta = False
        return(consulta)

    def ChequearMailServer(self, User, Pass, Port, Host):
        """Chequea estado es el server remoto si esta conectado se almasena la
        respuesta en cache durante 60 segundos para mejorar performance y si no esta
        disponible no se almasena y la proxima respuesta debera hacerse contra el server
        remoto para asegurarme de q se solucione el problema"""
        if Host == "MAILMASIVO":
            return(True)
        test = self.revisarCache(User, Pass, Port, Host)
        if not test == "Vencido":
            return(test)
        W = self.chequear_stado_Server(User, Pass, Port, Host)
        #if False == W:#si hay algun error no actualiso el estado en cache
        #    return(W)
        hora = datetime.datetime.now() + datetime.timedelta(seconds=120)
        self.Consultas[self._GenerarKey(User, Pass, Port, Host)] = {"hora": hora,
        "estado": W}
        print("chequeando servidor de salida", W)
        return(W)

    def revisarCache(self, User, Pass, Port, Host):
        if not self._GenerarKey(User, Pass, Port, Host) in self.Consultas.keys():
            return("Vencido")
        cache = self.Consultas[self._GenerarKey(User, Pass, Port, Host)]
        if datetime.datetime.now() < cache["hora"]:
            return(cache["estado"])
        return("Vencido")

    def _GenerarKey(self, User, Pass,  Port, Host):
        base = """{}-{}-{}-{}"""
        completo = base.format(User, Pass,  str(Port), Host)
        return(completo)

    def SMTPcliente(self, User, Pass, Port, Host):
        dg = smtplib.SMTP(host=Host, port=Port, timeout=10)
        dg.starttls()
        dg.login(User,Pass)
        dg.quit()    


class AndroidStatus():
    """Esta clase manejara estados de la mensajeria de sms via android
    con cache"""
    def __init__(self):
        self.ESTADOS = {}
        self.TOKENs = {}

    def obtenerToken(self, email, clave):
        try:
            ModeloURL = """https://smsgateway24.com/getdata/gettoken?email={}&pass={}"""
            url = ModeloURL.format(email, clave)
            resp = requests.get(url, timeout=10)
            respuesta = resp.json()
        except:
            respuesta = {"error": 1}
        return(respuesta)

    def ObtenerToken(self, email, clave):
        np = """{}-{}""".format(email, clave)
        token = False
        if np in self.TOKENs.keys():
            if self.TOKENs[np]["hora"] > datetime.datetime.now():
                return(self.TOKENs[np]["token"])
            else:
                self.TOKENs.pop(np, None)
        Token = self.obtenerToken(email, clave)
        print(Token)
        if not Token["error"] == 1:
            hora = datetime.datetime.now() + datetime.timedelta(seconds=3600)
            self.TOKENs[np] = {"hora": hora, "token": Token["token"]}
            token = Token["token"]
        return(token)

    def EstadoDispositivo(self, email, clave, dispositivo):
        """{'online': True, 'error': 0, 'message': 'OK', 'device_id': 2183,
        'lastseen': {'date': '2020-08-04 23:15:29.000000', 'timezone_type': 3,
        'timezone': 'UTC'}, 'diffseconds': 34, 'title': 'Redmi_Note_7'}"""
        token = self.ObtenerToken(email, clave)
        Id = token + dispositivo
        try:
            if self.ESTADOS[Id]["hora"] > datetime.datetime.now():
                return(self.ESTADOS[Id]["estado"])
        except:
            pass
        estado = self.estadoDispositivo(token, dispositivo)
        if estado["online"] == True:
            hora = datetime.datetime.now() + datetime.timedelta(seconds=60)
            self.ESTADOS[Id] = {"estado": estado, "hora": hora}
        return(estado)




    def estadoDispositivo(self, token, dispositivo):
        respuesta = {'online': False, "error": True}
        if token == False:
            return(respuesta)
        URL = """https://smsgateway24.com/getdata/getdevicestatus?token={}&device_id={}"""
        url = URL.format(token, dispositivo)
        try:
            resp = requests.get(url, timeout=10)
            respuesta = resp.json()
        except:
            pass
        return(respuesta)