2017-03-04 21:45:09 +00:00
|
|
|
import json
|
|
|
|
import requests
|
|
|
|
import logging
|
|
|
|
|
2017-05-05 03:23:02 +00:00
|
|
|
from bot import MonkeyBot
|
2017-03-04 22:48:31 +00:00
|
|
|
from pnutlib import Pnut
|
2017-03-04 21:45:09 +00:00
|
|
|
from flask import Flask, jsonify, request, abort
|
|
|
|
from models import *
|
|
|
|
|
|
|
|
app = Flask(__name__)
|
|
|
|
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
|
|
|
|
db.init_app(app)
|
|
|
|
|
2017-05-05 04:35:05 +00:00
|
|
|
cmdbot = MonkeyBot()
|
2017-05-05 03:23:02 +00:00
|
|
|
|
2017-03-04 21:45:09 +00:00
|
|
|
txId = 0
|
|
|
|
|
|
|
|
@app.route("/transactions/<transaction>", methods=["PUT"])
|
|
|
|
def on_receive_events(transaction):
|
|
|
|
global txId
|
|
|
|
|
|
|
|
events = request.get_json()["events"]
|
|
|
|
for event in events:
|
2017-05-04 00:55:55 +00:00
|
|
|
logging.info(event)
|
2017-03-04 22:42:40 +00:00
|
|
|
user = MatrixUser.query.filter_by(matrix_id=event["user_id"]).first()
|
2017-03-04 21:45:09 +00:00
|
|
|
|
|
|
|
if (event['type'] == 'm.room.message'
|
|
|
|
and not app.config['MATRIX_PNUT_PREFIX'] in event["user_id"]
|
|
|
|
and not 'pnut-bridge' in event["user_id"]):
|
|
|
|
|
2017-05-03 14:23:56 +00:00
|
|
|
embed = None
|
|
|
|
|
2017-05-04 03:02:11 +00:00
|
|
|
chan = MatrixRoom.query.filter_by(room_id=event['room_id']).first()
|
|
|
|
if chan:
|
|
|
|
chan_id = chan.pnut_chan
|
|
|
|
else:
|
2017-05-05 03:23:02 +00:00
|
|
|
adminrm = MatrixAdminRooms.query.filter_by(room_id=event['room_id']).first()
|
|
|
|
if adminrm:
|
|
|
|
cmdbot.on_message(event)
|
2017-05-04 03:02:11 +00:00
|
|
|
return jsonify({})
|
|
|
|
|
2017-03-04 21:45:09 +00:00
|
|
|
if (event['content']['msgtype'] == 'm.text'
|
|
|
|
or event['content']['msgtype'] == 'm.notice'):
|
|
|
|
if user:
|
|
|
|
token = user.pnut_token
|
|
|
|
text = event['content']['body']
|
|
|
|
else:
|
|
|
|
token = app.config['MATRIX_PNUT_TOKEN']
|
2017-04-25 02:43:06 +00:00
|
|
|
text = "[" + get_displayname(event["user_id"]) + "] " + event['content']['body']
|
2017-03-04 21:45:09 +00:00
|
|
|
elif event['content']['msgtype'] == 'm.emote':
|
|
|
|
if user:
|
|
|
|
token = user.pnut_token
|
|
|
|
text = "* " + user.pnut_id + " " + event['content']['body']
|
|
|
|
else:
|
|
|
|
token = app.config['MATRIX_PNUT_TOKEN']
|
2017-04-25 01:55:44 +00:00
|
|
|
text = "* " + get_displayname(event["user_id"]) + " " + event['content']['body']
|
2017-05-03 05:43:23 +00:00
|
|
|
elif event['content']['msgtype'] == 'm.image':
|
2017-05-03 05:50:33 +00:00
|
|
|
imgurl = app.config['MATRIX_HOST'] + '/_matrix/media/r0/download/' + event['content']['url'][6:]
|
2017-05-03 14:27:39 +00:00
|
|
|
thmburl = app.config['MATRIX_HOST'] + '/_matrix/media/r0/download/' + event['content']['info']['thumbnail_url'][6:]
|
2017-05-03 14:23:56 +00:00
|
|
|
value = {"type": "photo", "version": "1.0"}
|
|
|
|
value["title"] = event['content']['body']
|
|
|
|
value["url"] = imgurl
|
|
|
|
value["width"] = event['content']['info']['w']
|
|
|
|
value["height"] = event['content']['info']['h']
|
|
|
|
value["thumbnail_width"] = event['content']['info']['thumbnail_info']['w']
|
|
|
|
value["thumbnail_height"] = event['content']['info']['thumbnail_info']['h']
|
2017-05-03 14:27:39 +00:00
|
|
|
value["thumbnail_url"] = thmburl
|
2017-05-03 14:23:56 +00:00
|
|
|
rawitem = {"type": "io.pnut.core.oembed", "value": value}
|
|
|
|
embed = [rawitem]
|
2017-05-03 05:43:23 +00:00
|
|
|
if user:
|
|
|
|
token = user.pnut_token
|
|
|
|
text = ""
|
|
|
|
else:
|
|
|
|
token = app.config['MATRIX_PNUT_TOKEN']
|
|
|
|
text = "[" + get_displayname(event["user_id"]) + "] "
|
2017-05-03 14:36:38 +00:00
|
|
|
text += imgurl
|
2017-03-04 21:45:09 +00:00
|
|
|
else:
|
|
|
|
text = None
|
|
|
|
|
|
|
|
if user == None and not chan.pnut_write:
|
|
|
|
txId += 1
|
2017-05-03 05:48:00 +00:00
|
|
|
url = app.config['MATRIX_HOST']
|
2017-03-04 21:45:09 +00:00
|
|
|
url += '/_matrix/client/r0/rooms/{0}/redact/{1}/{2}'.format(
|
|
|
|
event['room_id'], event['event_id'], txId)
|
|
|
|
url += "?access_token=" + app.config['MATRIX_AS_TOKEN']
|
|
|
|
requests.put(url, headers={"Content-Type": "application/json"}, data=json.dumps({}))
|
|
|
|
else:
|
|
|
|
if text:
|
2017-05-03 14:23:56 +00:00
|
|
|
r = Pnut(token).channel_post(chan_id, text, embed)
|
2017-03-04 21:45:09 +00:00
|
|
|
if r.status_code == 201:
|
|
|
|
msgid = json.loads(r.text)['data']['id']
|
|
|
|
if token == app.config['MATRIX_PNUT_TOKEN']:
|
|
|
|
puser = app.config['MATRIX_PNUT_USER']
|
|
|
|
else:
|
|
|
|
puser = user.pnut_id
|
|
|
|
|
|
|
|
el = MatrixMsgEvents(event['event_id'], event['room_id'], msgid, puser, chan_id)
|
|
|
|
db.session.add(el)
|
|
|
|
db.session.commit()
|
2017-05-25 13:59:55 +00:00
|
|
|
elif r.status_code == 401:
|
|
|
|
txId += 1
|
|
|
|
err_notice = event["user_id"] + ": The pnut.io channel this room is connected with is restricted to valid "
|
|
|
|
err_notice += "pnut.io users only. Direct chat this bot to associate your account."
|
|
|
|
body = {'msgtype': 'm.notice', 'body': err_notice}
|
|
|
|
url = app.config['MATRIX_HOST']
|
|
|
|
url += '/_matrix/client/r0/rooms/{0}/send/m.room.message/{1}'.format(event['room_id'], str(txId))
|
|
|
|
url += "?access_token=" + app.config['MATRIX_AS_TOKEN']
|
|
|
|
requests.put(url, headers={"Content-Type": "application/json"}, data=json.dumps(body))
|
|
|
|
else:
|
|
|
|
logging.debug(r.text)
|
2017-03-04 21:45:09 +00:00
|
|
|
|
|
|
|
elif event['type'] == 'm.room.redaction':
|
|
|
|
r_event = MatrixMsgEvents.query.filter_by(event_id=event['redacts'],room_id=event['room_id']).first()
|
|
|
|
if r_event:
|
|
|
|
if r_event.pnut_user == app.config['MATRIX_PNUT_USER']:
|
|
|
|
token = token == app.config['MATRIX_PNUT_TOKEN']
|
|
|
|
else:
|
|
|
|
r_user = MatrixUser.query.filter_by(pnut_id=r_event.pnut_user).first()
|
|
|
|
if r_user:
|
|
|
|
token = r_user.pnut_token
|
|
|
|
else:
|
|
|
|
return jsonify({})
|
|
|
|
|
|
|
|
r = Pnut(token).delete_channel_post(r_event.pnut_chan, r_event.pnut_msgid)
|
|
|
|
|
2017-05-04 06:01:51 +00:00
|
|
|
elif event['type'] == 'm.room.member':
|
|
|
|
|
2017-05-04 23:40:32 +00:00
|
|
|
if event['state_key'] == app.config['MATRIX_AS_ID']:
|
|
|
|
|
2017-05-05 00:17:45 +00:00
|
|
|
if event['content']['membership'] == 'invite' and 'is_direct' in event['content'] and event['content']['is_direct'] == True:
|
2017-05-04 23:40:32 +00:00
|
|
|
|
2017-05-25 00:04:27 +00:00
|
|
|
logging.info('>> GOT PRIVATE INVITE')
|
2017-05-04 23:40:32 +00:00
|
|
|
txId += 1
|
|
|
|
url = app.config['MATRIX_HOST']
|
|
|
|
url += '/_matrix/client/r0/join/' + event['room_id']
|
|
|
|
url += "?access_token=" + app.config['MATRIX_AS_TOKEN']
|
|
|
|
r = requests.post(url, headers={"Content-Type": "application/json"},
|
|
|
|
data=json.dumps({}))
|
|
|
|
if r.status_code == 200:
|
|
|
|
addadminrm = MatrixAdminRooms(matrix_id=event['sender'], room_id=event['room_id'])
|
|
|
|
db.session.add(addadminrm)
|
|
|
|
db.session.commit()
|
2017-05-04 06:01:51 +00:00
|
|
|
|
2017-05-25 00:04:27 +00:00
|
|
|
elif event['content']['membership'] == 'invite':
|
|
|
|
logging.info('>> GOT ROOM INVITE')
|
|
|
|
txId += 1
|
|
|
|
url = app.config['MATRIX_HOST']
|
|
|
|
url += '/_matrix/client/r0/join/' + event['room_id']
|
|
|
|
url += "?access_token=" + app.config['MATRIX_AS_TOKEN']
|
|
|
|
r = requests.post(url, headers={"Content-Type": "application/json"},
|
|
|
|
data=json.dumps({}))
|
|
|
|
|
2017-05-25 14:01:22 +00:00
|
|
|
elif event['content']['membership'] == 'leave':
|
2017-05-05 00:17:45 +00:00
|
|
|
adminrm = MatrixAdminRooms.query.filter_by(room_id=event['room_id']).first()
|
|
|
|
if adminrm:
|
2017-05-04 23:40:32 +00:00
|
|
|
logging.info('>> GOT LEAVE')
|
|
|
|
txId += 1
|
|
|
|
url = app.config['MATRIX_HOST']
|
|
|
|
url += '/_matrix/client/r0/rooms/' + event['room_id'] + "/leave"
|
|
|
|
url += "?access_token=" + app.config['MATRIX_AS_TOKEN']
|
|
|
|
r = requests.post(url, headers={"Content-Type": "application/json"},
|
|
|
|
data=json.dumps({}))
|
|
|
|
if r.status_code == 200:
|
|
|
|
db.session.delete(adminrm)
|
|
|
|
db.session.commit()
|
2017-05-04 06:01:51 +00:00
|
|
|
|
|
|
|
|
2017-03-04 21:45:09 +00:00
|
|
|
return jsonify({})
|
|
|
|
|
|
|
|
@app.route("/rooms/<alias>")
|
|
|
|
def query_alias(alias):
|
|
|
|
alias_localpart = alias.split(":")[0][1:]
|
|
|
|
try:
|
|
|
|
channel_id = int(alias_localpart.split('_')[1])
|
|
|
|
r = requests.get('https://api.pnut.io/v0/channels/' + str(channel_id) + '?include_raw=1')
|
|
|
|
if r.status_code == 200:
|
|
|
|
cdata = json.loads(r.text)['data']
|
|
|
|
if cdata['type'] != 'io.pnut.core.chat':
|
|
|
|
abort(404)
|
2017-03-05 21:05:09 +00:00
|
|
|
if 'is_active' in cdata:
|
|
|
|
if not cdata['is_active']:
|
|
|
|
abort(404)
|
2017-03-04 21:45:09 +00:00
|
|
|
raw = cdata['raw']
|
|
|
|
for item in raw:
|
|
|
|
if item['type'] == 'io.pnut.core.chat-settings':
|
|
|
|
chan_settings = item['value']
|
|
|
|
else:
|
|
|
|
abort(404)
|
|
|
|
except:
|
|
|
|
raise
|
|
|
|
abort(404)
|
|
|
|
|
|
|
|
mroom = {'room_alias_name': alias_localpart}
|
|
|
|
if 'name' in chan_settings:
|
|
|
|
mroom['name'] = chan_settings['name']
|
|
|
|
if 'description' in chan_settings:
|
|
|
|
mroom['topic'] = chan_settings['description']
|
|
|
|
if cdata['acl']['read']['any_user']:
|
|
|
|
mroom['preset'] = 'public_chat'
|
|
|
|
mroom['visibility'] = 'public'
|
|
|
|
|
|
|
|
resp = requests.post(
|
|
|
|
# NB: "TOKEN" is the as_token referred to in registration.yaml
|
|
|
|
"http://localhost:8008/_matrix/client/api/v1/createRoom?access_token=" + app.config['MATRIX_AS_TOKEN'],
|
|
|
|
json.dumps(mroom),
|
|
|
|
headers={"Content-Type":"application/json"}
|
|
|
|
)
|
|
|
|
|
|
|
|
if resp.status_code == 200:
|
|
|
|
room_id = json.loads(resp.text)['room_id']
|
|
|
|
mro = MatrixRoom(room_id, channel_id, cdata['acl']['write']['any_user'])
|
|
|
|
db.session.add(mro)
|
|
|
|
db.session.commit()
|
|
|
|
|
|
|
|
return jsonify({})
|
|
|
|
|
|
|
|
@app.errorhandler(404)
|
|
|
|
def not_found(error):
|
|
|
|
return jsonify({'errcode':'COM.MONKEYSTEW.PNUT_NOT_FOUND'}), 404
|
|
|
|
|
2017-04-25 01:55:44 +00:00
|
|
|
def get_displayname(userid):
|
|
|
|
url = "http://localhost:8008/_matrix/client/r0/profile/" + userid
|
|
|
|
r = requests.get(url)
|
|
|
|
if r.status_code == 200:
|
|
|
|
data = json.loads(r.text)
|
2017-04-25 02:05:17 +00:00
|
|
|
if 'displayname' in data:
|
|
|
|
return data["displayname"]
|
|
|
|
return userid
|