Added button to product found. Added product_name to know from which search provides the article found.
This commit is contained in:
@@ -6,7 +6,9 @@ import constants
|
|||||||
|
|
||||||
from PIL import Image, ImageDraw, ImageFont
|
from PIL import Image, ImageDraw, ImageFont
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from telegram import InlineKeyboardButton
|
from telegram import InlineKeyboardButton, InlineKeyboardMarkup
|
||||||
|
from telegram.ext import Application
|
||||||
|
from telegram.constants import ParseMode
|
||||||
|
|
||||||
# Enable logging
|
# Enable logging
|
||||||
logging.basicConfig(
|
logging.basicConfig(
|
||||||
@@ -111,12 +113,18 @@ def create_image(article):
|
|||||||
# guardamos la imagen con otro nombre
|
# guardamos la imagen con otro nombre
|
||||||
image.save(f"/app/data/images/products/{article['id']}_composed.png", quality=95)
|
image.save(f"/app/data/images/products/{article['id']}_composed.png", quality=95)
|
||||||
|
|
||||||
def send_article(article, product):
|
async def send_article(article, product):
|
||||||
|
application = Application.builder().get_updates_http_version('1.1').http_version('1.1').token(constants.TELEGRAM_TOKEN).build()
|
||||||
create_image(article)
|
create_image(article)
|
||||||
text = f"*{telegram_escape_characters(article['title'])}*\n\n*Descripción*: {telegram_escape_characters(article['description'])}\n\n*Precio*: {telegram_escape_characters(str(article['price']))} {telegram_escape_characters(article['currency'])}\n\n[IR AL ANUNCIO](https://es\.wallapop\.com/item/{telegram_escape_characters(article['web_slug'])})"
|
text = f"*{telegram_escape_characters(article['title'])}*\n\n*Descripción*: {telegram_escape_characters(article['description'])}\n\n*Encontrado por la búsqueda de:*{telegram_escape_characters(product['product_name'])}\n\n*Precio*: {telegram_escape_characters(str(article['price']))} {telegram_escape_characters(article['currency'])}"
|
||||||
url = f"https://api.telegram.org/bot{constants.TELEGRAM_TOKEN}/sendPhoto?chat_id={product['telegram_user_id']}&caption={text}&parse_mode=MarkdownV2"
|
#url = f"https://api.telegram.org/bot{constants.TELEGRAM_TOKEN}/sendPhoto?chat_id={product['telegram_user_id']}&caption={text}&parse_mode=MarkdownV2"
|
||||||
files = {'photo':open(f"/app/data/images/products/{article['id']}_composed.png", 'rb')}
|
#files = {'photo':open(f"/app/data/images/products/{article['id']}_composed.png", 'rb')}
|
||||||
logging.info(requests.post(url, files=files).content)
|
keyboard = [[InlineKeyboardButton("Ir al anuncio", url=f"https://es.wallapop.com/item/{article['web_slug']}")]]
|
||||||
|
#InlineKeyboardButton("Listar productos", callback_data="list")]
|
||||||
|
markup = InlineKeyboardMarkup(keyboard)
|
||||||
|
response = await application.bot.send_photo(chat_id=product['telegram_user_id'], photo=open(f"/app/data/images/products/{article['id']}_composed.png", 'rb'), caption=text, parse_mode=ParseMode.MARKDOWN_V2, reply_markup=markup)
|
||||||
|
#logging.info(requests.post(url, files=files).content)
|
||||||
|
logging.info(response)
|
||||||
|
|
||||||
def get_category_id(category):
|
def get_category_id(category):
|
||||||
ret = constants.CATEGORIES.get(category, '')
|
ret = constants.CATEGORIES.get(category, '')
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ def add_test_user(telegram_user_id, telegram_name, until):
|
|||||||
found = False
|
found = False
|
||||||
con = sqlite3.connect(constants.DB)
|
con = sqlite3.connect(constants.DB)
|
||||||
cur = con.cursor()
|
cur = con.cursor()
|
||||||
params = (telegram_name,)
|
params = (telegram_user_id,)
|
||||||
res = cur.execute(f"SELECT * FROM users WHERE telegram_user_id=?", params)
|
res = cur.execute(f"SELECT * FROM users WHERE telegram_user_id=?", params)
|
||||||
if res.fetchone() is None:
|
if res.fetchone() is None:
|
||||||
params = (telegram_user_id, True, 'testing', until, telegram_name.first_name)
|
params = (telegram_user_id, True, 'testing', until, telegram_name.first_name)
|
||||||
@@ -119,6 +119,19 @@ def get_user_list():
|
|||||||
con.close()
|
con.close()
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
def get_user(telegram_user_id):
|
||||||
|
con = sqlite3.connect(constants.DB)
|
||||||
|
con.row_factory = dict_factory
|
||||||
|
cur = con.cursor()
|
||||||
|
params = (telegram_user_id,)
|
||||||
|
res = cur.execute(f"SELECT telegram_name FROM users WHERE telegram_user_id=?", params)
|
||||||
|
if res != None:
|
||||||
|
ret = res.fetchone()['telegram_name']
|
||||||
|
else:
|
||||||
|
ret = 'NoName'
|
||||||
|
con.close()
|
||||||
|
return ret
|
||||||
|
|
||||||
def get_user_type(telegram_user_id):
|
def get_user_type(telegram_user_id):
|
||||||
con = sqlite3.connect(constants.DB)
|
con = sqlite3.connect(constants.DB)
|
||||||
cur = con.cursor()
|
cur = con.cursor()
|
||||||
|
|||||||
@@ -91,16 +91,21 @@ async def menu_click_handler(update: Update, context: CallbackContext):
|
|||||||
|
|
||||||
async def add_product_name(update: Update, context: CallbackContext):
|
async def add_product_name(update: Update, context: CallbackContext):
|
||||||
if context.user_data.get('product_name', '') == '':
|
if context.user_data.get('product_name', '') == '':
|
||||||
answer = update.message.text
|
product_name = update.message.text
|
||||||
context.user_data['product_name'] = answer
|
if len(product_name) > 200:
|
||||||
if not walladb.get_product(context.user_data):
|
|
||||||
await context.bot.send_message(chat_id=update.effective_chat.id,
|
await context.bot.send_message(chat_id=update.effective_chat.id,
|
||||||
text='Escribe el precio mínimo', reply_markup=ForceReply())
|
text='El nombre del producto a buscar es muy largo, pon otro nombre', reply_markup=ForceReply())
|
||||||
return ADD_PRODUCT_MIN_PRICE
|
return ADD_PRODUCT_NAME
|
||||||
else:
|
else:
|
||||||
await context.bot.send_message(chat_id=update.effective_chat.id,
|
context.user_data['product_name'] = product_name
|
||||||
text=f"¡{walladb.get_product(context.user_data)['product_name']} ya está en seguimiento!")
|
if not walladb.get_product(context.user_data):
|
||||||
return ConversationHandler.END
|
await context.bot.send_message(chat_id=update.effective_chat.id,
|
||||||
|
text='Escribe el precio mínimo', reply_markup=ForceReply())
|
||||||
|
return ADD_PRODUCT_MIN_PRICE
|
||||||
|
else:
|
||||||
|
await context.bot.send_message(chat_id=update.effective_chat.id,
|
||||||
|
text=f"¡{walladb.get_product(context.user_data)['product_name']} ya está en seguimiento!")
|
||||||
|
return ConversationHandler.END
|
||||||
|
|
||||||
async def add_product_min_price(update: Update, context: CallbackContext):
|
async def add_product_min_price(update: Update, context: CallbackContext):
|
||||||
if context.user_data.get('min_price', '') == '':
|
if context.user_data.get('min_price', '') == '':
|
||||||
@@ -111,9 +116,9 @@ async def add_product_min_price(update: Update, context: CallbackContext):
|
|||||||
await context.bot.send_message(chat_id=update.effective_chat.id,
|
await context.bot.send_message(chat_id=update.effective_chat.id,
|
||||||
text='Pon un precio mínimo en números', reply_markup=ForceReply())
|
text='Pon un precio mínimo en números', reply_markup=ForceReply())
|
||||||
return ADD_PRODUCT_MIN_PRICE
|
return ADD_PRODUCT_MIN_PRICE
|
||||||
if min_price < 0:
|
if min_price < 0 or min_price > 999999:
|
||||||
await context.bot.send_message(chat_id=update.effective_chat.id,
|
await context.bot.send_message(chat_id=update.effective_chat.id,
|
||||||
text='Pon un precio mínimo en números que no sean negativos', reply_markup=ForceReply())
|
text='Pon un precio mínimo entre 0 y 999999', reply_markup=ForceReply())
|
||||||
return ADD_PRODUCT_MIN_PRICE
|
return ADD_PRODUCT_MIN_PRICE
|
||||||
context.user_data['min_price'] = min_price
|
context.user_data['min_price'] = min_price
|
||||||
await context.bot.send_message(chat_id=update.effective_chat.id,
|
await context.bot.send_message(chat_id=update.effective_chat.id,
|
||||||
@@ -129,9 +134,13 @@ async def add_product_max_price(update: Update, context: CallbackContext):
|
|||||||
await context.bot.send_message(chat_id=update.effective_chat.id,
|
await context.bot.send_message(chat_id=update.effective_chat.id,
|
||||||
text='Pon un precio máximo en números', reply_markup=ForceReply())
|
text='Pon un precio máximo en números', reply_markup=ForceReply())
|
||||||
return ADD_PRODUCT_MAX_PRICE
|
return ADD_PRODUCT_MAX_PRICE
|
||||||
if max_price < 0:
|
if max_price < 0 or max_price > 999999:
|
||||||
await context.bot.send_message(chat_id=update.effective_chat.id,
|
await context.bot.send_message(chat_id=update.effective_chat.id,
|
||||||
text='Pon un precio máximo en números que no sean negativos', reply_markup=ForceReply())
|
text='Pon un precio máximo entre 0 y 999999', reply_markup=ForceReply())
|
||||||
|
return ADD_PRODUCT_MAX_PRICE
|
||||||
|
if max_price < context.user_data['min_price']:
|
||||||
|
await context.bot.send_message(chat_id=update.effective_chat.id,
|
||||||
|
text='Pon un precio máximo menor al precio mínimo', reply_markup=ForceReply())
|
||||||
return ADD_PRODUCT_MAX_PRICE
|
return ADD_PRODUCT_MAX_PRICE
|
||||||
context.user_data['max_price'] = max_price
|
context.user_data['max_price'] = max_price
|
||||||
keyboard = [
|
keyboard = [
|
||||||
@@ -340,7 +349,7 @@ async def add_to_db_and_send(update: Update, context: ContextTypes.DEFAULT_TYPE)
|
|||||||
walladb.add_product(context.user_data)
|
walladb.add_product(context.user_data)
|
||||||
p = threading.Thread(target=Worker.run, args=(walladb.get_product(context.user_data), ))
|
p = threading.Thread(target=Worker.run, args=(walladb.get_product(context.user_data), ))
|
||||||
p.start()
|
p.start()
|
||||||
await context.bot.send_message(chat_id=update.effective_chat.id, text=f"¡*{context.user_data['product_name']}* añadido correctamente\!", parse_mode=ParseMode.MARKDOWN_V2)
|
await context.bot.send_message(chat_id=update.effective_chat.id, text=f"¡*{helpers.telegram_escape_characters(context.user_data['product_name'])}* añadido correctamente\!", parse_mode=ParseMode.MARKDOWN_V2)
|
||||||
|
|
||||||
def error(update, context):
|
def error(update, context):
|
||||||
logging.error(f'Update ---{update}--- caused error ---{context.error}---')
|
logging.error(f'Update ---{update}--- caused error ---{context.error}---')
|
||||||
@@ -371,6 +380,8 @@ def main()->None:
|
|||||||
application.add_handler(CommandHandler("remove_user", remove_user_command))
|
application.add_handler(CommandHandler("remove_user", remove_user_command))
|
||||||
application.add_handler(CommandHandler("status", status_command))
|
application.add_handler(CommandHandler("status", status_command))
|
||||||
application.add_handler(CommandHandler("test", test_command))
|
application.add_handler(CommandHandler("test", test_command))
|
||||||
|
#application.add_handler(CallbackQueryHandler("list", send_list()))
|
||||||
|
#application.add_handler(CallbackQueryHandler(pattern="list", callback=send_list()))
|
||||||
|
|
||||||
conv_handler = ConversationHandler(
|
conv_handler = ConversationHandler(
|
||||||
conversation_timeout=60,
|
conversation_timeout=60,
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import logging
|
|||||||
import helpers
|
import helpers
|
||||||
import walladb
|
import walladb
|
||||||
import constants
|
import constants
|
||||||
|
import asyncio
|
||||||
|
|
||||||
# Enable logging
|
# Enable logging
|
||||||
logging.basicConfig(
|
logging.basicConfig(
|
||||||
@@ -56,6 +57,7 @@ class Worker:
|
|||||||
return json_data['search_objects']
|
return json_data['search_objects']
|
||||||
|
|
||||||
def first_run(self, product):
|
def first_run(self, product):
|
||||||
|
logging.info(f"First run for {product['product_name']} for {walladb.get_user(product['telegram_user_id'])}")
|
||||||
for i in range(5):
|
for i in range(5):
|
||||||
helpers.random_wait()
|
helpers.random_wait()
|
||||||
list = []
|
list = []
|
||||||
@@ -66,7 +68,7 @@ class Worker:
|
|||||||
list.insert(0, article['id'])
|
list.insert(0, article['id'])
|
||||||
return list
|
return list
|
||||||
|
|
||||||
def work(self, product, list):
|
async def work(self, product, list):
|
||||||
helpers.random_wait() # Random wait to make requests separated in time in order to prevent API rate limit
|
helpers.random_wait() # Random wait to make requests separated in time in order to prevent API rate limit
|
||||||
exec_times = []
|
exec_times = []
|
||||||
while True:
|
while True:
|
||||||
@@ -81,18 +83,20 @@ class Worker:
|
|||||||
try:
|
try:
|
||||||
if not self.has_excluded_words(article['title'].lower(), article['description'].lower(), product['title_description_exclude']) and not self.is_title_key_word_excluded(article['title'].lower(), product['title_exclude']):
|
if not self.has_excluded_words(article['title'].lower(), article['description'].lower(), product['title_description_exclude']) and not self.is_title_key_word_excluded(article['title'].lower(), product['title_exclude']):
|
||||||
try:
|
try:
|
||||||
helpers.send_article(article, product)
|
await helpers.send_article(article, product)
|
||||||
except:
|
except:
|
||||||
helpers.send_article(article, product)
|
await helpers.send_article(article, product)
|
||||||
time.sleep(1) # Avoid Telegram flood restriction
|
await asyncio.sleep(1)
|
||||||
|
#time.sleep(1) # Avoid Telegram flood restriction
|
||||||
list.insert(0, article['id'])
|
list.insert(0, article['id'])
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.info("---------- EXCEPTION -----------")
|
logging.info("---------- EXCEPTION -----------")
|
||||||
logging.info(f"{product['product_name']} worker crashed. {e}")
|
logging.info(f"{product['product_name']} worker crashed. {e}")
|
||||||
logging.info(f"{product['product_name']}: Trying to parse {article['id']}: {article['title']} .\n")
|
logging.info(f"{product['product_name']}: Trying to parse {article['id']}: {article['title']} .\n")
|
||||||
time.sleep(constants.SLEEP_TIME)
|
#time.sleep(constants.SLEEP_TIME)
|
||||||
|
await asyncio.sleep(constants.SLEEP_TIME)
|
||||||
exec_times.append(time.time() - start_time)
|
exec_times.append(time.time() - start_time)
|
||||||
logging.info(f"\'{product['product_name']}\' node-> last: {exec_times[-1]} max: {self.get_max_time(exec_times)} avg: {self.get_average_time(exec_times)}")
|
logging.info(f"\'{product['product_name']}\' for {walladb.get_user(product['telegram_user_id'])} ({product['telegram_user_id']}) node-> last: {exec_times[-1]:.2f} max: {self.get_max_time(exec_times):.2f} avg: {self.get_average_time(exec_times):.2f}")
|
||||||
|
|
||||||
def has_excluded_words(self, title, description, excluded_words):
|
def has_excluded_words(self, title, description, excluded_words):
|
||||||
if len(excluded_words) > 0:
|
if len(excluded_words) > 0:
|
||||||
@@ -125,13 +129,30 @@ class Worker:
|
|||||||
largest = i
|
largest = i
|
||||||
return largest
|
return largest
|
||||||
|
|
||||||
|
async def old_run(product):
|
||||||
|
worker = Worker()
|
||||||
|
list = worker.first_run(product)
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
logging.info(f"Wallapop monitor worker started. Checking for new items containing: \'{product['product_name']}\' for {walladb.get_user(product['telegram_user_id'])} ({product['telegram_user_id']}) with given parameters periodically")
|
||||||
|
await worker.work(product, list)
|
||||||
|
break
|
||||||
|
except Exception as e:
|
||||||
|
logging.info(f"Exception: {e}")
|
||||||
|
logging.info(f"{product['product_name']} worker crashed. Restarting worker...")
|
||||||
|
await asyncio.sleep(10)
|
||||||
|
#time.sleep(10)
|
||||||
|
logging.info(f"Wallapop monitor worker stopped for: \'{product['product_name']}\'")
|
||||||
|
|
||||||
def run(product):
|
def run(product):
|
||||||
worker = Worker()
|
worker = Worker()
|
||||||
list = worker.first_run(product)
|
list = worker.first_run(product)
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
logging.info(f"Wallapop monitor worker started. Checking for new items containing: \'{product['product_name']}\' with given parameters periodically")
|
loop = asyncio.new_event_loop()
|
||||||
worker.work(product, list)
|
asyncio.set_event_loop(loop)
|
||||||
|
loop.run_until_complete(worker.work(product, list))
|
||||||
|
loop.close()
|
||||||
break
|
break
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.info(f"Exception: {e}")
|
logging.info(f"Exception: {e}")
|
||||||
|
|||||||
Reference in New Issue
Block a user