doorbot/targets.py

121 lines
3.5 KiB
Python

import logging
import requests
from matrix_client.client import MatrixClient as MatrixApiClient
from matrix_client.errors import MatrixError
class Client:
def post_image(self, file, name, content_type="image/png", targets=None):
"""Push to all targets"""
self.post_image(file, name, content_type, targets)
#raise NotImplementedError()
def send_image(self, target, file, name, content_type="image/png"):
"""Send an image to a room
Args:
target (str): The internal room id to post into
path (file): The image file object
name (str): The name for the file in the room
content_type (str): Content-type of the image
"""
self.post_image(path, name, content_type, targets=[target])
def post_text(self, text, targets=None):
"""Push to all targets"""
self.post_text(text, targets)
#raise NotImplementedError()
def send_text(self, target, text):
"""Send a text to a room
Args:
target (str): The internal room id to post into
text (str): The text to post
"""
self.post_text(text, targets=[target])
def _get_targets(self, targets):
if not targets:
targets = self.targets
if not targets:
self.log.info("no targets…")
targets = []
return targets
class MatrixClient(Client):
key = "matrix"
def __init__(self, host, username, password, **kwargs):
self.client = MatrixApiClient(host)
self.client.login_with_password_no_sync(username=username, password=password)
self.log = logging.getLogger(__name__)
self.targets = kwargs.values()
def _get_room(self, target):
if target not in self.client.rooms:
try:
self.client.join_room(target)
except MatrixError as e:
self.log.error("could not join room '" + target + "'")
self.log.exception(e)
return None
return self.client.rooms[target]
def _upload_image(self, file, content_type):
try:
data = file.read()
file.seek(0)
return self.client.api.media_upload(data, content_type)
except MatrixError as e:
self.log.exception(e)
return None
def post_image(self, file, name, content_type="image/png", targets=None):
targets = self._get_targets(targets)
mxc = None
for target in targets:
room = self._get_room(target)
if not room:
self.log.error("could not get room '" + target + "'")
continue
if not mxc:
mxc = self._upload_image(file, content_type)
if not mxc:
return
room.send_image(mxc['content_uri'], name)
def post_text(self, text, targets=None):
targets = self._get_targets(targets)
for target in targets:
room = self._get_room(target)
if room:
room.send_text(text)
class TelegramClient(Client):
key = "telegram"
MESSAGE_URL = "https://api.telegram.org/bot{token}/sendMessage"
IMAGE_URL = "https://api.telegram.org/bot{token}/sendPhoto"
def __init__(self, token, **kwargs):
self.text_url = self.MESSAGE_URL.format(token=token)
self.image_url = self.IMAGE_URL.format(token=token)
self.log = logging.getLogger(__name__)
self.targets = kwargs.values()
def post_image(self, file, name, content_type="image/png", targets=None):
targets = self._get_targets(targets)
for target in targets:
files = {'photo': file}
values = {'chat_id': target}
response = requests.post(self.image_url, files=files, data=values)
self.log.info("post message: %s -- %s", response.status_code, response.text)
file.seek(0)
def post_text(self, text, targets=None):
targets = self._get_targets(targets)
for target in targets:
response = requests.post(self.text_url, data={'chat_id': target, 'text': text})
self.log.info("post message: %s -- %s", response.status_code, response.text)