this fixed it

This commit is contained in:
Andrea Spacca 2022-08-07 19:24:54 +09:00
parent 057fa1dca8
commit cd6a86dfb9
5 changed files with 127 additions and 112 deletions

16
bot.py
View File

@ -24,19 +24,7 @@ from PIL import Image
import requests
from nio import AsyncClient, InviteEvent, JoinError, RoomMessageText, MatrixRoom, LoginError, RoomMemberEvent, RoomVisibility, RoomPreset, RoomCreateError, RoomResolveAliasResponse, UploadError, UploadResponse, SyncError
# Couple of custom exceptions
class UploadFailed(Exception):
pass
class CommandRequiresAdmin(Exception):
pass
class CommandRequiresOwner(Exception):
pass
from modules.common.exceptions import CommandRequiresAdmin, CommandRequiresOwner, UploadFailed
class Bot:
@ -115,7 +103,7 @@ class Bot:
except ValueError: # broken cache?
self.logger.warning(f"Image cache for {url} could not be unpacked, attempting to re-upload...")
try:
matrix_uri, mimetype, w, h, size = await self.upload_image(url, event=event, blob=blob, no_cache=no_cache)
matrix_uri, mimetype, w, h, size = await self.upload_image(url, blob=blob, no_cache=no_cache)
except (UploadFailed, ValueError):
return await self.send_text(room, f"Sorry. Something went wrong fetching {url} and uploading the image to matrix server :(", event=event)

View File

@ -7,7 +7,7 @@ from nio import AsyncClient, UploadError
from nio import UploadResponse
from modules.common.module import BotModule
from bot import UploadFailed
from modules.common.exceptions import UploadFailed
class Apod:

View File

@ -0,0 +1,14 @@
# Couple of custom exceptions
class UploadFailed(Exception):
pass
class CommandRequiresAdmin(Exception):
pass
class CommandRequiresOwner(Exception):
pass

View File

@ -5,7 +5,6 @@ import sys
import traceback
import cups
import httpx
import asyncio
import aiofiles
import os

View File

@ -1,66 +1,84 @@
import time
import urllib.request
import urllib.parse
import urllib.error
import datetime
import pytz
import aiohttp.web
import requests
import os
import sys
import json
import importlib
from importlib import reload
from nio import MatrixRoom
from aiohttp import web
import asyncio
import nest_asyncio
nest_asyncio.apply()
from aiohttp import web
from future.moves.urllib.parse import urlencode
from nio import MatrixRoom
from modules.common.module import BotModule
tautulli_path = os.getenv("TAUTULLI_PATH")
import nest_asyncio
nest_asyncio.apply()
def load_tzlocal():
try:
global tautulli_path
rooms = dict()
global_bot = None
sys.path.insert(0, tautulli_path)
sys.path.insert(0, "{}/lib".format(tautulli_path))
module = importlib.import_module("tzlocal")
module = reload(module)
return module
except ModuleNotFoundError:
async def send_entry(blob, content_type, fmt_params, rooms):
for room_id in rooms:
room = MatrixRoom(room_id=room_id, own_user_id=os.getenv("BOT_OWNERS"),
encrypted=rooms[room_id])
if blob and content_type:
await global_bot.upload_and_send_image(room, blob, text="", blob=True, blob_content_type=content_type)
await global_bot.send_html(room, msg_template_html.format(**fmt_params),
msg_template_plain.format(**fmt_params))
def get_image(img=None, width=1000, height=1500):
"""
Return image data as array.
Array contains the image content type and image binary
Parameters required: img { Plex image location }
Optional parameters: width { the image width }
height { the image height }
Output: array
"""
pms_url = os.getenv("PLEX_MEDIA_SERVER_URL")
pms_token = os.getenv("PLEX_MEDIA_SERVER_TOKEN")
if not pms_url or not pms_token:
return None
def load_tautulli():
try:
global tautulli_path
width = width or 1000
height = height or 1500
sys.path.insert(0, tautulli_path)
sys.path.insert(0, "{}/lib".format(tautulli_path))
module = importlib.import_module("plexpy")
module = reload(module)
return module
except ModuleNotFoundError:
if img:
params = {'url': 'http://127.0.0.1:32400%s' % (img), 'width': width, 'height': height, 'format': "png"}
uri = pms_url + '/photo/:/transcode?%s' % urlencode(params)
headers = {'X-Plex-Token': pms_token}
session = requests.Session()
try:
r = session.request("GET", uri, headers=headers)
r.raise_for_status()
except Exception:
return None
plexpy = load_tautulli()
tzlocal = load_tzlocal()
response_status = r.status_code
response_content = r.content
response_headers = r.headers
if response_status in (200, 201):
return response_content, response_headers['Content-Type']
send_entry_lock = asyncio.Lock()
async def send_entry(bot, room, entry):
global send_entry_lock
async with send_entry_lock:
def get_from_entry(entry):
blob = None
content_type = ""
if "art" in entry:
global plexpy
if plexpy:
pms = plexpy.pmsconnect.PmsConnect()
pms_image = pms.get_image(entry["art"], 600, 300)
pms_image = get_image(entry["art"], 600, 300)
if pms_image:
(blob, content_type) = pms_image
await bot.upload_and_send_image(room, blob, "", True, content_type)
fmt_params = {
"title": entry["title"],
@ -73,9 +91,8 @@ async def send_entry(bot, room, entry):
"genres": ", ".join(entry["genres"])
}
await bot.send_html(room,
msg_template_html.format(**fmt_params),
msg_template_plain.format(**fmt_params))
return (blob, content_type, fmt_params)
msg_template_html = """
<b>{title} -({year})- Rating: {audience_rating}</b><br>
@ -94,25 +111,29 @@ msg_template_plain = """*{title} -({year})- Rating: {audience_rating}*
"""
class WebServer:
bot = None
rooms = dict()
def _get_loop():
try:
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
except RuntimeError:
loop = asyncio.get_event_loop()
finally:
return loop
class WebServer:
def __init__(self, host, port):
self.app = web.Application()
self.host = host
self.port = port
self.app = web.Application()
self.app.router.add_post('/notify', self.notify)
async def run(self):
def run(self):
if not self.host or not self.port:
return
loop = asyncio.get_event_loop()
runner = web.AppRunner(self.app)
loop.run_until_complete(runner.setup())
site = web.TCPSite(runner, host=self.host, port=self.port)
loop.run_until_complete(site.start())
aiohttp.web.run_app(self.app, host=self.host, port=self.port, handle_signals=True, loop=asyncio.get_running_loop())
async def notify(self, request: web.Request) -> web.Response:
try:
@ -126,9 +147,9 @@ class WebServer:
if "directors" in data:
data["directors"] = data["directors"].split(",")
for room_id in self.rooms:
room = MatrixRoom(room_id=room_id, own_user_id=os.getenv("BOT_OWNERS"), encrypted=self.rooms[room_id])
await send_entry(self.bot, room, data)
global rooms
(blob, content_type, fmt_params) = get_from_entry(data)
await send_entry(blob, content_type, fmt_params, rooms)
except Exception as exc:
message = str(exc)
@ -136,6 +157,7 @@ class WebServer:
return web.Response()
class MatrixModule(BotModule):
httpd = None
rooms = dict()
@ -143,29 +165,16 @@ class MatrixModule(BotModule):
def __init__(self, name):
super().__init__(name)
global plexpy
if plexpy:
global tautulli_path
plexpy.FULL_PATH = "{}/Tautulli.py".format(tautulli_path)
plexpy.PROG_DIR = os.path.dirname(plexpy.FULL_PATH)
plexpy.DATA_DIR = tautulli_path
plexpy.DB_FILE = os.path.join(plexpy.DATA_DIR, plexpy.database.FILENAME)
try:
plexpy.SYS_TIMEZONE = tzlocal.get_localzone()
except (pytz.UnknownTimeZoneError, LookupError, ValueError) as e:
plexpy.SYS_TIMEZONE = pytz.UTC
plexpy.SYS_UTC_OFFSET = datetime.datetime.now(plexpy.SYS_TIMEZONE).strftime('%z')
plexpy.initialize("{}/config.ini".format(tautulli_path))
self.httpd = WebServer(os.getenv("TAUTULLI_NOTIFIER_ADDR"), os.getenv("TAUTULLI_NOTIFIER_PORT"))
loop = asyncio.get_event_loop()
loop.run_until_complete(self.httpd.run())
def matrix_start(self, bot):
super().matrix_start(bot)
self.httpd.bot = bot
global global_bot
global_bot = bot
self.httpd.run()
def matrix_stop(self, bot):
super().matrix_stop(bot)
async def matrix_message(self, bot, room, event):
args = event.body.split()
@ -183,7 +192,7 @@ class MatrixModule(BotModule):
try:
url = "{}/api/v2?apikey={}&cmd=get_recently_added&count=10".format(os.getenv("TAUTULLI_URL"), self.api_key)
req = urllib.request.Request(url+"&media_type="+media_type)
req = urllib.request.Request(url + "&media_type=" + media_type)
connection = urllib.request.urlopen(req).read()
entries = json.loads(connection)
if "response" not in entries and "data" not in entries["response"] and "recently_added" not in entries["response"]["data"]:
@ -191,7 +200,8 @@ class MatrixModule(BotModule):
return
for entry in entries["response"]["data"]["recently_added"]:
await send_entry(bot, room, entry)
(blob, content_type, fmt_params) = get_from_entry(entry)
await send_entry(blob, content_type, fmt_params, {room.room_id: room})
except urllib.error.HTTPError as err:
raise ValueError(err.read())
@ -210,7 +220,8 @@ class MatrixModule(BotModule):
await bot.send_text(room, f"Removed {room_id} to rooms notification list")
bot.save_settings()
self.httpd.rooms = self.rooms
global rooms
rooms = self.rooms
else:
await bot.send_text(room, 'Usage: !tautulli <movie|show|artist>|<add|remove> %room_id% %encrypted%')
else:
@ -220,16 +231,19 @@ class MatrixModule(BotModule):
data = super().get_settings()
data["api_key"] = self.api_key
data["rooms"] = self.rooms
self.httpd.rooms = self.rooms
global rooms
rooms = self.rooms
return data
def set_settings(self, data):
super().set_settings(data)
if data.get("rooms"):
self.rooms = data["rooms"]
self.httpd.rooms = self.rooms
global rooms
rooms = self.rooms
if data.get("api_key"):
self.api_key = data["api_key"]
def help(self):
return ('Tautulli recently added bot')