Beispiel #1
0
    def scrapearBusquedaSinCuenta(self, busqueda):

        print(
            f"[SCRAPER] Recuperando artículos de búsqueda '{busqueda.keywords}' del usuario {self.usuario.id_telegram}"
        )
        articulos_recuperados = self.recuperarArticulosWallapop(busqueda)

        gestorBBDD = GestorBBDD()

        for articulo in articulos_recuperados:
            # Si no está en la base de datos, no está estudiado para esta búsqueda.
            excluido = articulo.estaExcluido(busqueda)
            existe = gestorBBDD.existeArticulo(articulo.id_articulo,
                                               busqueda.id_busqueda)

            # Solo notifico
            if (not (excluido) and not (existe)):
                self.notificador.notificarAnuncio(self.usuario.id_telegram,
                                                  articulo, busqueda)

            # Finalmente, lo añado a la base de datos.
            gestorBBDD.insertarArticulo(articulo)
        print(
            f"[SCRAPER] Scrapeo de la búsqueda {busqueda.id_busqueda} del usuario {self.usuario.id_telegram} finalizado."
        )
Beispiel #2
0
    def scrapearBusquedas(self, lista_busquedas_usuario):
        gestorBBDD = GestorBBDD()
        try:
            for busqueda in lista_busquedas_usuario:
                # Verifico si es la primera vez que se realiza la búsqueda
                articulos = gestorBBDD.recuperarArticulosBusqueda(
                    busqueda.id_busqueda)
                no_hay_articulos = len(articulos) == 0

                # Si es la primera vez, añado artículos de una búsqueda inicial, para no notificar de los anuncios ya existentes.
                if (no_hay_articulos):
                    print(
                        f"[SCRAPER] La búsqueda {busqueda.id_busqueda} se lanza por primera vez. Scrapeo artículos iniciales.  "
                    )
                    self.scrapeoInicial(busqueda)

                if (self.tiene_cuenta):
                    self.scrapearBusqueda(busqueda)
                else:
                    self.scrapearBusquedaSinCuenta(busqueda)

            print(
                f"[SCRAPER] Scrapeo de todas las búsquedas del usuario {self.usuario.id_telegram} finalizado."
            )
        except Exception as e:
            print(
                f"[SCRAPER] Error scrapeando las búsquedas de {self.usuario.id_telegram}: {e}. Se aborta el scrapeo..."
            )
        finally:
            self.notificador.notificarFinScrapeo(self.usuario.id_telegram)

            # Cierro el driver y con ello el navegador.
            self.driver.quit()
Beispiel #3
0
    def borrar_busqueda(self, update, context):
        gestorBBDD = GestorBBDD()
        id_telegram = update.message.from_user.id
        opciones = []
        if(gestorBBDD.existeUsuario(id_telegram)):
            print(f"[TELEGRAM] Usuario {id_telegram} quiere borrar búsquedas. ")
            try:
                busquedas = gestorBBDD.recuperarBusquedasUsuario(id_telegram)

                if(len(busquedas) > 0):
                    texto = "¿Qué busqueda quieres borrar?"
                    contador = 1
                    for busqueda in busquedas:
                        texto+=f"\n[{contador}] - {busqueda.keywords} [{busqueda.precio_min},{busqueda.precio_max}]"
                        opciones.append([f"Borrar {contador}"])
                        contador+=1
                    texto+=f"\n Utiliza /cancelar_borrar_busqueda para cancelar el borrado. "
                    keyboard = ReplyKeyboardMarkup(opciones, one_time_keyboard=True)
                    update.message.reply_text(texto, reply_markup=keyboard)
                    return self.STATUS1
                else:
                    update.message.reply_text("No tienes ninguna búsqueda guardada.")
            except:
                update.message.reply_text("No tienes ninguna búsqueda guardada.")

        else:
            update.message.reply_text("No estás registrado. Escribe /registrarse. ")
        return ConversationHandler.END
Beispiel #4
0
    def add_busqueda_siete(self, update, context):
        # Recojo keywords
        lista_keywords_descripcion_reincluyentes = update.message.text
        context.user_data[
            "lista_keywords_descripcion_reincluyentes"] = lista_keywords_descripcion_reincluyentes.split(
                ", ")

        # Habilito comparación solo si el usuario ha metido su cuenta de WP en la BBDD.
        gestorBBDD = GestorBBDD()
        id_telegram = update.message.from_user.id
        usuario = gestorBBDD.recuperarUsuario(id_telegram)
        tiene_cuenta = (usuario.email != "None" and usuario.password != "None")

        if (tiene_cuenta):
            keyboard = ReplyKeyboardMarkup([["Si"], ["No"]],
                                           one_time_keyboard=True)
            texto = "La autocomparación hace que se estudien todos los anuncios nuevos, y solo se te avise de los anuncios que se consideren chollos. Si no la activas, se te avisarán de todos los anuncios. ¿Deseas activar la autocomparación?"
            update.message.reply_text(texto, reply_markup=keyboard)
            return self.STATUS8
        else:
            # Si no tiene cuenta, relleno los campos restantes con valores por defecto,
            # teniendo en cuenta que no se van a utilizar.
            context.user_data["multiplicador_minimo"] = 0.4
            context.user_data["multiplicador_maximo"] = 0.6
            context.user_data["porcentaje_considerado_chollo"] = 0.2

            context.user_data["comparar_automaticamente"] = False
            context.user_data["enviar_mensaje_auto"] = False
            texto = "Muy bien. Guardando búsqueda... "
            update.message.reply_text(texto)
            self.guardarBusqueda(id_telegram, update, context)
            return ConversationHandler.END
Beispiel #5
0
 def iniciar_registro(self, update, context):
     # Si ya tiene cuenta, no dejo que se registre.
     gestorBBDD = GestorBBDD()
     id_telegram = update.message.from_user.id
     if(gestorBBDD.existeUsuario(id_telegram)):
         update.message.reply_text("Ya tienes una cuenta, no puedes añadir otra. Puedes borrar la previamente introducida con /borrar_cuenta. ")
         return ConversationHandler.END
     # Si no, pido código de invitación.
     else:
         print(f"[TELEGRAM] usuario {id_telegram} empieza a registrarse.")
         update.message.reply_text("Introduce código de invitación o usa /cancelar_registro en cualquier momento para cancelar el registro: ", reply_markup=ForceReply())
         return self.STATUS1
Beispiel #6
0
 def start(self, update, context):
     id_telegram = update.message.from_user.id
     nombre_usuario = update.message.from_user.username
     print(f"[TELEGRAM] Usuario {id_telegram} lanza /start. ")
     gestorBBDD = GestorBBDD()
     context.user_data["tiene_cuenta"] = gestorBBDD.existeUsuario(update.message.from_user.id)
     context.user_data["email"] = ""
     context.user_data["password"] = ""
     context.user_data["mensaje"] = ""
     context.user_data["codigo_postal"] = ""
     bienvenida = f'¡Hola {nombre_usuario}! Soy un bot para actualizarte con los nuevos anuncios que se suban en Wallapop. Utiliza /ayuda para ver los comandos disponibles.'
     update.message.reply_text(bienvenida)
Beispiel #7
0
    def __init__(self,
                 usuario,
                 notificador,
                 recursos="altos",
                 ejecucion_en_background=False):

        # Cargo el notificador
        self.notificador = notificador

        # Recupero usuario y veo si tiene cuenta
        self.usuario = usuario
        self.tiene_cuenta = (self.usuario.email !=
                             None) and (self.usuario.password != None)

        # Recupero búsquedas de la BBDD
        gestorBBDD = GestorBBDD()
        self.lista_busquedas = gestorBBDD.recuperarBusquedasUsuario(
            self.usuario.id_telegram)

        # Ajustes de configuración del webdriver
        self.recursos = recursos
        self.ejecucion_en_bakcground = ejecucion_en_background

        # Ignoro errores de certificado
        self.options = webdriver.ChromeOptions()
        self.options.add_argument('--ignore-certificate-errors')
        self.options.add_argument('--ignore-ssl-errors')
        self.options.add_argument("--start-maximized")
        self.options.add_argument("log-level=3")
        self.options.add_argument("--silent")

        # Configuro ventana para su ejecución en segundo plano
        if (ejecucion_en_background):
            self.options.add_argument('--disable-gpu')
            self.options.add_argument('--headless')
            self.options.add_argument("--window-size=1920x1080")

        # Si el host es un ordenador con bajos recursos, abrirá ventanas de una en una cerrándolas
        # en lugar de varias de golpe
        if (self.recursos == "bajos"):
            self.driver = webdriver.Chrome(ChromeDriverManager().install(),
                                           options=self.options)

        else:
            caps = DesiredCapabilities().CHROME
            caps["pageLoadStrategy"] = "eager"
            self.driver = webdriver.Chrome(ChromeDriverManager().install(),
                                           desired_capabilities=caps,
                                           options=self.options)

        # Lanzo el bot
        self.iniciarBot()
Beispiel #8
0
    def iniciar(self, update, context):
        id_telegram = update.message.from_user.id
        print(f"[TELEGRAM] Usuario {id_telegram} lanza /iniciar. ")
        gestorBBDD = GestorBBDD()
        if(gestorBBDD.existeUsuario(id_telegram) and len(gestorBBDD.recuperarBusquedasUsuario(id_telegram)) > 0):
            if(self.diccionario_scrapers.get(id_telegram) == None):
                usuario = gestorBBDD.recuperarUsuario(id_telegram)
                busquedas_usuario = gestorBBDD.recuperarBusquedasUsuario(id_telegram)
                for busqueda in busquedas_usuario:
                    # Si está activada la autocomparación, borro artículos anteriores
                    # y relleno con los nuevos desde scraperwallapop, de forma que
                    # solo se van comparando los artículos nuevos subidos.
                    if(busqueda.comparar_automaticamente == True):
                        print(f"[TELEGRAM] Borro artículos previos de la búsqueda {busqueda.keywords} del usuario {id_telegram} porque tiene autocomparación. ")
                        gestorBBDD.borrarArticulosBusqueda(busqueda.id_busqueda)

                notificador = Notificador(self.TOKEN)
                tarea = TareaPeriodica(10, ScraperWallapop, usuario, notificador, ejecucion_en_background=False)
                update.message.reply_text("Iniciando scrapeo. ")
                self.diccionario_scrapers[id_telegram] = tarea
                tarea.start()
            else:
                update.message.reply_text("Ya se está scrapeando, utiliza /detener para detener el scrapeo.")

        else:
            update.message.reply_text("Debes tener una cuenta y al menos una búsqueda para iniciar el scrapeo. ")
Beispiel #9
0
 def borrar_cuenta(self, update, context):
     gestorBBDD = GestorBBDD()
     id_telegram = update.message.from_user.id
     print(f"[TELEGRAM] Usuario {id_telegram} va a borrar su cuenta. ")
     if (gestorBBDD.existeUsuario(id_telegram)):
         texto = "Se borrará tu cuenta y todas las búsquedas y artículos guardados asociados. Esta acción no se puede deshacer. ¿Estás seguro de que quieres continuar?"
         reply_keyboard = [["Si"], ["No"]]
         keyboard = ReplyKeyboardMarkup(reply_keyboard,
                                        one_time_keyboard=True)
         update.message.reply_text(texto, reply_markup=keyboard)
         return self.STATUS1
     else:
         update.message.reply_text(
             "Debes haberte registrado para poder borrar tu cuenta.")
         return ConversationHandler.END
Beispiel #10
0
 def add_busqueda(self, update, context):
     gestorBBDD = GestorBBDD()
     id_telegram = update.message.from_user.id
     if (gestorBBDD.existeUsuario(id_telegram)):
         print(
             f"[TELEGRAM] Usuario {id_telegram} comienza a registrar búsqueda. "
         )
         self.iniciar_diccionario_busqueda(update, context)
         update.message.reply_text(
             "Introduce las keywords de tu búsqueda o utiliza en cualquier momento /cancelar_add_busqueda para cancelar.",
             reply_markup=ForceReply())
         return self.STATUS1
     else:
         update.message.reply_text(
             "Necesitas registrarte para poder añadir una búsqueda. Usa /registrarse ."
         )
Beispiel #11
0
    def scrapearBusqueda(self, busqueda):

        print(
            f"[SCRAPER] Recuperando artículos de búsqueda '{busqueda.keywords}'"
        )
        articulos_recuperados = self.recuperarArticulosWallapop(busqueda)

        gestorBBDD = GestorBBDD()

        for articulo in articulos_recuperados:
            # Si no está en la base de datos, no está estudiado para esta búsqueda.
            excluido = articulo.estaExcluido(busqueda)
            existe = gestorBBDD.existeArticulo(articulo.id_articulo,
                                               busqueda.id_busqueda)

            if (not (excluido) and not (existe)):

                # Lo añado a la base de datos.
                gestorBBDD.insertarArticulo(articulo)

                # Si está activada la autocomparación, pues comparo.
                if (busqueda.comparar_automaticamente):

                    preciosArticulo = self.__extraerPreciosArticulo(
                        articulo, busqueda)
                    chollo = self.__esChollo(articulo, busqueda,
                                             preciosArticulo)

                    if (chollo):
                        print(
                            f"[SCRAPER] El usuario {self.usuario.id_telegram} ha encontrado un chollo: {articulo.titulo} - {articulo.precio} [{articulo.enlace}]"
                        )
                        self.notificador.notificarChollo(
                            self.usuario.id_telegram, articulo, busqueda)
                        if (busqueda.enviar_mensaje_auto):
                            self.enviarMensaje(articulo)
                    else:
                        print(
                            f"[SCRAPER] El usuario {self.usuario.id_telegram} ha analizado {articulo.titulo} - {articulo.precio}, pero no es un chollo..."
                        )
                # Si no está activada la autocomparación, solo notifico.
                else:
                    self.notificador.notificarAnuncio(self.usuario.id_telegram,
                                                      articulo, busqueda)
        print(
            f"[SCRAPER] Scrapeo de la búsqueda {busqueda.id_busqueda} del usuario {self.usuario.id_telegram} finalizado."
        )
Beispiel #12
0
    def guardarBusqueda(self, id_telegram, update, context):
        gestorBBDD = GestorBBDD()
        try:
            exclusiones = ExclusionesBusqueda(
                list(context.user_data["lista_keywords_titulo_excluyentes"]),
                list(context.
                     user_data["lista_keywords_descripcion_excluyentes"]),
                list(context.
                     user_data["lista_keywords_descripcion_reincluyentes"]),
                float(context.user_data["multiplicador_maximo"]),
                float(context.user_data["multiplicador_minimo"]),
                float(context.user_data["porcentaje_considerado_chollo"]))

            busqueda = BusquedaWallapop(
                id_telegram,
                None,  # Porque la id de búsqueda se asigna dentro de insertar búsqueda.
                exclusiones,
                str(context.user_data["keywords"]),
                bool(context.user_data["enviar_mensaje_auto"]),
                bool(context.user_data["comparar_automaticamente"]),
                float(context.user_data["precio_min"]),
                float(context.user_data["precio_max"]),
                int(context.user_data["radio_km"]),
            )
            gestorBBDD.insertarBusqueda(busqueda)
            update.message.reply_text("¡Búsqueda guardada!")
            print(f"[TELEGRAM] Usuario {id_telegram} registra búsqueda: ")
            print(
                f"[TELEGRAM] {gestorBBDD.recuperarBusqueda(gestorBBDD.getMaxIdBusqueda())}"
            )
            self.limpiarBusqueda(context)
        except:
            update.message.reply_text(
                "No se ha podido crear la búsqueda. ¿Seguro que has introducido bien los parámetros? Recuerda que los porcentajes se deben poner con un punto, por ej. 0.4."
            )
            self.limpiarBusqueda(context)
Beispiel #13
0
 def confirmar_borrar_cuenta(self, update, context):
     parametro = update.message.text.lower()
     gestorBBDD = GestorBBDD()
     id_telegram = update.message.from_user.id
     if (parametro == "si"):
         # Primero borro búsquedas y articulos contenidos
         busquedas = gestorBBDD.recuperarBusquedasUsuario(id_telegram)
         for busqueda in busquedas:
             gestorBBDD.borrarBusqueda(busqueda.id_busqueda)
         # Después, borro al usuario
         gestorBBDD.borrarUsuario(id_telegram)
         self.limpiar_datos(context)
         update.message.reply_text(f"Cuenta borrada.")
         print(
             f"[TELEGRAM] Usuario {id_telegram} borra su cuenta y búsquedas asociadas. "
         )
         return ConversationHandler.END
     else:
         update.message.reply_text("Borrado de cuenta cancelado. ")
         return ConversationHandler.END
Beispiel #14
0
 def borrar_busqueda_uno(self, update, context):
     # Extraigo el nº de búsqueda a borrar
     numero_busqueda_a_borrar = int(update.message.text.split(" ")[-1])
     id_telegram = update.message.from_user.id
     gestor = GestorBBDD()
     try:
         busqueda =  gestor.recuperarBusquedasUsuario(id_telegram)[numero_busqueda_a_borrar-1]
         id_busqueda = busqueda.id_busqueda
         if(gestor.existeBusqueda(id_busqueda)):
             gestor.borrarBusqueda(id_busqueda)
             print(f"[TELEGRAM] Búsqueda {id_busqueda} del usuario {id_telegram} borrada. ")
             update.message.reply_text(f"¡Busqueda '{busqueda.keywords}' borrada!")
             return ConversationHandler.END
         else:
             update.message.reply_text(f"Error, búsqueda no encontrada en la base de datos. ")
             return ConversationHandler.END
     except:
         update.message.reply_text(f"Error, búsqueda no encontrada en la base de datos. ")
         return ConversationHandler.END
Beispiel #15
0
 def scrapeoInicial(self, busqueda):
     gestorBBDD = GestorBBDD()
     articulos = self.recuperarArticulosWallapop(busqueda)
     for articulo in articulos:
         if (not (articulo.estaExcluido(busqueda))):
             gestorBBDD.insertarArticulo(articulo)
Beispiel #16
0
    def recoge_codigo_postal_probar_credenciales(self, update, context):
        codigo_postal = update.message.text
        id_telegram = update.message.from_user.id
        correcto = False
        print(f"[TELEGRAM] Usuario {id_telegram} mete codigo postal: {codigo_postal}.")
        try:
            ccaa = int(codigo_postal[:2])
            if(ccaa in range(1,53) and len(codigo_postal) == 5):
                correcto = True
        except:
            pass

        if(not(correcto)):
            update.message.reply_text("Código postal incorrecto. Registro cancelado. ")
            return ConversationHandler.END
        else:
            context.user_data["codigo_postal"] = codigo_postal

        # Si introduce cuenta de wp, pruebo credenciales.
        if(context.user_data["tiene_cuenta"]):
            texto = "Código postal guardado. Vamos a probar tu cuenta. Esto puede durar unos segundos..."
            update.message.reply_text(texto)
            usuario = Usuario(update.message.from_user.id,
                              context.user_data["email"],
                              context.user_data["pass_wallapop"],
                              context.user_data["codigo_postal"],
                              context.user_data["mensaje_wallapop"])
            bot = TestCredenciales(usuario, ejecucion_en_background=True)
            if(bot.probarCredenciales()):
                # Registro al usuario en la BBDD
                gestorBBDD = GestorBBDD()
                gestorBBDD.insertarUsuario(usuario)

                # Muestro datos guardados.
                texto = f"""Credenciales correctos. Cuenta guardada:
                - Email: {context.user_data["email"]}
                - Password: {context.user_data["pass_wallapop"]}
                - Mensaje automático: {context.user_data["mensaje_wallapop"]}
                - Código postal: {context.user_data["codigo_postal"]}
                """
                update.message.reply_text(texto)

                # Logueo
                id_telegram = update.message.from_user.id
                if(gestorBBDD.existeUsuario(usuario.id_telegram)):
                    print(f"[TELEGRAM] Usuario {id_telegram} registrado con éxito.")
            else:
                update.message.reply_text("Credenciales erróneos. Registro cancelado y datos borrados. ")
                self.limpiar_datos(context)
        # Si no tiene cuenta
        else:
            # Solo le inserto en la bbdd
            usuario = Usuario(update.message.from_user.id,
                              None,
                              None,
                              context.user_data["codigo_postal"],
                              None)
            gestorBBDD = GestorBBDD()
            gestorBBDD.insertarUsuario(usuario)
            update.message.reply_text("Registrado como usuario sin cuenta en la BBDD.")
            print(f"[TELEGRAM] Usuario {id_telegram} registrado como usuario sin cuenta con éxito.")
        return ConversationHandler.END