Added animebyter and caddy logger
This commit is contained in:
parent
5361c00ec1
commit
993482612a
197
Animebyter/animebyter.py
Normal file
197
Animebyter/animebyter.py
Normal file
@ -0,0 +1,197 @@
|
||||
from feedparser import parse
|
||||
from aiohttp import ClientSession
|
||||
from discord.ext.commands import Bot
|
||||
from tinydb import TinyDB, Query
|
||||
from os.path import join
|
||||
from os import getenv
|
||||
from asyncio import sleep
|
||||
from traceback import print_exc
|
||||
|
||||
client = Bot('ab!')
|
||||
QB_URL = getenv("qbit_url")
|
||||
INTERVAL = int(getenv("INTERVAL")) if getenv("INTERVAL") else 300
|
||||
web = ClientSession()
|
||||
db = TinyDB("animebyter.json")
|
||||
chn = int(getenv("channel"))
|
||||
|
||||
downloading = []
|
||||
|
||||
class Anime:
|
||||
def __init__(self,name,le,tl,res):
|
||||
self.title = name
|
||||
self.last_episode = le
|
||||
self.torrent_link = tl
|
||||
self.resolution = res.strip()
|
||||
|
||||
async def login_qb():
|
||||
async with web.post(QB_URL+'/login',data={'username':getenv("qbit_user"),'password':getenv("qbit_pass")}) as res:
|
||||
if res.status!=200:
|
||||
print("Could not authenticate with qBittorrent. Exiting...")
|
||||
exit(1)
|
||||
else:
|
||||
print("Logged in to qBittorrent")
|
||||
|
||||
async def get_airing():
|
||||
r = []
|
||||
res = await web.get("https://animebytes.tv/feed/rss_torrents_airing_anime/{}".format(getenv("ab_key")))
|
||||
if res.status==200:
|
||||
txt = await res.text()
|
||||
rss = parse(txt)
|
||||
for i in rss['entries']:
|
||||
try:
|
||||
title = i['ab_grouptitle']
|
||||
ep = int((''.join(x for x in i['ab_torrentproperty'].split("|")[6] if x.isdigit())).strip())
|
||||
link = i['link']
|
||||
r.append(Anime(title,ep,link,i['ab_torrentproperty'].split("|")[3]))
|
||||
except Exception:
|
||||
continue
|
||||
return r
|
||||
|
||||
async def add_torrent(anime):
|
||||
print("Adding episode {} of {}".format(anime.last_episode,anime.title))
|
||||
path = "/mnt/Storage/Anime"
|
||||
try:
|
||||
res = await web.post(QB_URL+'/command/download',data={'urls':anime.torrent_link,'savepath':join(path,anime.title),'label':'Anime'})
|
||||
except Exception as e:
|
||||
print(str(e))
|
||||
return
|
||||
finally:
|
||||
res.close()
|
||||
if res.status==200:
|
||||
msg = "Added episode {} of {}".format(anime.last_episode,anime.title)
|
||||
print(msg)
|
||||
return msg
|
||||
else:
|
||||
print("Failed to add episode {} of {} ({})".format(anime.last_episode,anime.title,res.status))
|
||||
|
||||
async def main():
|
||||
print("Starting new episode checker")
|
||||
while True:
|
||||
try:
|
||||
print("Checking for new episodes")
|
||||
airing = await get_airing()
|
||||
for i in airing:
|
||||
res = db.search(Query().title==i.title)
|
||||
if res:
|
||||
le = res[0]['last_episode']
|
||||
if le<i.last_episode and i.resolution in ("1080p"):
|
||||
msg = await add_torrent(i)
|
||||
if msg:
|
||||
await client.get_channel(chn).send(msg)
|
||||
db.update({'last_episode':i.last_episode},Query().title==i.title)
|
||||
except Exception as e:
|
||||
print(str(e))
|
||||
print_exc()
|
||||
continue
|
||||
finally:
|
||||
await sleep(INTERVAL)
|
||||
|
||||
async def dl_watchdog():
|
||||
print("Starting download watchdog")
|
||||
while True:
|
||||
try:
|
||||
res = await web.get(QB_URL+"/query/torrents",params={'filter':'downloading','label':'Anime'})
|
||||
if res.status==200:
|
||||
res = await res.json()
|
||||
names = []
|
||||
for i in res:
|
||||
names.append(i['name'])
|
||||
if i['name'] not in downloading:
|
||||
downloading.append(i['name'])
|
||||
for i in downloading:
|
||||
if i not in names:
|
||||
try:
|
||||
downloading.remove(i)
|
||||
except ValueError:
|
||||
pass
|
||||
await client.get_channel(chn).send(":exclamation: <@!196224042988994560> {} has finished downloading.".format(i))
|
||||
else:
|
||||
print("Something went wrong with fetching downloads ({}: {})".format(res.status,await res.text()))
|
||||
except Exception as e:
|
||||
print(str(e))
|
||||
print_exc()
|
||||
continue
|
||||
finally:
|
||||
await sleep(10)
|
||||
|
||||
def chunks(s, n=1999):
|
||||
for start in range(0, len(s), n):
|
||||
yield s[start:start+n]
|
||||
|
||||
@client.command(pass_context=True)
|
||||
async def add(ctx):
|
||||
airing = await get_airing()
|
||||
txt = ""
|
||||
for i,v in enumerate(airing):
|
||||
txt+="{}) {}\n".format(i,v.title)
|
||||
msgs = []
|
||||
for i in chunks(txt):
|
||||
msgs.append(await ctx.send(i))
|
||||
msg = await client.wait_for('message',check=lambda m: m.author==ctx.author and m.channel==ctx.channel)
|
||||
await ctx.channel.delete_messages(msgs)
|
||||
if msg:
|
||||
try:
|
||||
msg = int(msg.content)
|
||||
except Exception as e:
|
||||
return await ctx.send(e)
|
||||
if msg>=len(airing):
|
||||
return await ctx.send("Invalid number")
|
||||
an = airing[msg]
|
||||
db.insert({'title':an.title,'last_episode':an.last_episode-1})
|
||||
return await ctx.send("Added {}".format(an.title))
|
||||
|
||||
|
||||
@client.command(pass_context=True)
|
||||
async def remove(ctx):
|
||||
watching = db.all()
|
||||
txt = ""
|
||||
for i,v in enumerate(watching):
|
||||
txt+="{}) {}\n".format(i,v['title'])
|
||||
msgs = []
|
||||
for i in chunks(txt):
|
||||
msgs.append(await ctx.send(i))
|
||||
msg = await client.wait_for('message',check=lambda m: m.author==ctx.author and m.channel==ctx.channel)
|
||||
if len(msgs)==1:
|
||||
await msgs[0].delete()
|
||||
else:
|
||||
await ctx.channel.delete_messages(msgs)
|
||||
if msg:
|
||||
try:
|
||||
msg = int(msg.content)
|
||||
except Exception as e:
|
||||
return await ctx.send(e)
|
||||
if msg>=len(watching):
|
||||
return await ctx.send("Invalid number")
|
||||
an = watching[msg]
|
||||
db.remove(Query().title==an['title'])
|
||||
return await ctx.send("Removed {}".format(an))
|
||||
|
||||
@client.command(pass_context=True)
|
||||
async def down(ctx):
|
||||
airing = await get_airing()
|
||||
txt = ""
|
||||
for i,v in enumerate(airing):
|
||||
txt+="{}) {} (Episode: {})[{}]\n".format(i,v.title,v.last_episode,v.resolution)
|
||||
msgs = []
|
||||
for i in chunks(txt):
|
||||
msgs.append(await ctx.send(i))
|
||||
msg = await client.wait_for('message',check=lambda m: m.author==ctx.author and m.channel==ctx.channel)
|
||||
print(msg)
|
||||
await ctx.channel.delete_messages(msgs)
|
||||
if msg:
|
||||
try:
|
||||
msg = int(msg.content)
|
||||
except Exception as e:
|
||||
return await ctx.send(e)
|
||||
if msg>=len(airing):
|
||||
return await ctx.send("Invalid number")
|
||||
await ctx.send(await add_torrent(airing[msg]))
|
||||
|
||||
@client.event
|
||||
async def on_ready():
|
||||
print("Starting animebyter")
|
||||
await login_qb()
|
||||
client.loop.create_task(main())
|
||||
client.loop.create_task(dl_watchdog())
|
||||
|
||||
client.run(getenv("discord_token"))
|
21
Animebyter/animebyter.service
Normal file
21
Animebyter/animebyter.service
Normal file
@ -0,0 +1,21 @@
|
||||
[Unit]
|
||||
Description=Adds new episodes from animebytes on qbittorrent
|
||||
After=network.target qbittorrent.service
|
||||
|
||||
[Service]
|
||||
|
||||
WorkingDirectory=/home/marios/Animebyter #The location of the animebyter script
|
||||
ExecStart=/usr/bin/python3.7 animebyter.py
|
||||
User=marios
|
||||
Restart=always
|
||||
|
||||
Environment=qbit_url=http://127.0.0.1:8080 #URL of your qBittorrent WebUI
|
||||
Environment=qbit_user=admin #Username for qBittorrent WebUI
|
||||
Environment=qbit_pass=adminadmin #Password for qBittorrent WebUI
|
||||
Environment=ab_key=YOUR_ANIMEBYTES_TOKEN #Your animebytes token. You can find this by querying any of the RSS feeds
|
||||
Environment=channel=THE_CHANNEL_YOU_WANT_TO_SEND_NOTIFICATIONS_IN #The ID of the channel you want to send notifications in on discord
|
||||
Environment=discord_token=YOUR_DISCORD_TOKEN #The token of your discord bot
|
||||
Environment=INTERVAL=300 #It will look for new episodes every x seconds
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
48
Caddy_Logger/caddy_logger.py
Normal file
48
Caddy_Logger/caddy_logger.py
Normal file
@ -0,0 +1,48 @@
|
||||
import socket
|
||||
from os import getenv
|
||||
from datetime import datetime
|
||||
import pymysql
|
||||
|
||||
class LogItem:
|
||||
def __init__(self,line):
|
||||
self.ip = line.split(" ")[0]
|
||||
self.timestamp = datetime.strptime(line.split("[")[1].split("]")[0].split("+")[0].strip(),"%d/%b/%Y:%H:%M:%S")
|
||||
req = line.split('"')[1].split(' ')
|
||||
self.method = req[0]
|
||||
self.path = req[1]
|
||||
self.http = req[2]
|
||||
self.status = int(line.split('"')[2].split(' ')[1])
|
||||
|
||||
print("Starting log server")
|
||||
db_conn = pymysql.connect(host=getenv("db_host"),user=getenv("db_user"),password=getenv("db_pass"),db=getenv("db_db"),autocommit=True)
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
s.bind((getenv("tcp_ip"),int(getenv("tcp_port"))))
|
||||
s.listen(True)
|
||||
|
||||
with db_conn.cursor() as db:
|
||||
db.execute("""
|
||||
CREATE TABLE IF NOT EXISTS `caddy_logs` (
|
||||
`ip` varchar(255) DEFAULT NULL,
|
||||
`timestamp` datetime DEFAULT NULL,
|
||||
`path` varchar(255) DEFAULT NULL,
|
||||
`method` varchar(255) DEFAULT NULL,
|
||||
`http` varchar(255) DEFAULT NULL,
|
||||
`status` int(11) DEFAULT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
""")
|
||||
|
||||
while True:
|
||||
conn, addr = s.accept()
|
||||
print("Caddy connected from {}".format(addr))
|
||||
while True:
|
||||
data = conn.recv(4096)
|
||||
if not data:
|
||||
break
|
||||
data = data.decode("utf-8").split("]:")[1].strip()
|
||||
itm = LogItem(data)
|
||||
try:
|
||||
with db_conn.cursor() as db:
|
||||
db.execute("INSERT INTO `caddy_logs` (`ip`, `timestamp`, `path`, `method`, `http`, `status`) VALUES (%s, %s, %s, %s, %s, %s)",(itm.ip,itm.timestamp,itm.path,itm.method,itm.http,itm.status,))
|
||||
except Exception:
|
||||
continue
|
||||
conn.close()
|
20
Caddy_Logger/caddy_logger.service
Normal file
20
Caddy_Logger/caddy_logger.service
Normal file
@ -0,0 +1,20 @@
|
||||
[Unit]
|
||||
Description=Caddy log parser
|
||||
After=network.target mysql.service
|
||||
Requires=mysql.service
|
||||
|
||||
[Service]
|
||||
Environment=tcp_ip=127.0.0.1 #The address to run the tcp server on
|
||||
Environment=tcp_port=6969 #The port to run the tcp server on
|
||||
Environment=db_host=127.0.0.1 #Your mysql server address
|
||||
Environment=db_user=root #Your mysql user
|
||||
Environment=db_pass=MYSQL_PASSWORD #Your mysql password
|
||||
Environment=db_db=ip_logging #The database in which you log IPs
|
||||
User=marios
|
||||
ExecStart=/usr/bin/python3 /home/caddy_logger.py #Change this according to where you have the script saved
|
||||
|
||||
#ATTENTION: Add the following under the directive you want to log from in your caddyfile
|
||||
#log syslog+tcp://127.0.0.1:6969 (Without the # obviously)
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
Loading…
x
Reference in New Issue
Block a user