Files
wallamanta/wallamanta/alert.py
2023-03-04 22:57:05 +01:00

156 lines
6.6 KiB
Python

import json
import os
import threading
import logging
import prettytable
import helpers
import walladb
from worker import Worker
from telegram import Update
from telegram.ext import Application, CommandHandler, ContextTypes
TELEGRAM_CHANNEL_ID = os.getenv("TELEGRAM_CHANNEL_ID")
TELEGRAM_TOKEN = os.getenv("TELEGRAM_TOKEN")
LATITUDE = os.getenv("LATITUDE")
LONGITUDE = os.getenv("LONGITUDE")
SLEEP_TIME = os.getenv("SLEEP_TIME")
# Enable logging
logging.basicConfig(
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO
)
logger = logging.getLogger(__name__)
def parse_json_file():
f = open("/app/data/products.json")
return json.load(f)
def save_json_file(products):
with open('/app/data/products.json', 'w') as outfile:
json.dump(products, outfile, indent=2)
async def help_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""Send a message when the command /help is issued."""
message = """Añade un producto con `/add producto;precio_mínimo;precio_máximo,excluir_título(opcional, separado por comas);excluir_descripción_y_título(opciona, separado por comas);latitud(opcional);longitud(opcional),distancia(opcional)`\n
Ejemplo: `/add placa base itx;0;150`\n
Ejemplo 2: `/add cpu;10;30;;intel,core 2 duo,celeron;;;100`\n
Los campos opcionales que se dejen vacíos tomarán el valor configurado en el archivo `.env`\n
Lista los productos con `/list` o obtén la información de uno en concreto con `/list nombre del producto`\n
Borra un producto con `/remove nombre del producto`"""
await update.message.reply_markdown_v2(helpers.telegram_escape_characters(message))
async def add_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
message = """Tienes que pasar el número correcto de parámetros: `/add producto;precio_mínimo;precio_máximo,excluir_título(opcional, separado por comas);excluir_descripción_y_título(opciona, separado por comas);latitud(opcional);longitud(opcional),distancia(opcional)`\n
Ejemplo: `/add placa base itx;0;150`\n
Ejemplo 2: `/add cpu;10;30;;intel,core 2 duo,celeron;;;100`\n
Los campos opcionales que se dejen vacíos tomarán el valor configurado en el archivo `.env`"""
args = update.message.text.split("/add ")
if len(args) == 1:
pass
elif len(args[1].split(";")) > 2:
args = args[1].split(";")
logging.info(f'Adding: {args}')
title_exclude, title_description_exclude, latitude, longitude, distance = [], [], LATITUDE, LONGITUDE, "0"
product_name, min_price, max_price = args[0:3]
if len(args) > 3 and args[3]:
title_exclude = args[3].split(",")
if len(args) > 4 and args[4]:
title_description_exclude = args[4].split(",")
if len(args) > 5 and args[5]:
latitude = args[5]
if len(args) > 6 and args[6]:
longitude = args[6]
if len(args) > 7 and args[7]:
distance = args[7]
product = {"product_name": product_name,
"distance": distance,
"latitude": latitude,
"longitude": longitude,
"condition": "all",
"min_price": min_price,
"max_price": max_price,
"title_keyword_exclude" : title_exclude,
"exclude": title_description_exclude
}
products = parse_json_file()
found = False
for fproduct in products:
if fproduct['product_name'] == product_name:
found = True
if not found:
products.append(product)
save_json_file(products)
p = threading.Thread(target=Worker.run, args=(product, ))
p.start()
message = f"Añadido {product_name} a seguimiento"
else:
message = f"{product_name} ya está en seguimiento!"
await update.message.reply_markdown_v2(helpers.telegram_escape_characters(message))
async def remove_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
product_to_remove = update.message.text[len('/remove '):]
message = f"{product_to_remove} no está en seguimiento!"
products = parse_json_file()
for product in products:
if product['product_name'] == product_to_remove:
products.remove(product)
message = f"{product_to_remove} borrado!"
save_json_file(products)
await update.message.reply_text(message)
async def list_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
products = parse_json_file()
args = update.message.text.split("/list ")
found = False
if len(args) > 1:
table = prettytable.PrettyTable(['Campo', 'Valor'])
table.align['Campo'] = 'l'
table.align['Valor'] = 'r'
for product in products:
if product['product_name'] == args[1]:
for key in product:
table.add_row([key, product[key]])
found = True
break
if not found:
table = prettytable.PrettyTable(['Producto', 'Mín', 'Máx'])
table.align['Producto'] = 'l'
table.align['Mín'] = 'r'
table.align['Máx'] = 'r'
for product in products:
table.add_row([helpers.telegram_escape_characters(product['product_name']), f"{helpers.telegram_escape_characters(product['min_price'])}", f"{helpers.telegram_escape_characters(product['max_price'])}"])
await update.message.reply_markdown_v2(f'```{(table)}```')
def main()->None:
walladb.setup_db()
products = parse_json_file()
for product in products:
logging.info(product)
p = threading.Thread(target=Worker.run, args=(product, ))
p.start()
"""Start the bot."""
# Create the Application and pass it your bot's token.
application = Application.builder().token(TELEGRAM_TOKEN).build()
# on different commands - answer in Telegram
application.add_handler(CommandHandler("help", help_command))
application.add_handler(CommandHandler("add", add_command))
application.add_handler(CommandHandler("remove", remove_command))
application.add_handler(CommandHandler("list", list_command))
# on non command i.e message - echo the message on Telegram
#application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, echo))
# Run the bot until the user presses Ctrl-C
application.run_polling()
if __name__ == "__main__":
main()