Added delete feature. Minor fixes.

This commit is contained in:
AB
2021-02-25 22:06:53 +03:00
parent 5c6db17174
commit 5cf0207099
5 changed files with 52 additions and 28 deletions

View File

@ -19,7 +19,7 @@ class DBInitException(Exception):
class DataBase: class DataBase:
"""This class create or use existent SQLite database file. It provides """This class create or use existent SQLite database file. It provides
high-level methods for database.""" high-level methods for database."""
def __init__(self, scheme, basefile='/usr/share/gaspar/data.sqlite'): def __init__(self):
""" """
Constructor creates new SQLite database if Constructor creates new SQLite database if
it doesn't exist. Uses SQL code from file for DB init. it doesn't exist. Uses SQL code from file for DB init.
@ -27,15 +27,15 @@ class DataBase:
:type scheme: string :type scheme: string
:return: None :return: None
""" """
self.scheme = '' self.scheme = os.environ.get('TG_SCHEME') if os.environ.get('TG_SCHEME') else '/usr/share/gaspar/scheme.sql'
self.basefile = basefile self.basefile = os.environ.get('TG_DB') if os.environ.get('TG_DB') else '/usr/share/gaspar/data.sqlite'
try: try:
conn = self.connect(basefile=basefile) conn = self.connect()
log.info("Using '%s' base file.", os.path.realpath(basefile)) log.info("Using '%s' base file.", os.path.realpath(self.basefile))
except: except:
log.debug('Could not connect to DataBase.') log.debug('Could not connect to DataBase.')
return None return None
with open(scheme, 'r') as scheme_sql: with open(self.scheme, 'r') as scheme_sql:
sql = scheme_sql.read() sql = scheme_sql.read()
self.scheme = sql self.scheme = sql
if conn is not None: if conn is not None:
@ -51,15 +51,15 @@ class DataBase:
log.info('DB connected.') log.info('DB connected.')
self.close(conn) self.close(conn)
def connect(self, basefile): def connect(self):
""" """
Create connect object for basefile Create connect object for basefile
:param basefile: SQLite database filename :param basefile: SQLite database filename
:type basefile: string :type basefile: string
:return: sqlite3 connect object :return: sqlite3 connect object
""" """
#log.debug("Open connection to %s", basefile) log.info("Open connection to %s", os.path.realpath(self.basefile))
return sqlite3.connect(basefile, check_same_thread=False) return sqlite3.connect(self.basefile, check_same_thread=False)
def execute(self, sql, params): def execute(self, sql, params):
""" """
@ -69,7 +69,7 @@ class DataBase:
:type sql: string :type sql: string
:return: list of response. Empty list when no rows are available. :return: list of response. Empty list when no rows are available.
""" """
conn = self.connect(basefile=self.basefile) conn = self.connect()
log.debug("Executing: %s %s", sql, params) log.debug("Executing: %s %s", sql, params)
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute(sql, params) cursor.execute(sql, params)
@ -170,6 +170,11 @@ class DataBase:
tor_data["topic_title"], tor_data["topic_title"],
tor_data["seeder_last_seen"], tor_data["seeder_last_seen"],
)) ))
def delete_tor(self, user_id, tor_id):
sql = "DELETE FROM alerts WHERE user_id = ? AND tor_id = ?"
self.execute(sql, (user_id, tor_id))
def save_user(self, chat_instance): def save_user(self, chat_instance):
sql = """INSERT OR IGNORE INTO users( sql = """INSERT OR IGNORE INTO users(
'id', 'id',
@ -196,14 +201,14 @@ class DataBase:
def get_alerts(self, user_id=None): def get_alerts(self, user_id=None):
if user_id: if user_id:
sql = """SELECT t.size, t.reg_time, t.topic_title, t.id, t.info_hash FROM sql = """SELECT t.size, t.reg_time, t.topic_title, t.id, t.info_hash FROM
torrents t LEFT JOIN alerts a ON a.tor_id = t.id torrents t JOIN alerts a ON a.tor_id = t.id
WHERE a.user_id = ?""" WHERE a.user_id = ?"""
raw = self.execute(sql, ( raw = self.execute(sql, (
user_id, user_id,
)) ))
else: else:
sql = """SELECT t.size, t.reg_time, t.topic_title, t.id, t.info_hash FROM sql = """SELECT t.size, t.reg_time, t.topic_title, t.id, t.info_hash FROM
torrents t LEFT JOIN alerts a ON a.tor_id = t.id GROUP BY t.id""" torrents t JOIN alerts a ON a.tor_id = t.id GROUP BY t.id"""
raw = self.execute(sql, ()) raw = self.execute(sql, ())
alerts = list() alerts = list()
for alert in raw: for alert in raw:

View File

@ -3,7 +3,7 @@ import sys
import logging import logging
from urllib import parse from urllib import parse
from telegram import * from telegram import *
from telegram.ext import Updater, MessageHandler, CommandHandler, filters from telegram.ext import Updater, MessageHandler, CommandHandler, PrefixHandler, filters
from .rutracker import Torrent from .rutracker import Torrent
from .notify import update_watcher from .notify import update_watcher
from .database import DataBase from .database import DataBase
@ -14,21 +14,20 @@ logging.basicConfig(
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s') format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
torrent = Torrent()
def main():
token = os.environ.get('TG_TOKEN') token = os.environ.get('TG_TOKEN')
if not token: if not token:
log.error("Env var TG_TOKEN isn't set.") log.error("Env var TG_TOKEN isn't set.")
sys.exit(1) sys.exit(1)
"""Run bot."""
def main():
"""Run bot."""
def add(update, context): def add(update, context):
if 'https://rutracker.org' in update.message.text: if 'https://rutracker.org' in update.message.text:
try: try:
tor_id = parse.parse_qs(parse.urlsplit(update.message.text).query)['t'][0] tor_id = parse.parse_qs(parse.urlsplit(update.message.text).query)['t'][0]
except KeyError: except KeyError:
log.warn("URL provided doesn't contains any torrent id.") log.warning("URL provided doesn't contains any torrent id.")
update.message.reply_text("URL provided doesn't contains any torrent id.") update.message.reply_text("URL provided doesn't contains any torrent id.")
return return
else: else:
@ -57,7 +56,7 @@ def main():
"Got /list request from user [%s] %s", "Got /list request from user [%s] %s",
update.message.chat['id'], update.message.chat['id'],
update.message.from_user.username) update.message.from_user.username)
alerts = torrent.db.get_alerts(update.message.chat['id']) alerts = Torrent().db.get_alerts(update.message.chat['id'])
if len(alerts) == 0: if len(alerts) == 0:
update.message.reply_text("You have no configured alerts.") update.message.reply_text("You have no configured alerts.")
return True return True
@ -102,14 +101,27 @@ def main():
parse_mode='HTML', parse_mode='HTML',
disable_web_page_preview=True) disable_web_page_preview=True)
return return
torrent.db.add_client(u_id, scheme, hostname, port, username, password, path)
Torrent().db.add_client(u_id, scheme, hostname, port, username, password, path)
def delete(update, context):
log.info(
"Got /delete request from user [%s] %s",
update.message.chat['id'],
update.message.from_user.username)
tor_id = update.message.text.split('_')[1]
try:
Torrent().db.delete_tor(update.message.chat['id'], tor_id)
context.bot.sendMessage(update.message.chat['id'], f'Deleted {tor_id}')
except:
context.bot.sendMessage(update.message.chat['id'], f'Faled to delete {tor_id}')
updater = Updater(token, use_context=True) updater = Updater(token, use_context=True)
update_watcher(updater.bot) update_watcher(updater.bot)
updater.dispatcher.add_handler(CommandHandler('list', list_alerts)) updater.dispatcher.add_handler(CommandHandler('list', list_alerts))
updater.dispatcher.add_handler(CommandHandler('client', handle_client)) updater.dispatcher.add_handler(CommandHandler('client', handle_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(MessageHandler(filters.Filters.text, add))
updater.start_polling() updater.start_polling()
@ -117,4 +129,5 @@ def main():
if __name__ == '__main__': if __name__ == '__main__':
log = logging.getLogger('gaspar')
main() main()

View File

@ -51,15 +51,17 @@ def update_watcher(bot):
pre='<i>Topic has been updated</i>\n') pre='<i>Topic has been updated</i>\n')
subs = torrent.db.get_subscribers(alert['id']) subs = torrent.db.get_subscribers(alert['id'])
for sub in subs: for sub in subs:
bot.sendMessage(sub, msg, parse_mode='HTML', disable_web_page_preview=True)
try: try:
scheme, hostname, port, username, password, path = torrent.db.get_client(sub) scheme, hostname, port, username, password, path = torrent.db.get_client(sub)
if add_tor(scheme, hostname, port, username, password, path, torrent.meta['info_hash']): if add_tor(scheme, hostname, port, username, password, path, torrent.meta['info_hash']):
log.info("Push update to client Transmission RPC for %s", 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: else:
log.warning("Failed push update to client Transmission RPC for %s", torrent.meta['info_hash']) log.warning("Failed push update to client Transmission RPC for %s", torrent.meta['info_hash'])
except: except:
pass pass
bot.sendMessage(sub, msg, parse_mode='HTML', disable_web_page_preview=True)
time.sleep(1) time.sleep(1)
else: else:
log.info("There is no update for %s", alert['topic_title']) log.info("There is no update for %s", alert['topic_title'])

View File

@ -1,13 +1,16 @@
import urllib.request, json import json
import os
import logging import logging
import re import re
import urllib.request
from .database import DataBase from .database import DataBase
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
class Torrent: class Torrent:
def __init__(self, tor_id=None): def __init__(self, tor_id=None):
self.db = DataBase("/usr/share/gaspar/scheme.sql") self.db = DataBase()
self.api_url = "http://api.rutracker.org/v1/" self.api_url = "http://api.rutracker.org/v1/"
self.tor_id = tor_id self.tor_id = tor_id
self.meta = None self.meta = None

View File

@ -14,5 +14,6 @@ def format_topic(tor_id, topic_title, size, info_hash, reg_time, pre=''):
msg = f"""{pre}<a href='https://rutracker.org/forum/viewtopic.php?t={tor_id}'><b>{topic_title}</b></a> msg = f"""{pre}<a href='https://rutracker.org/forum/viewtopic.php?t={tor_id}'><b>{topic_title}</b></a>
<b>💿 Size:</b> <code>{size}</code> <b>💿 Size:</b> <code>{size}</code>
<b>#️⃣ Hash:</b> <code>{info_hash}</code> <b>#️⃣ Hash:</b> <code>{info_hash}</code>
<b>📅 Updated:</b> <code>{reg_time}</code>\n""" <b>📅 Updated:</b> <code>{reg_time}</code>
<b>❌ Unsubscribe: /delete_{tor_id}</b>\n"""
return msg return msg