OppaiBot/oppaibot.py

131 lines
3.6 KiB
Python
Raw Permalink Normal View History

2018-05-09 15:59:14 -04:00
#!/usr/bin/env python3
"""
2018-05-21 13:49:04 -04:00
A lazy bot for idling in OppaiTime's announce channel and downloading
2018-05-09 15:59:14 -04:00
every torrent with matching tags.
"""
import os
import re
import functools
import configparser
import http.cookiejar
import requests
2019-07-26 20:03:20 -04:00
from twisted.internet import ssl, protocol, reactor
2018-05-09 15:59:14 -04:00
from twisted.words.protocols import irc
HEADERS = {"User-Agent": "spaghetti is a faggot"}
class OppaiBot(irc.IRCClient):
def __init__(self, config):
self.config = config
2018-05-11 17:44:13 -04:00
self.tracker = self.config.name
2018-05-09 15:59:14 -04:00
self.nickname = self.config["nickname"]
self.username = self.config["ident"]
2018-05-09 16:06:29 -04:00
self.cj = http.cookiejar.MozillaCookieJar(self.config["cookies_txt"])
self.cj.load()
2018-05-09 15:59:14 -04:00
self.watch_dir = self.config["watch_dir"]
2018-05-18 08:44:37 -04:00
2018-05-17 13:28:57 -04:00
self.tags = re.findall(r"\[(.+?)\]", self.config["tags"])
self.tags = [tag.split(",") for tag in self.tags]
2018-05-18 09:15:15 -04:00
self.blacklist = self.config.get("blacklist", "").split(",")
2018-05-09 15:59:14 -04:00
def save_torrent(self, url, directory):
"""
Downloads and saves the torrent file to the given directory.
"""
2018-05-09 16:06:29 -04:00
res = requests.get(url, cookies=self.cj, headers=HEADERS, verify=True)
2018-05-09 15:59:14 -04:00
res.raise_for_status()
2019-07-26 20:03:20 -04:00
if not res.headers['Content-Type'].startswith('application/x-bittorrent'):
print(f"ERROR: Could not download torrent file from URL '{url}'.")
return
2018-06-30 19:16:05 -04:00
fname =re.search(r'filename="(.+)"',res.headers['content-disposition'])
2018-05-09 15:59:14 -04:00
fname = fname.group(1)
2018-06-30 19:16:05 -04:00
fname = fname.encode("latin-1").decode("utf-8")
2018-05-11 17:44:13 -04:00
print(self.tracker + ": Saving torrent:", fname)
2018-05-09 15:59:14 -04:00
with open(os.path.join(directory, fname), "wb") as file:
for chunk in res.iter_content(100000):
file.write(chunk)
def privmsg(self, user, channel, message):
"""
Called when the bot receives a PRIVMSG, which can come from channels
or users alike.
"""
# More advanced logic is left as an exercise to the reader.
black_in_msg = [tag in message for tag in self.blacklist if tag]
2018-05-17 13:44:22 -04:00
if any(black_in_msg):
return
2018-05-17 13:28:57 -04:00
tags_in_msg = []
for tag_group in self.tags:
2018-05-18 08:40:30 -04:00
tags_in_group = []
for tag in tag_group:
if tag.startswith("!"):
tags_in_group.append(tag[1:] not in message)
else:
tags_in_group.append(tag in message)
tags_in_msg.append(all(tags_in_group))
2018-05-09 18:25:07 -04:00
if any(tags_in_msg):
2018-05-10 03:11:59 -04:00
url = re.findall(r"(http.+?) ", message)[1]
2018-05-09 16:06:29 -04:00
self.save_torrent(url, self.watch_dir)
2018-05-09 15:59:14 -04:00
def joined(self, channel):
"""Called when the bot joins a new channel."""
2018-05-11 17:44:13 -04:00
print(self.tracker + ": Joined", channel)
2018-05-09 15:59:14 -04:00
def signedOn(self):
"""Called when the bot successfully connects to the server."""
2018-05-11 17:44:13 -04:00
print(self.tracker + ": Signed on as", self.nickname)
2018-05-09 15:59:14 -04:00
self.mode(self.nickname, True, "B") # set +B on self
self.msg(self.config["tracker_bot"], self.config["auth_msg"])
def nickChanged(self, nick):
"""Called when my nick has been changed."""
2018-05-11 17:44:13 -04:00
print(self.tracker + ": Nick changed to", nick)
2018-05-09 15:59:14 -04:00
class OppaiBotFactory(protocol.ReconnectingClientFactory):
# black magic going on here
protocol = property(lambda s: functools.partial(OppaiBot, s.config))
def __init__(self, config):
self.config = config
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(
description="Downloads new torrents from a torrent tracker's IRC " \
+ "announce channel.")
parser.add_argument(
"-c",
"--config",
default="config.cfg",
help="Specify an alternate config file to use.")
args = parser.parse_args()
config = configparser.ConfigParser()
config.read(args.config)
2018-05-11 17:44:13 -04:00
for tracker in config.sections():
tracker_config = config[tracker]
2018-05-09 15:59:14 -04:00
2018-05-11 17:44:13 -04:00
server = tracker_config["server"]
port = tracker_config.getint("port")
print("Connecting to:", tracker_config.name)
2019-07-26 20:03:20 -04:00
reactor.connectSSL(
server,
port,
OppaiBotFactory(tracker_config),
ssl.ClientContextFactory())
2018-05-09 15:59:14 -04:00
reactor.run()