#!/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('//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)