Skip to content

Instantly share code, notes, and snippets.

@marios8543
Created September 27, 2019 21:23
Show Gist options
  • Save marios8543/92c96ffc1a2f8a06b4642307b03c1526 to your computer and use it in GitHub Desktop.
Save marios8543/92c96ffc1a2f8a06b4642307b03c1526 to your computer and use it in GitHub Desktop.
import feedparser
import aiohttp
import discord
from discord.ext.commands import Bot
from os import getenv
from tinydb import TinyDB, Query
from os.path import join
import logging
from asyncio import sleep,ensure_future
client = Bot('ab!')
QB_URL = getenv("qbit_url")
INTERVAL = int(getenv("INTERVAL")) if getenv("INTERVAL") else 300
web = aiohttp.ClientSession()
db = TinyDB("/home/marios/Animebyter/animebyter.json")
downloading = []
class Anime:
def __init__(self,name,le,tl,res):
self.title = name
self.last_episode = le
self.torrent_link = tl
self.resolution = res
async def login_qb():
res = await web.post(QB_URL+'/login',data={'username':getenv("qbit_user"),'password':getenv("qbit_pass")})
if res.status!=200:
print("Could not authenticate with qBittorrent. Exiting...")
exit(1)
else:
print("Logged in to qBittorrent")
async def get_airing():
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 = feedparser.parse(txt)
res = []
for i in rss['entries']:
title = i['ab_grouptitle']
ep = int((''.join(x for x in i['ab_torrentproperty'].split("|")[6] if x.isdigit())).strip())
link = i['link']
res.append(Anime(title,ep,link,i['ab_torrentproperty'].split("|")[3]))
return res
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
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():
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']
print(type(le),type(i.last_episode),type(i.resolution))
if le<i.last_episode and i.resolution in ("1080p","720p"):
print("trying")
msg = await add_torrent(i)
if msg:
await client.send_message(client.get_channel(getenv("channel")),msg)
db.update({'last_episode':i.last_episode},Query().title==i.title)
except Exception as e:
print(str(e))
continue
finally:
await sleep(INTERVAL)
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 client.say(i))
msg = await client.wait_for_message(author=ctx.message.author,channel=ctx.message.channel)
await client.delete_messages(msgs)
if msg:
try:
msg = int(msg.content)
except Exception as e:
return await client.say(e)
if msg>=len(airing):
return await client.say("Invalid number")
an = airing[msg]
db.insert({'title':an.title,'last_episode':an.last_episode})
return await client.say("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 client.say(i))
msg = await client.wait_for_message(author=ctx.message.author,channel=ctx.message.channel)
if len(msgs)==1:
await client.delete_message(msgs[0])
else:
await client.delete_messages(msgs)
if msg:
try:
msg = int(msg.content)
except Exception as e:
return await client.say(e)
if msg>=len(watching):
return await client.say("Invalid number")
an = watching[msg]
db.remove(Query().title==an['title'])
return await client.say("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 client.say(i))
msg = await client.wait_for_message(author=ctx.message.author,channel=ctx.message.channel)
await client.delete_messages(msgs)
if msg:
try:
msg = int(msg.content)
except Exception as e:
return await client.say(e)
if msg>=len(airing):
return await client.say("Invalid number")
await client.say(await add_torrent(airing[msg]))
async def execute(code,ctx):
# Make an async function with the code and `exec` it
exec(
f'async def __ex(ctx): ' +
''.join(f'\n {l}' for l in code.split('\n'))
)
return await locals()['__ex'](ctx)
@client.command(pass_context=True)
async def interpret(ctx):
if ctx.message.author.id!="196224042988994560":
return await client.say("Only the bot manager can use this")
await client.say("Switching on interpreter mode")
while True:
msg = await client.wait_for_message(author=ctx.message.author,channel=ctx.message.channel)
if not msg:
continue
if msg.content=="quit":
return await client.say("Exiting interpreter mode")
try:
resp = await execute(msg.content,ctx)
if not resp:
await client.say("Evaluation returned None")
else:
await client.say(resp)
except Exception as e:
await client.say("Error ({})".format(str(e)))
@client.event
async def on_ready():
print("Starting animebyter")
await login_qb()
client.loop.create_task(main())
client.run(getenv("discord_token"))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment