cammiechat/chat.py

157 lines
4.5 KiB
Python
Raw Permalink Normal View History

2018-12-04 20:07:17 +01:00
#!/bin/false
# Don't run directly, use gunicorn
2024-09-26 20:52:45 +02:00
from flask import Flask, request, render_template
2019-10-08 02:21:36 +02:00
from flask_socketio import SocketIO, emit, send
2018-12-04 20:07:17 +01:00
import subprocess
import json
from datetime import datetime
from collections import defaultdict
2019-08-02 20:34:45 +02:00
from urllib.parse import urlencode
2019-08-02 20:45:33 +02:00
import urllib.request
2019-08-02 20:38:56 +02:00
import base64
2022-02-28 19:55:51 +01:00
import requests
2024-09-26 20:52:45 +02:00
import socket
2018-12-04 20:07:17 +01:00
app = Flask(__name__)
2019-10-08 03:46:04 +02:00
# This is fine
socketio = SocketIO(app, cors_allowed_origins='*')
2018-12-04 20:07:17 +01:00
messages = []
timeout = 1
class Message:
2024-09-26 20:52:45 +02:00
def __init__(self, time, sender, sendertype, msg, sid = None):
2018-12-04 20:07:17 +01:00
self.time = time
2024-09-26 20:52:45 +02:00
self.sid = sid
2018-12-04 20:07:17 +01:00
self.sender = sender
self.sendertype = sendertype
self.msg = msg
2024-09-26 20:52:45 +02:00
def send_message(message) -> tuple:
2018-12-04 20:07:17 +01:00
2024-09-26 20:52:45 +02:00
if not message.msg:
return (False,"No message found")
if len(message.msg) > 200:
return (False,"Message too long, maximum 200")
messages.append(message)
# Send message to MessageOS
msg_with_sendr: str = "<{}> {}".format(message.sender, message.msg) if message.sender != "somebody" else message.msg
msg_b64 = base64.b64encode(msg_with_sendr.encode())
url = "http://10.0.5.42:8000/" # Set destination URL here
post_fields = {"X-Messages": msg_b64}
assembly_request = urllib.request.Request(url, urlencode(post_fields).encode())
assembly_request.add_header("X-Messages", msg_b64)
urllib.request.urlopen(assembly_request).read().decode()
2018-12-04 20:07:17 +01:00
try:
2024-09-26 20:52:45 +02:00
requests.put("http://10.0.0.10/api/mailbox.json", json={"topic": "morsemessage", "message": msg_with_sendr})
2018-12-04 20:07:17 +01:00
except:
pass
2024-09-26 20:52:45 +02:00
return (True,"OK")
2018-12-04 20:07:17 +01:00
2024-09-26 20:52:45 +02:00
def reverse_lookup(ip):
rdns = socket.getnameinfo((ip, 0), 0)
if rdns:
ip = rdns[0]
return ip
2019-10-08 02:21:36 +02:00
2024-09-26 20:52:45 +02:00
@app.route("/messages/")
def messages_get():
return render_template("chat.html", messages=messages[::-1])
2019-10-08 02:21:36 +02:00
2024-09-26 20:52:45 +02:00
@app.route("/reply/", methods = ["POST"])
def reply_post():
if request.data:
2019-10-08 02:21:36 +02:00
message = request.data.decode()
if len(message) > 200:
return "Message too long, maximum 200"
if not message:
return "No message found"
2024-09-26 20:52:45 +02:00
if len(messages) > 0 and messages[-1].sid:
socketio.emit('replymessage', {'message': message},to=messages[-1].sid)
return "Message sent\n"
else:
return "Could not reply"
2021-09-27 15:17:31 +02:00
return "Failed\n"
2018-12-04 20:07:17 +01:00
2024-09-26 20:52:45 +02:00
@socketio.on('message')
def message_socket(data):
if data.get("username"):
sender = data.get("username")
sendertype = "name"
elif "X-Real-IP" in request.headers:
sender = reverse_lookup(request.headers["X-Real-IP"])
sendertype = "ip"
else:
sender = "somebody"
sendertype = "unknown"
ok, return_message = send_message(Message(datetime.now(), sender, sendertype, data.get("message"), sid = request.sid))
return return_message
2018-12-04 20:07:17 +01:00
@app.route("/messages/", methods = ["POST"])
def messages_post():
if request.data:
2024-09-26 20:52:45 +02:00
if "X-Username" in request.headers and len(request.headers["X-Username"]) > 0:
2018-12-04 20:07:17 +01:00
sender = request.headers["X-Username"]
sendertype = "name"
elif "X-Real-IP" in request.headers:
2024-09-26 20:52:45 +02:00
sender = reverse_lookup(request.headers["X-Real-IP"])
2018-12-04 20:07:17 +01:00
sendertype = "ip"
else:
2024-09-26 20:52:45 +02:00
sender = "-"
2018-12-04 20:07:17 +01:00
sendertype = "unknown"
2019-09-03 01:05:40 +02:00
message = request.data.decode()
2019-09-03 00:36:39 +02:00
if not message:
2018-12-04 20:07:17 +01:00
return "No message found"
2024-09-26 20:52:45 +02:00
headers = {
'X-Username': sender,
}
data = {
'message': message
}
2019-09-03 00:27:49 +02:00
2024-09-26 20:52:45 +02:00
try:
response = requests.post("http://10.0.0.171:8080/message", headers=headers, json=data)
response.raise_for_status()
except:
pass
2019-09-03 00:27:49 +02:00
2019-09-03 01:05:40 +02:00
msg_with_sendr: str = "<{}> {}".format(sender, message) if sender != "somebody" else message
2022-02-28 19:55:51 +01:00
try:
requests.put("http://10.0.0.10/api/mailbox.json", json={"topic": "morsemessage", "message": msg_with_sendr})
except:
pass
2018-12-04 20:07:17 +01:00
2024-09-26 20:52:45 +02:00
messages.append(Message(datetime.now(), sender, sendertype, message))
2018-12-04 20:07:17 +01:00
2024-09-26 20:52:45 +02:00
return ""
else:
return ""
2018-12-04 20:07:17 +01:00
2022-02-28 19:58:51 +01:00
# make sure only messages from the last hour are sent
# this command also only sends messages the user doesn't have yet.
@app.route('/<last_index>/api.json')
def api(last_index):
curr_time = datetime.now()
ci = len(messages)-1
while curr_time - messages[ci].time < datetime.timedelta(hours = 1) and ci > last_index:
ci -= 1
return jsonify({"newest_msg_index": len(messages) , "messages": messages[ci:]})
2018-12-04 20:07:17 +01:00
if __name__ == "__main__":
2024-09-26 20:52:45 +02:00
socketio.run(app,port=3000,host='0.0.0.0')