Compare commits

..

2 Commits

Author SHA1 Message Date
29b740cd33 thread watching 2018-02-10 19:28:26 -05:00
c6a4f032fa thread watching 2018-02-10 19:28:07 -05:00
3 changed files with 157 additions and 9 deletions

View File

@ -1,5 +1,4 @@
#! /usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*-
""" """
Various things related to Banished Quest. Various things related to Banished Quest.
""" """

View File

@ -1,5 +1,4 @@
#! /usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*-
""" """
This module exracts various information from imbd. This module exracts various information from imbd.
It also contains functionality for the local movie database. It also contains functionality for the local movie database.
@ -22,14 +21,14 @@ def setup(bot):
@module.example('.movie Citizen Kane', '[MOVIE] Title: Citizen Kane | Year: \ @module.example('.movie Citizen Kane', '[MOVIE] Title: Citizen Kane | Year: \
1941 | Rating: 8.4 | Genre: Drama, Mystery | IMDB Link: \ 1941 | Rating: 8.4 | Genre: Drama, Mystery | IMDB Link: \
http://imdb.com/title/tt0033467') http://imdb.com/title/tt0033467')
def movie(bot, trigger): def movieInfo(bot, trigger):
""" """
Returns some information about a movie, like Title, Year, Rating, Returns some information about a movie, like Title, Year, Rating,
Genre and IMDB Link. Genre and IMDB Link.
""" """
if not trigger.group(2): if not trigger.group().replace(".movie ", ""):
return return
word = trigger.group(2).strip().replace(" ", "+") word = trigger.group().replace(".movie ", "").strip().replace(" ", "+")
api_key = bot.config.movie.tmdb_api_key api_key = bot.config.movie.tmdb_api_key
uri = "https://api.themoviedb.org/3/search/movie?" + \ uri = "https://api.themoviedb.org/3/search/movie?" + \
@ -125,11 +124,15 @@ def pickMovie(bot, trigger):
cur = conn.cursor() cur = conn.cursor()
cur.execute("SELECT movie_title FROM movie WHERE " + \ cur.execute("SELECT movie_title FROM movie WHERE " + \
"times_watched < 1 AND shitpost = 0 ORDER BY RANDOM() LIMIT 1;") "times_watched < 1 AND shitpost = 0 ORDER BY RANDOM() LIMIT 1;")
movie = cur.fetchone() movie = cur.fetchone()[0]
conn.close() conn.close()
bot.memory['movie_lock'].release() bot.memory['movie_lock'].release()
bot.reply(movie[0]) bot.reply(movie)
if trigger.group(2) == "-m":
trigger.set_group(f".movie {movie}")
movieInfo(bot, trigger)
@module.require_admin @module.require_admin

146
modules/watcher.py Executable file
View File

@ -0,0 +1,146 @@
#!/usr/bin/env python3
"""
A thread watcher module for 4chan.
"""
import time
import threading
import requests
from module import commands, example
def setup(bot):
"""
Establishes the bot's dictionary of watched threads.
"""
bot.memory["watcher"] = {}
def get_time():
"""
Returns the current time formatted in If-Modified-Since notation.
"""
return time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime())
def get_num_posts(thread, name):
"""
Gets the number of OP posts from the thread JSON.
"""
num = 0
for post in thread["posts"]:
if post.get("name") == name:
num += 1
return num
def get_last_post(thread, name):
"""
Gets the last post made by name.
"""
for post in reversed(thread["posts"]):
if post.get("name") == name:
return post.get("no")
def get_api_url(url):
"""
Returns the API url for the provided thread url.
"""
return url.replace("boards.4chan", "a.4cdn") + ".json"
def get_thread_url(api_url):
"""
Returns the normal thread url for the provided API url.
"""
return api_url.replace("a.4cdn", "boards.4chan").replace(".json", "")
@commands("watch")
@example(".watch https://boards.4chan.org/qst/thread/2")
def watch(bot, trigger):
"""
A thread watcher for 4chan.
"""
url = trigger.group(3)
op_name = trigger.group(4)
if url in bot.memory["watcher"].keys():
return bot.say("Error: I'm already watching that thread.")
api_url = get_api_url(url)
res = requests.get(api_url, verify=True)
if res.status_code == 404:
return bot.say("404: thread not found")
thread = res.json()
last_post = get_last_post(thread, op_name)
time_since = get_time()
t = WatcherThread(bot, api_url, op_name, last_post, time_since)
t.start()
bot.memory["watcher"][url] = t
bot.say("[\x0304Watcher\x03] Watching thread: \x0307" + url)
@commands("unwatch")
@example(".unwatch https://boards.4chan.org/qst/thread/2")
def unwatch(bot, trigger):
"""
Stops the thread watcher thread for that thread.
"""
url = trigger.group(2)
try:
bot.memory["watcher"][url].stop.set()
bot.memory["watcher"].pop(url)
except KeyError:
return bot.say("Error: I'm not watching that thread.")
return bot.say("[\x0304Watcher\x03] No longer watching: \x0307" + url)
class WatcherThread(threading.Thread):
def __init__(self, bot, api_url, op_name, last_post, time_since):
threading.Thread.__init__(self)
self.stop = threading.Event()
self.period = 20
self.bot = bot
self.api_url = api_url
self.op_name = op_name
self.last_post = last_post
self.time_since = time_since
def run(self):
while not self.stop.is_set():
headers = {"If-Modified-Since": self.time_since}
res = requests.get(self.api_url, headers=headers, verify=True)
self.time_since = get_time()
if res.status_code == 404:
msg = "[\x0304Watcher\x03] Thread deleted: " \
+ f"\x0307{get_thread_url(self.api_url)}"
self.bot.say(msg)
self.stop.set()
continue
if res.status_code == 304:
self.stop.wait(self.period)
continue
thread = res.json()
if thread["posts"][0].get("closed"):
msg = "[\x0304Watcher\x03] Thread closed: " \
+ f"\x0307{get_thread_url(self.api_url)}"
self.bot.say(msg)
self.stop.set()
continue
new_last_post = get_last_post(thread, self.op_name)
if new_last_post > self.last_post:
self.last_post = new_last_post
msg = "[\x0304Watcher\x03] New post from \x0308" \
+ f"{self.op_name}\x03 in \x0307{get_thread_url(self.api_url)}"
self.bot.say(msg)
self.stop.wait(self.period)