cammiechat/chat.py

157 lines
4.4 KiB
Python

#!/bin/false
# Don't run directly, use gunicorn
from flask import Flask, request, escape, render_template
from flask_socketio import SocketIO, emit, send
import subprocess
import json
from datetime import datetime
from collections import defaultdict
import mpd
from urllib.parse import urlencode
import urllib.request
import base64
import requests
from dataclasses import dataclass
mpc = mpd.MPDClient()
mpc.timeout = 0.2
app = Flask(__name__, static_url_path='/static')
# This is fine
socketio = SocketIO(app, cors_allowed_origins='*')
messages = []
last_sent = defaultdict(lambda: datetime(1970,1,1))
timeout = 1
@dataclass
class Message:
time: datetime
sender: str
sendertype: str
msg: str
@app.route("/messages/")
def messages_get():
try:
mpc.connect("localhost", 6600)
song = mpc.currentsong()
status = mpc.status()
except:
status = {"state": "not connected"}
song = {}
try:
mpc.disconnect()
except:
pass
return render_template("message_os.html", messages=messages, mpd_song=song, mpd_status=status)
@app.route("/reply/", methods = ["POST"])
def reply_post():
if request.data:
if "X-Username" in request.headers:
sender = request.headers["X-Username"]
sendertype = "name"
elif "X-Real-IP" in request.headers:
sender = request.headers["X-Real-IP"]
sendertype = "ip"
else:
sender = "somebody"
sendertype = "unknown"
if sender[:6] == "abefor":
sender = "abeforkelder"
time = datetime.now()
last_sent_from_ip = last_sent[sendertype + sender]
last_sent[sendertype + sender] = time
if (time-last_sent_from_ip).total_seconds() < timeout:
return "OK Felix"
message = request.data.decode()
if len(message) > 200:
return "Message too long, maximum 200"
if not message:
return "No message found"
socketio.emit('replymessage', {'message': message}, broadcast=True)
return "Message sent\n"
return "Failed\n"
@app.route("/messages/", methods = ["POST"])
def messages_post():
if request.data:
if "X-Username" in request.headers:
sender = request.headers["X-Username"]
sendertype = "name"
elif "X-Real-IP" in request.headers:
sender = request.headers["X-Real-IP"]
sendertype = "ip"
else:
sender = "somebody"
sendertype = "unknown"
if sender[:6] == "abefor":
sender = "abeforkelder"
time = datetime.now()
last_sent_from_ip = last_sent[sendertype + sender]
last_sent[sendertype + sender] = time
if (time-last_sent_from_ip).total_seconds() < timeout:
return "OK Felix"
message = request.data.decode()
if len(message) > 200:
return "Message too long, maximum 200"
if not message:
return "No message found"
if "spam" in message.lower():
messages.append(Message(time, "1.3.3.7", "ip", "Nee"))
return "OK"
# Save message to serve it in this application
messages.append(Message(time, sender, sendertype, message))
# Send message to MessageOS
msg_with_sendr: str = "<{}> {}".format(sender, message) if sender != "somebody" else message
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()
try:
requests.put("http://10.0.0.10/api/mailbox.json", json={"topic": "morsemessage", "message": msg_with_sendr})
except:
pass
return "OK"
# 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:]})
if __name__ == "__main__":
socketio.run(app)