diff --git a/gaspar/__init__.py b/gaspar/__init__.py index e69de29..c1336bd 100644 --- a/gaspar/__init__.py +++ b/gaspar/__init__.py @@ -0,0 +1 @@ +__version__ = "0.0.5" \ No newline at end of file diff --git a/gaspar/database.py b/gaspar/database.py index 8583aac..4e5f90c 100644 --- a/gaspar/database.py +++ b/gaspar/database.py @@ -35,7 +35,7 @@ class DataBase: self.basefile = os.environ.get('TG_DB') if os.environ.get('TG_DB') else '/usr/share/gaspar/data.sqlite' try: conn = self.connect() - log.info("Using '%s' base file.", os.path.realpath(self.basefile)) + log.debig("Using '%s' base file.", os.path.realpath(self.basefile)) except: log.debug('Could not connect to DataBase.') return None @@ -52,7 +52,7 @@ class DataBase: else: log.debug("Error! cannot create the database connection.") raise DBInitException - log.info('DB connected.') + log.debug('DB connected.') self.close(conn) def connect(self): @@ -62,7 +62,7 @@ class DataBase: :type basefile: string :return: sqlite3 connect object """ - log.info("Open connection to %s", os.path.realpath(self.basefile)) + log.debug("Open connection to %s", os.path.realpath(self.basefile)) return sqlite3.connect(self.basefile, check_same_thread=False) def execute(self, sql, params): @@ -78,7 +78,8 @@ class DataBase: cursor = conn.cursor() cursor.execute(sql, params) conn.commit() - result = cursor.fetchall() + _result = cursor.fetchall() + result = _result if _result else cursor.lastrowid self.close(conn) return result @@ -109,7 +110,7 @@ class DataBase: ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ? )""" self.execute(sql, attrs) - def add_client(self, user_id, scheme, hostname, port, username, password, path): + def add_client_rpc(self, user_id, scheme, hostname, port, username, password, path): if check_connection(scheme, hostname, port, username, password, path): sql = """INSERT OR REPLACE INTO tr_clients(user_id, scheme, hostname, port, username, password, path) VALUES(?, ?, ?, ?, ?, ?, ?);""" @@ -118,7 +119,7 @@ class DataBase: else: return False - def get_client(self, user_id): + def get_client_rpc(self, user_id): sql = "SELECT scheme, hostname, port, username, password, path FROM tr_clients WHERE user_id = ?" res = self.execute(sql, (user_id,)) if len(res): @@ -126,7 +127,7 @@ class DataBase: else: return False - def drop_client(self, user_id): + def drop_client_rpc(self, user_id): sql = "DELETE FROM tr_clients WHERE user_id = ?" self.execute(sql, (user_id,)) @@ -174,7 +175,7 @@ class DataBase: 'topic_title', 'seeder_last_seen' ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""" - self.execute(sql, ( + row_id = self.execute(sql, ( tor_data["id"], tor_data["info_hash"], tor_data["forum_id"], @@ -186,6 +187,7 @@ class DataBase: tor_data["topic_title"], tor_data["seeder_last_seen"], )) + return row_id def delete_tor(self, user_id, tor_id): sql = "DELETE FROM alerts WHERE user_id = ? AND tor_id = ?" diff --git a/gaspar/gaspar.py b/gaspar/gaspar.py index 3258332..91c12fb 100644 --- a/gaspar/gaspar.py +++ b/gaspar/gaspar.py @@ -3,11 +3,13 @@ import os import sys from urllib import parse -from telegram.ext import Updater, MessageHandler, CommandHandler, filters +from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update +from telegram.ext import Updater, MessageHandler, CommandHandler, filters, CallbackQueryHandler, CallbackContext from .notify import update_watcher from .rutracker import Torrent from .tools import format_topic +from .transmission import easy_send logging.basicConfig( level=logging.INFO, @@ -49,7 +51,16 @@ def main(): torrent.meta['info_hash'], torrent.meta['reg_time'], pre='You will be alerted about\n') - update.message.reply_text(msg, parse_mode='HTML', disable_web_page_preview=True) + keyboard = [] + if torrent.db.get_client_rpc(update.message.chat['id']): + keyboard.append([ + InlineKeyboardButton("Add torrent to RPC client", callback_data=f"start_rpc.{torrent.meta['id']}"), + InlineKeyboardButton("Don't!", callback_data=f"close.{torrent.meta['id']}"), ], + ) + + reply_markup = InlineKeyboardMarkup(keyboard) + + update.message.reply_text(msg, parse_mode='HTML', disable_web_page_preview=True, reply_markup=reply_markup) def list_alerts(update, context): log.info( @@ -95,8 +106,7 @@ def main(): disable_web_page_preview=True) return except: - tr_client = Torrent().db.get_client(u_id) - log.info(tr_client) + tr_client = Torrent().db.get_client_rpc(u_id) if tr_client: tr_line = f"Your client: {tr_client[0]}://{tr_client[1]}:{tr_client[2]}{tr_client[5]}\n" \ r"/delete_client" @@ -110,7 +120,7 @@ def main(): disable_web_page_preview=True) return - if Torrent().db.add_client(u_id, scheme, hostname, port, username, password, path): + if Torrent().db.add_client_rpc(u_id, scheme, hostname, port, username, password, path): update.message.reply_text(f'Client reachable and saved.') else: update.message.reply_text(f'Client unreachable.') @@ -120,7 +130,7 @@ def main(): "Got /delete request from user [%s] %s", update.message.chat['id'], update.message.from_user.username) - Torrent().db.drop_client(update.message.chat['id']) + Torrent().db.drop_client_rpc(update.message.chat['id']) update.message.reply_text(f'Client deleted.') def delete(update, context): @@ -135,6 +145,28 @@ def main(): except: update.message.reply_text(f'Faled to delete {tor_id}') + def button(update: Update, context: CallbackContext) -> None: + query = update.callback_query + query.answer() + + torrent_id = query.data.split('.')[1] + torrent = Torrent(torrent_id) + + msg = format_topic( + torrent.meta['id'], + torrent.meta['topic_title'], + torrent.meta['size'], + torrent.meta['info_hash'], + torrent.meta['reg_time'], + pre='You will be alerted about\n') + if query.data.split('.')[0] == "close": + query.edit_message_text(text=f"{msg}", parse_mode='HTML', + disable_web_page_preview=True) + else: + easy_send(client_id=query.from_user, torent=torrent) + query.edit_message_text(text=f"{msg}📨 Sent to RPC client", parse_mode='HTML', + disable_web_page_preview=True) + updater = Updater(token, use_context=True) update_watcher(updater.bot) @@ -143,6 +175,7 @@ def main(): updater.dispatcher.add_handler(CommandHandler('delete_client', delete_client)) updater.dispatcher.add_handler(MessageHandler(filters.Filters.regex(r'/delete_'), delete)) updater.dispatcher.add_handler(MessageHandler(filters.Filters.text, add)) + updater.dispatcher.add_handler(CallbackQueryHandler(button)) updater.start_polling() updater.idle() diff --git a/gaspar/notify.py b/gaspar/notify.py index 311e514..c8fd79a 100644 --- a/gaspar/notify.py +++ b/gaspar/notify.py @@ -5,7 +5,7 @@ from datetime import datetime from .rutracker import Torrent from .tools import format_topic -from .transmission import add_tor +from .transmission import send_to_client_rpc UPDATE_INTERVAL = 2 * 60 * 60 # in secs. @@ -57,8 +57,8 @@ def update_watcher(bot): subs = torrent.db.get_subscribers(alert['id']) for sub in subs: try: - scheme, hostname, port, username, password, path = torrent.db.get_client(sub) - if add_tor(scheme, hostname, port, username, password, path, torrent.meta['info_hash']): + scheme, hostname, port, username, password, path = torrent.db.get_client_rpc(sub) + if send_to_client_rpc(scheme, hostname, port, username, password, path, torrent.meta['info_hash']): log.info("Push update to client Transmission RPC for %s", torrent.meta['info_hash']) msg = f"{msg}\n* Added to your Transmission: {scheme}://{hostname}:{port}/{path}" else: diff --git a/gaspar/transmission.py b/gaspar/transmission.py index 14b3d05..66e1ee6 100644 --- a/gaspar/transmission.py +++ b/gaspar/transmission.py @@ -1,7 +1,19 @@ from transmission_rpc import Client +import logging + +log = logging.getLogger(__name__) + +def easy_send(torent, client_id): + try: + scheme, hostname, port, username, password, path = torent.db.get_client_rpc(client_id['id']) + if send_to_client_rpc(scheme, hostname, port, username, password, path, torent.meta['info_hash']): + log.info("Push update to client Transmission RPC for %s", torent.meta['topic_title']) + except Exception as e: + log.warning("Failed push update to client Transmission RPC for %s: %s", + torent.meta['topic_title'], e) -def add_tor(scheme, hostname, port, username, password, path, tor_hash): +def send_to_client_rpc(scheme, hostname, port, username, password, path, tor_hash): try: c = Client( host=hostname, diff --git a/setup.py b/setup.py index 746ce34..7c0af4b 100644 --- a/setup.py +++ b/setup.py @@ -1,5 +1,6 @@ import os, subprocess from setuptools import setup +from gaspar import __version__ as version def read(fname): return open(os.path.join(os.path.dirname(__file__), fname)).read() @@ -16,7 +17,7 @@ def get_requires(rfile): setup( name = "gaspar", - version = "0.0.5", + version = version, author = "UltraDesu", author_email = "ultradesu@hexor.ru", description = ("Telegram bot. Keep an eye on rutracker.org topics and let you "