mirror of
https://github.com/house-of-vanity/gaspar.git
synced 2025-07-07 02:34:06 +00:00
Improve client command.
This commit is contained in:
14
README
14
README
@ -9,10 +9,20 @@
|
|||||||
Gaspar telegram bot written in python.
|
Gaspar telegram bot written in python.
|
||||||
|
|
||||||
Fetures:
|
Fetures:
|
||||||
* notify about topic update on rutracker via telegram.
|
* Notify about topic update on rutracker.org via Telegram.
|
||||||
* is able to push new magnet link into your Transmission RPC client.
|
* Can push new magnet link into your Transmission web client.
|
||||||
|
|
||||||
|
|
||||||
running instance - @let_you_know_bot
|
running instance - @let_you_know_bot
|
||||||
|
|
||||||
|
⣿⣿⣿⡷⠊⡢⡹⣦⡑⢂⢕⢂⢕⢂⢕⢂⠕⠔⠌⠝⠛⠶⠶⢶⣦⣄⢂⢕⢂⢕
|
||||||
|
⣿⣿⠏⣠⣾⣦⡐⢌⢿⣷⣦⣅⡑⠕⠡⠐⢿⠿⣛⠟⠛⠛⠛⠛⠡⢷⡈⢂⢕⢂
|
||||||
|
⠟⣡⣾⣿⣿⣿⣿⣦⣑⠝⢿⣿⣿⣿⣿⣿⡵⢁⣤⣶⣶⣿⢿⢿⢿⡟⢻⣤⢑⢂
|
||||||
|
⣾⣿⣿⡿⢟⣛⣻⣿⣿⣿⣦⣬⣙⣻⣿⣿⣷⣿⣿⢟⢝⢕⢕⢕⢕⢽⣿⣿⣷⣔
|
||||||
|
⣿⣿⠵⠚⠉⢀⣀⣀⣈⣿⣿⣿⣿⣿⣿⣿⣿⣿⣗⢕⢕⢕⢕⢕⢕⣽⣿⣿⣿⣿
|
||||||
|
⢷⣂⣠⣴⣾⡿⡿⡻⡻⣿⣿⣴⣿⣿⣿⣿⣿⣿⣷⣵⣵⣵⣷⣿⣿⣿⣿⣿⣿⡿
|
||||||
|
⢌⠻⣿⡿⡫⡪⡪⡪⡪⣺⣿⣿⣿⣿⣿⠿⠿⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠃
|
||||||
|
⠣⡁⠹⡪⡪⡪⡪⣪⣾⣿⣿⣿⣿⠋⠐⢉⢍⢄⢌⠻⣿⣿⣿⣿⣿⣿⣿⣿⠏⠈
|
||||||
|
⡣⡘⢄⠙⣾⣾⣾⣿⣿⣿⣿⣿⣿⡀⢐⢕⢕⢕⢕⢕⡘⣿⣿⣿⣿⣿⣿⠏⠠⠈
|
||||||
|
⠌⢊⢂⢣⠹⣿⣿⣿⣿⣿⣿⣿⣿⣧⢐⢕⢕⢕⢕⢕⢅⣿⣿⣿⣿⡿⢋⢜⠠⠈
|
||||||
|
|
||||||
|
@ -4,12 +4,15 @@
|
|||||||
.. moduleauthor:: AB <github.com/house-of-vanity>
|
.. moduleauthor:: AB <github.com/house-of-vanity>
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import sqlite3
|
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
import sqlite3
|
||||||
|
|
||||||
|
from .transmission import check_connection
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class DBInitException(Exception):
|
class DBInitException(Exception):
|
||||||
""" Exception at DB Init """
|
""" Exception at DB Init """
|
||||||
|
|
||||||
@ -19,6 +22,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):
|
def __init__(self):
|
||||||
"""
|
"""
|
||||||
Constructor creates new SQLite database if
|
Constructor creates new SQLite database if
|
||||||
@ -85,7 +89,7 @@ class DataBase:
|
|||||||
:type conn: object
|
:type conn: object
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
#log.debug("Close connection to %s", self.basefile)
|
# log.debug("Close connection to %s", self.basefile)
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
def copy_to_history(self, tor_id):
|
def copy_to_history(self, tor_id):
|
||||||
@ -106,13 +110,25 @@ class DataBase:
|
|||||||
self.execute(sql, attrs)
|
self.execute(sql, attrs)
|
||||||
|
|
||||||
def add_client(self, user_id, scheme, hostname, port, username, password, path):
|
def add_client(self, user_id, scheme, hostname, port, username, password, path):
|
||||||
sql = """INSERT OR REPLACE INTO tr_clients(user_id, scheme, hostname, port, username, password, path)
|
if check_connection(scheme, hostname, port, username, password, path):
|
||||||
VALUES(?, ?, ?, ?, ?, ?, ?);"""
|
sql = """INSERT OR REPLACE INTO tr_clients(user_id, scheme, hostname, port, username, password, path)
|
||||||
self.execute(sql, (user_id, scheme, hostname, port, username, password, path))
|
VALUES(?, ?, ?, ?, ?, ?, ?);"""
|
||||||
|
self.execute(sql, (user_id, scheme, hostname, port, username, password, path))
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
def get_client(self, user_id):
|
def get_client(self, user_id):
|
||||||
sql = "SELECT scheme, hostname, port, username, password, path FROM tr_clients WHERE user_id = ?"
|
sql = "SELECT scheme, hostname, port, username, password, path FROM tr_clients WHERE user_id = ?"
|
||||||
return self.execute(sql, (user_id,))[0]
|
res = self.execute(sql, (user_id,))
|
||||||
|
if len(res):
|
||||||
|
return self.execute(sql, (user_id,))[0]
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def drop_client(self, user_id):
|
||||||
|
sql = "DELETE FROM tr_clients WHERE user_id = ?"
|
||||||
|
self.execute(sql, (user_id,))
|
||||||
|
|
||||||
def get_attr(self, tor_id, attr):
|
def get_attr(self, tor_id, attr):
|
||||||
sql = """SELECT %s FROM torrents WHERE id = ? ORDER BY reg_time DESC LIMIT 1""" % attr
|
sql = """SELECT %s FROM torrents WHERE id = ? ORDER BY reg_time DESC LIMIT 1""" % attr
|
||||||
@ -133,17 +149,17 @@ class DataBase:
|
|||||||
WHERE id = ?
|
WHERE id = ?
|
||||||
"""
|
"""
|
||||||
self.execute(sql, (
|
self.execute(sql, (
|
||||||
tor_data["info_hash"],
|
tor_data["info_hash"],
|
||||||
tor_data["forum_id"],
|
tor_data["forum_id"],
|
||||||
tor_data["poster_id"],
|
tor_data["poster_id"],
|
||||||
int(tor_data["size"]),
|
int(tor_data["size"]),
|
||||||
int(tor_data["reg_time"]),
|
int(tor_data["reg_time"]),
|
||||||
tor_data["tor_status"],
|
tor_data["tor_status"],
|
||||||
tor_data["seeders"],
|
tor_data["seeders"],
|
||||||
tor_data["topic_title"],
|
tor_data["topic_title"],
|
||||||
tor_data["seeder_last_seen"],
|
tor_data["seeder_last_seen"],
|
||||||
tor_data["id"],
|
tor_data["id"],
|
||||||
))
|
))
|
||||||
|
|
||||||
def save_tor(self, tor_data):
|
def save_tor(self, tor_data):
|
||||||
sql = """INSERT OR IGNORE INTO torrents(
|
sql = """INSERT OR IGNORE INTO torrents(
|
||||||
@ -159,17 +175,17 @@ class DataBase:
|
|||||||
'seeder_last_seen'
|
'seeder_last_seen'
|
||||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"""
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"""
|
||||||
self.execute(sql, (
|
self.execute(sql, (
|
||||||
tor_data["id"],
|
tor_data["id"],
|
||||||
tor_data["info_hash"],
|
tor_data["info_hash"],
|
||||||
tor_data["forum_id"],
|
tor_data["forum_id"],
|
||||||
tor_data["poster_id"],
|
tor_data["poster_id"],
|
||||||
int(tor_data["size"]),
|
int(tor_data["size"]),
|
||||||
int(tor_data["reg_time"]),
|
int(tor_data["reg_time"]),
|
||||||
tor_data["tor_status"],
|
tor_data["tor_status"],
|
||||||
tor_data["seeders"],
|
tor_data["seeders"],
|
||||||
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):
|
def delete_tor(self, user_id, tor_id):
|
||||||
sql = "DELETE FROM alerts WHERE user_id = ? AND tor_id = ?"
|
sql = "DELETE FROM alerts WHERE user_id = ? AND tor_id = ?"
|
||||||
@ -183,20 +199,21 @@ class DataBase:
|
|||||||
'last_name'
|
'last_name'
|
||||||
) VALUES (?, ?, ?, ?)"""
|
) VALUES (?, ?, ?, ?)"""
|
||||||
self.execute(sql, (
|
self.execute(sql, (
|
||||||
chat_instance['id'],
|
chat_instance['id'],
|
||||||
chat_instance['username'],
|
chat_instance['username'],
|
||||||
chat_instance['first_name'],
|
chat_instance['first_name'],
|
||||||
chat_instance['last_name'],
|
chat_instance['last_name'],
|
||||||
))
|
))
|
||||||
|
|
||||||
def save_alert(self, user_id, tor_id):
|
def save_alert(self, user_id, tor_id):
|
||||||
sql = """INSERT OR IGNORE INTO alerts(
|
sql = """INSERT OR IGNORE INTO alerts(
|
||||||
'user_id',
|
'user_id',
|
||||||
'tor_id'
|
'tor_id'
|
||||||
) VALUES (?, ?)"""
|
) VALUES (?, ?)"""
|
||||||
self.execute(sql, (
|
self.execute(sql, (
|
||||||
user_id,
|
user_id,
|
||||||
tor_id
|
tor_id
|
||||||
))
|
))
|
||||||
|
|
||||||
def get_alerts(self, user_id=None):
|
def get_alerts(self, user_id=None):
|
||||||
if user_id:
|
if user_id:
|
||||||
@ -204,8 +221,8 @@ class DataBase:
|
|||||||
torrents t 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 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"""
|
||||||
@ -227,6 +244,3 @@ class DataBase:
|
|||||||
for sub in self.execute(sql, (tor_id,)):
|
for sub in self.execute(sql, (tor_id,)):
|
||||||
subs.append(sub[0])
|
subs.append(sub[0])
|
||||||
return subs
|
return subs
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
120
gaspar/gaspar.py
120
gaspar/gaspar.py
@ -1,12 +1,12 @@
|
|||||||
|
import logging
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import logging
|
|
||||||
from urllib import parse
|
from urllib import parse
|
||||||
from telegram import *
|
|
||||||
from telegram.ext import Updater, MessageHandler, CommandHandler, PrefixHandler, filters
|
from telegram.ext import Updater, MessageHandler, CommandHandler, filters
|
||||||
from .rutracker import Torrent
|
|
||||||
from .notify import update_watcher
|
from .notify import update_watcher
|
||||||
from .database import DataBase
|
from .rutracker import Torrent
|
||||||
from .tools import format_topic
|
from .tools import format_topic
|
||||||
|
|
||||||
logging.basicConfig(
|
logging.basicConfig(
|
||||||
@ -14,14 +14,15 @@ 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__)
|
||||||
|
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
"""Run bot."""
|
"""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:
|
||||||
@ -34,28 +35,27 @@ def main():
|
|||||||
update.message.reply_text("Send me a URL to rutracker.org topic.")
|
update.message.reply_text("Send me a URL to rutracker.org topic.")
|
||||||
return
|
return
|
||||||
log.info(
|
log.info(
|
||||||
"Got /add request from user [%s] %s",
|
"Got /add request from user [%s] %s",
|
||||||
update.message.chat['id'],
|
update.message.chat['id'],
|
||||||
update.message.from_user.username)
|
update.message.from_user.username)
|
||||||
torrent = Torrent(tor_id)
|
torrent = Torrent(tor_id)
|
||||||
torrent.db.save_tor(torrent.meta)
|
torrent.db.save_tor(torrent.meta)
|
||||||
torrent.db.save_user(update.message.chat)
|
torrent.db.save_user(update.message.chat)
|
||||||
torrent.db.save_alert(update.message.chat['id'], torrent.meta['id'])
|
torrent.db.save_alert(update.message.chat['id'], torrent.meta['id'])
|
||||||
msg = format_topic(
|
msg = format_topic(
|
||||||
torrent.meta['id'],
|
torrent.meta['id'],
|
||||||
torrent.meta['topic_title'],
|
torrent.meta['topic_title'],
|
||||||
torrent.meta['size'],
|
torrent.meta['size'],
|
||||||
torrent.meta['info_hash'],
|
torrent.meta['info_hash'],
|
||||||
torrent.meta['reg_time'],
|
torrent.meta['reg_time'],
|
||||||
pre='You will be alerted about\n')
|
pre='You will be alerted about\n')
|
||||||
update.message.reply_text(msg, parse_mode='HTML', disable_web_page_preview=True)
|
update.message.reply_text(msg, parse_mode='HTML', disable_web_page_preview=True)
|
||||||
|
|
||||||
|
|
||||||
def list_alerts(update, context):
|
def list_alerts(update, context):
|
||||||
log.info(
|
log.info(
|
||||||
"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.")
|
||||||
@ -63,46 +63,65 @@ def main():
|
|||||||
msg = "<b>Configured alerts:</b>\n"
|
msg = "<b>Configured alerts:</b>\n"
|
||||||
for alert in alerts:
|
for alert in alerts:
|
||||||
msg += format_topic(
|
msg += format_topic(
|
||||||
alert['id'],
|
alert['id'],
|
||||||
alert['topic_title'],
|
alert['topic_title'],
|
||||||
alert['size'],
|
alert['size'],
|
||||||
alert['info_hash'],
|
alert['info_hash'],
|
||||||
alert['reg_time'],
|
alert['reg_time'],
|
||||||
pre="\n")
|
pre="\n")
|
||||||
update.message.reply_text(msg, parse_mode='HTML', disable_web_page_preview=True)
|
update.message.reply_text(msg, parse_mode='HTML', disable_web_page_preview=True)
|
||||||
|
|
||||||
def handle_client(update, context):
|
def handle_client(update, context):
|
||||||
u_id = update.message.chat['id']
|
u_id = update.message.chat['id']
|
||||||
log.info(
|
log.info(
|
||||||
"Got /client request from user [%s] %s",
|
"Got /client request from user [%s] %s",
|
||||||
u_id,
|
u_id,
|
||||||
update.message.from_user.username)
|
update.message.from_user.username)
|
||||||
try:
|
try:
|
||||||
addr = update.message.text.split()[1]
|
addr = update.message.text.split()[1]
|
||||||
log.info("Client Transmission RPC address - %s", addr)
|
log.info("Client Transmission RPC address - %s", addr)
|
||||||
tr = parse.urlparse(addr)
|
tr = parse.urlparse(addr)
|
||||||
scheme = tr.scheme if tr.scheme else False
|
scheme = tr.scheme if tr.scheme else False
|
||||||
hostname = tr.hostname if tr.hostname else False
|
hostname = tr.hostname if tr.hostname else False
|
||||||
username = tr.username if tr.username else False
|
username = tr.username if tr.username else False
|
||||||
password = tr.password if tr.password else False
|
password = tr.password if tr.password else False
|
||||||
path = tr.path if tr.path else '/transmission/rpc'
|
path = tr.path if tr.path else '/transmission/rpc'
|
||||||
port = tr.port if tr.port else (80 if scheme == 'http' else 443)
|
port = tr.port if tr.port else (80 if scheme == 'http' else 443)
|
||||||
if not scheme or not hostname:
|
if not scheme or not hostname:
|
||||||
update.message.reply_text(
|
update.message.reply_text(
|
||||||
f'Can\'t understand : <b>{update.message.text}</b>. '
|
f'Can\'t understand : <b>{update.message.text}</b>. '
|
||||||
'Send transmission RPC address like <b>http(s)://[user:pass]host[:port][/rpc_path]</b>',
|
'Send transmission RPC address like <b>http(s)://[user:pass]host[:port][/transmission/rpc]</b>',
|
||||||
|
parse_mode='HTML',
|
||||||
|
disable_web_page_preview=True)
|
||||||
|
return
|
||||||
|
except:
|
||||||
|
tr_client = Torrent().db.get_client(u_id)
|
||||||
|
log.info(tr_client)
|
||||||
|
if tr_client:
|
||||||
|
tr_line = f"Your client: <code>{tr_client[0]}://{tr_client[1]}:{tr_client[2]}{tr_client[5]}</code>\n" \
|
||||||
|
r"/delete_client"
|
||||||
|
else:
|
||||||
|
tr_line = False
|
||||||
|
update.message.reply_text(
|
||||||
|
'Gaspar can add new topics to your private Transmission server. '
|
||||||
|
'Send transmission RPC address like \n<b>http(s)://[user:pass]host[:port][/transmission/rpc]</b>\n'
|
||||||
|
f'{tr_line if tr_line else "You have no configured client."}',
|
||||||
parse_mode='HTML',
|
parse_mode='HTML',
|
||||||
disable_web_page_preview=True)
|
disable_web_page_preview=True)
|
||||||
return
|
return
|
||||||
except:
|
|
||||||
update.message.reply_text(
|
|
||||||
'Gaspar is able to add new topics to your private Transmission server.'
|
|
||||||
'Send transmission RPC address like <b>http(s)://[user:pass]host[:port][/rpc_path]</b>',
|
|
||||||
parse_mode='HTML',
|
|
||||||
disable_web_page_preview=True)
|
|
||||||
return
|
|
||||||
|
|
||||||
Torrent().db.add_client(u_id, scheme, hostname, port, username, password, path)
|
if Torrent().db.add_client(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.')
|
||||||
|
|
||||||
|
def delete_client(update, context):
|
||||||
|
log.info(
|
||||||
|
"Got /delete request from user [%s] %s",
|
||||||
|
update.message.chat['id'],
|
||||||
|
update.message.from_user.username)
|
||||||
|
Torrent().db.drop_client(update.message.chat['id'])
|
||||||
|
update.message.reply_text(f'Client deleted.')
|
||||||
|
|
||||||
def delete(update, context):
|
def delete(update, context):
|
||||||
log.info(
|
log.info(
|
||||||
@ -112,15 +131,16 @@ def main():
|
|||||||
tor_id = update.message.text.split('_')[1]
|
tor_id = update.message.text.split('_')[1]
|
||||||
try:
|
try:
|
||||||
Torrent().db.delete_tor(update.message.chat['id'], tor_id)
|
Torrent().db.delete_tor(update.message.chat['id'], tor_id)
|
||||||
context.bot.sendMessage(update.message.chat['id'], f'Deleted {tor_id}')
|
update.message.reply_text(f'Deleted {tor_id}')
|
||||||
except:
|
except:
|
||||||
context.bot.sendMessage(update.message.chat['id'], f'Faled to delete {tor_id}')
|
update.message.reply_text(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(CommandHandler('delete_client', delete_client))
|
||||||
updater.dispatcher.add_handler(MessageHandler(filters.Filters.regex(r'/delete_'), delete))
|
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))
|
||||||
|
|
||||||
|
@ -1,25 +1,28 @@
|
|||||||
import time
|
|
||||||
import threading
|
|
||||||
import logging
|
import logging
|
||||||
|
import threading
|
||||||
|
import time
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from .rutracker import Torrent
|
from .rutracker import Torrent
|
||||||
from .tools import format_topic
|
from .tools import format_topic
|
||||||
from .transmission import add_tor
|
from .transmission import add_tor
|
||||||
|
|
||||||
UPDATE_INTERVAL = 2 * 60 * 60 # in secs.
|
UPDATE_INTERVAL = 2 * 60 * 60 # in secs.
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
torrent = Torrent()
|
torrent = Torrent()
|
||||||
|
|
||||||
|
|
||||||
def sizeof_fmt(num, suffix='B'):
|
def sizeof_fmt(num, suffix='B'):
|
||||||
num = int(num)
|
num = int(num)
|
||||||
for unit in ['','Ki','Mi','Gi','Ti','Pi','Ei','Zi']:
|
for unit in ['', 'Ki', 'Mi', 'Gi', 'Ti', 'Pi', 'Ei', 'Zi']:
|
||||||
if abs(num) < 1024.0:
|
if abs(num) < 1024.0:
|
||||||
return "%3.1f%s%s" % (num, unit, suffix)
|
return "%3.1f%s%s" % (num, unit, suffix)
|
||||||
num /= 1024.0
|
num /= 1024.0
|
||||||
return "%.1f%s%s" % (num, 'Yi', suffix)
|
return "%.1f%s%s" % (num, 'Yi', suffix)
|
||||||
|
|
||||||
|
|
||||||
def update(tor_id):
|
def update(tor_id):
|
||||||
torrent.tor_id = tor_id
|
torrent.tor_id = tor_id
|
||||||
if torrent.is_outdated():
|
if torrent.is_outdated():
|
||||||
@ -29,6 +32,7 @@ def update(tor_id):
|
|||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def update_watcher(bot):
|
def update_watcher(bot):
|
||||||
def __thread():
|
def __thread():
|
||||||
while True:
|
while True:
|
||||||
@ -36,35 +40,38 @@ def update_watcher(bot):
|
|||||||
raw = torrent.db.get_alerts()
|
raw = torrent.db.get_alerts()
|
||||||
for alert in raw:
|
for alert in raw:
|
||||||
alerts.append(alert['id'])
|
alerts.append(alert['id'])
|
||||||
log.info("Checking for updates. Configured interval: %sh , [%s secs]", UPDATE_INTERVAL/60/60, UPDATE_INTERVAL)
|
log.info("Checking for updates. Configured interval: %sh , [%s secs]", UPDATE_INTERVAL / 60 / 60,
|
||||||
|
UPDATE_INTERVAL)
|
||||||
log.info("Checking alert %s", alert['topic_title'])
|
log.info("Checking alert %s", alert['topic_title'])
|
||||||
if update(alert['id']):
|
if update(alert['id']):
|
||||||
log.info("Found update for [%s] %s", torrent.meta['id'], torrent.meta['topic_title'])
|
log.info("Found update for [%s] %s", torrent.meta['id'], torrent.meta['topic_title'])
|
||||||
reg_time = datetime.utcfromtimestamp(int(torrent.meta['reg_time'])
|
reg_time = datetime.utcfromtimestamp(int(torrent.meta['reg_time'])
|
||||||
).strftime('%b-%d-%Y')
|
).strftime('%b-%d-%Y')
|
||||||
msg = format_topic(
|
msg = format_topic(
|
||||||
torrent.meta['id'],
|
torrent.meta['id'],
|
||||||
torrent.meta['topic_title'],
|
torrent.meta['topic_title'],
|
||||||
torrent.meta['size'],
|
torrent.meta['size'],
|
||||||
torrent.meta['info_hash'],
|
torrent.meta['info_hash'],
|
||||||
torrent.meta['reg_time'],
|
torrent.meta['reg_time'],
|
||||||
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:
|
||||||
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}"
|
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)
|
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'])
|
||||||
time.sleep(UPDATE_INTERVAL)
|
time.sleep(UPDATE_INTERVAL)
|
||||||
|
|
||||||
update_thread = threading.Thread(target=__thread)
|
update_thread = threading.Thread(target=__thread)
|
||||||
update_thread.start()
|
update_thread.start()
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
import urllib.request
|
import urllib.request
|
||||||
@ -8,6 +7,7 @@ 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()
|
self.db = DataBase()
|
||||||
@ -27,7 +27,6 @@ class Torrent:
|
|||||||
self.__tor_id = tor_id
|
self.__tor_id = tor_id
|
||||||
if tor_id:
|
if tor_id:
|
||||||
return self.get_tor_topic_data(tor_id)
|
return self.get_tor_topic_data(tor_id)
|
||||||
|
|
||||||
|
|
||||||
def get_tor_topic_data(self, tor_id):
|
def get_tor_topic_data(self, tor_id):
|
||||||
data = dict()
|
data = dict()
|
||||||
@ -62,6 +61,6 @@ class Torrent:
|
|||||||
if not self.tor_id:
|
if not self.tor_id:
|
||||||
log.warn("Torrent id not presented.")
|
log.warn("Torrent id not presented.")
|
||||||
return False
|
return False
|
||||||
ep_str = re.search(r"\[\d+(\+\d+)?(-\d+)?( +)?(из)?( +)?\d+(\+\d+)?(-\d+)?\]", self.meta["topic_title"]).group(0)
|
ep_str = re.search(r"\[\d+(\+\d+)?(-\d+)?( +)?(из)?( +)?\d+(\+\d+)?(-\d+)?\]", self.meta["topic_title"]).group(
|
||||||
|
0)
|
||||||
return ep_str
|
return ep_str
|
||||||
|
|
||||||
|
@ -1,16 +1,18 @@
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
|
|
||||||
def format_topic(tor_id, topic_title, size, info_hash, reg_time, pre=''):
|
def format_topic(tor_id, topic_title, size, info_hash, reg_time, pre=''):
|
||||||
def sizeof_fmt(num, suffix='B'):
|
def sizeof_fmt(num, suffix='B'):
|
||||||
num = int(num)
|
num = int(num)
|
||||||
for unit in ['','Ki','Mi','Gi','Ti','Pi','Ei','Zi']:
|
for unit in ['', 'Ki', 'Mi', 'Gi', 'Ti', 'Pi', 'Ei', 'Zi']:
|
||||||
if abs(num) < 1024.0:
|
if abs(num) < 1024.0:
|
||||||
return "%3.1f%s%s" % (num, unit, suffix)
|
return "%3.1f%s%s" % (num, unit, suffix)
|
||||||
num /= 1024.0
|
num /= 1024.0
|
||||||
return "%.1f%s%s" % (num, 'Yi', suffix)
|
return "%.1f%s%s" % (num, 'Yi', suffix)
|
||||||
size = sizeof_fmt(size)
|
|
||||||
|
size = sizeof_fmt(size)
|
||||||
reg_time = datetime.utcfromtimestamp(int(reg_time)
|
reg_time = datetime.utcfromtimestamp(int(reg_time)
|
||||||
).strftime('%b-%d-%Y')
|
).strftime('%b-%d-%Y')
|
||||||
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>
|
||||||
|
@ -1,17 +1,31 @@
|
|||||||
from transmission_rpc import Client
|
from transmission_rpc import Client
|
||||||
|
|
||||||
def add_tor(scheme, hostname, port, username, password, path, tor_hash):
|
|
||||||
try:
|
|
||||||
c = Client(
|
|
||||||
host=hostname,
|
|
||||||
port=port,
|
|
||||||
username=username,
|
|
||||||
password=password,
|
|
||||||
protocol=scheme,
|
|
||||||
path=path)
|
|
||||||
m = f'magnet:?xt=urn:btih:{tor_hash}'
|
|
||||||
c.add_torrent(m)
|
|
||||||
return True
|
|
||||||
except:
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
def add_tor(scheme, hostname, port, username, password, path, tor_hash):
|
||||||
|
try:
|
||||||
|
c = Client(
|
||||||
|
host=hostname,
|
||||||
|
port=port,
|
||||||
|
username=username,
|
||||||
|
password=password,
|
||||||
|
protocol=scheme,
|
||||||
|
path=path)
|
||||||
|
m = f'magnet:?xt=urn:btih:{tor_hash}'
|
||||||
|
c.add_torrent(m)
|
||||||
|
return True
|
||||||
|
except:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def check_connection(scheme, hostname, port, username, password, path):
|
||||||
|
try:
|
||||||
|
c = Client(
|
||||||
|
host=hostname,
|
||||||
|
port=port,
|
||||||
|
username=username,
|
||||||
|
password=password,
|
||||||
|
protocol=scheme,
|
||||||
|
path=path)
|
||||||
|
return True if c.rpc_version else False
|
||||||
|
except:
|
||||||
|
return False
|
||||||
|
Reference in New Issue
Block a user