diff --git a/gaspar/database.py b/gaspar/database.py
index 58581f8..195bbcf 100644
--- a/gaspar/database.py
+++ b/gaspar/database.py
@@ -19,7 +19,7 @@ class DBInitException(Exception):
class DataBase:
"""This class create or use existent SQLite database file. It provides
high-level methods for database."""
- def __init__(self, scheme, basefile='/usr/share/gaspar/data.sqlite'):
+ def __init__(self):
"""
Constructor creates new SQLite database if
it doesn't exist. Uses SQL code from file for DB init.
@@ -27,15 +27,15 @@ class DataBase:
:type scheme: string
:return: None
"""
- self.scheme = ''
- self.basefile = basefile
+ self.scheme = os.environ.get('TG_SCHEME') if os.environ.get('TG_SCHEME') else '/usr/share/gaspar/scheme.sql'
+ self.basefile = os.environ.get('TG_DB') if os.environ.get('TG_DB') else '/usr/share/gaspar/data.sqlite'
try:
- conn = self.connect(basefile=basefile)
- log.info("Using '%s' base file.", os.path.realpath(basefile))
+ conn = self.connect()
+ log.info("Using '%s' base file.", os.path.realpath(self.basefile))
except:
log.debug('Could not connect to DataBase.')
return None
- with open(scheme, 'r') as scheme_sql:
+ with open(self.scheme, 'r') as scheme_sql:
sql = scheme_sql.read()
self.scheme = sql
if conn is not None:
@@ -51,15 +51,15 @@ class DataBase:
log.info('DB connected.')
self.close(conn)
- def connect(self, basefile):
+ def connect(self):
"""
Create connect object for basefile
:param basefile: SQLite database filename
:type basefile: string
:return: sqlite3 connect object
"""
- #log.debug("Open connection to %s", basefile)
- return sqlite3.connect(basefile, check_same_thread=False)
+ log.info("Open connection to %s", os.path.realpath(self.basefile))
+ return sqlite3.connect(self.basefile, check_same_thread=False)
def execute(self, sql, params):
"""
@@ -69,7 +69,7 @@ class DataBase:
:type sql: string
: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)
cursor = conn.cursor()
cursor.execute(sql, params)
@@ -170,6 +170,11 @@ class DataBase:
tor_data["topic_title"],
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):
sql = """INSERT OR IGNORE INTO users(
'id',
@@ -196,14 +201,14 @@ class DataBase:
def get_alerts(self, user_id=None):
if user_id:
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 = ?"""
raw = self.execute(sql, (
user_id,
))
else:
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, ())
alerts = list()
for alert in raw:
diff --git a/gaspar/gaspar.py b/gaspar/gaspar.py
index 55cf502..29afc98 100644
--- a/gaspar/gaspar.py
+++ b/gaspar/gaspar.py
@@ -3,7 +3,7 @@ import sys
import logging
from urllib import parse
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 .notify import update_watcher
from .database import DataBase
@@ -14,21 +14,20 @@ logging.basicConfig(
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
log = logging.getLogger(__name__)
-torrent = Torrent()
+
+token = os.environ.get('TG_TOKEN')
+if not token:
+ log.error("Env var TG_TOKEN isn't set.")
+ sys.exit(1)
def main():
- token = os.environ.get('TG_TOKEN')
- if not token:
- log.error("Env var TG_TOKEN isn't set.")
- sys.exit(1)
"""Run bot."""
-
def add(update, context):
if 'https://rutracker.org' in update.message.text:
try:
tor_id = parse.parse_qs(parse.urlsplit(update.message.text).query)['t'][0]
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.")
return
else:
@@ -57,7 +56,7 @@ def main():
"Got /list request from user [%s] %s",
update.message.chat['id'],
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:
update.message.reply_text("You have no configured alerts.")
return True
@@ -102,14 +101,27 @@ def main():
parse_mode='HTML',
disable_web_page_preview=True)
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)
update_watcher(updater.bot)
updater.dispatcher.add_handler(CommandHandler('list', list_alerts))
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.start_polling()
@@ -117,4 +129,5 @@ def main():
if __name__ == '__main__':
+ log = logging.getLogger('gaspar')
main()
diff --git a/gaspar/notify.py b/gaspar/notify.py
index 3de028c..5f318f4 100644
--- a/gaspar/notify.py
+++ b/gaspar/notify.py
@@ -51,15 +51,17 @@ def update_watcher(bot):
pre='Topic has been updated\n')
subs = torrent.db.get_subscribers(alert['id'])
for sub in subs:
- bot.sendMessage(sub, msg, parse_mode='HTML', disable_web_page_preview=True)
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']):
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:
log.warning("Failed push update to client Transmission RPC for %s", torrent.meta['info_hash'])
except:
pass
+ bot.sendMessage(sub, msg, parse_mode='HTML', disable_web_page_preview=True)
+
time.sleep(1)
else:
log.info("There is no update for %s", alert['topic_title'])
diff --git a/gaspar/rutracker.py b/gaspar/rutracker.py
index 79609dd..29e2262 100644
--- a/gaspar/rutracker.py
+++ b/gaspar/rutracker.py
@@ -1,13 +1,16 @@
-import urllib.request, json
+import json
+import os
import logging
import re
+import urllib.request
+
from .database import DataBase
log = logging.getLogger(__name__)
class Torrent:
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.tor_id = tor_id
self.meta = None
diff --git a/gaspar/tools.py b/gaspar/tools.py
index f4f859a..222608a 100644
--- a/gaspar/tools.py
+++ b/gaspar/tools.py
@@ -12,7 +12,8 @@ def format_topic(tor_id, topic_title, size, info_hash, reg_time, pre=''):
reg_time = datetime.utcfromtimestamp(int(reg_time)
).strftime('%b-%d-%Y')
msg = f"""{pre}{topic_title}
-💿 Size: {size}
-#️⃣ Hash: {info_hash}
-📅 Updated: {reg_time}
\n"""
+💿 Size: {size}
+#️⃣ Hash: {info_hash}
+📅 Updated: {reg_time}
+❌ Unsubscribe: /delete_{tor_id}\n"""
return msg