Added animebyter and caddy logger

This commit is contained in:
marios8543 2019-11-30 15:44:38 +02:00
parent 5361c00ec1
commit 993482612a
4 changed files with 286 additions and 0 deletions

197
Animebyter/animebyter.py Normal file
View 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"))

View 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

View 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()

View 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