Compare commits

..

No commits in common. "19c4cb71f6cb824f5fa7b605d811d23dbcca8056" and "0e8ec152f073f4b5b32df66a78a6d40248b84c3e" have entirely different histories.

8 changed files with 109 additions and 106 deletions

View file

@ -1,8 +0,0 @@
import requests
import time
while True:
data = requests.get("https://kelder.zeus.ugent.be/camera/api/info").json()
cammie_watchers = data['connections']['/']
r = requests.put('http://10.0.0.10/api/mailbox.json', json={'message':str(cammie_watchers), 'topic': 'cammie'})
time.sleep(1)

198
chat.py
View file

@ -1,45 +1,131 @@
#!/bin/false
# Don't run directly, use gunicorn
from flask import Flask, request, render_template
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
import socket
mpc = mpd.MPDClient()
mpc.timeout = 0.2
app = Flask(__name__)
# This is fine
socketio = SocketIO(app, cors_allowed_origins='*')
messages = []
last_sent = defaultdict(lambda: datetime(1970,1,1))
timeout = 1
class Message:
def __init__(self, time, sender, sendertype, msg, sid = None):
def __init__(self, time, sender, sendertype, msg):
self.time = time
self.sid = sid
self.sender = sender
self.sendertype = sendertype
self.msg = msg
def send_message(message) -> tuple:
if not message.msg:
return (False,"No message found")
@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
if len(message.msg) > 200:
return (False,"Message too long, maximum 200")
return render_template("chat.html", messages=messages[::-1], mpd_song=song, mpd_status=status)
messages.append(message)
@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(message.sender, message.msg) if message.sender != "somebody" else message.msg
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
@ -52,94 +138,8 @@ def send_message(message) -> tuple:
except:
pass
return (True,"OK")
return "OK"
def reverse_lookup(ip):
rdns = socket.getnameinfo((ip, 0), 0)
if rdns:
ip = rdns[0]
return ip
@app.route("/messages/")
def messages_get():
return render_template("chat.html", messages=messages[::-1])
@app.route("/reply/", methods = ["POST"])
def reply_post():
if request.data:
message = request.data.decode()
if len(message) > 200:
return "Message too long, maximum 200"
if not message:
return "No message found"
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"
return "Failed\n"
@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
@app.route("/messages/", methods = ["POST"])
def messages_post():
if request.data:
if "X-Username" in request.headers and len(request.headers["X-Username"]) > 0:
sender = request.headers["X-Username"]
sendertype = "name"
elif "X-Real-IP" in request.headers:
sender = reverse_lookup(request.headers["X-Real-IP"])
sendertype = "ip"
else:
sender = "-"
sendertype = "unknown"
message = request.data.decode()
if not message:
return "No message found"
headers = {
'X-Username': sender,
}
data = {
'message': message
}
try:
response = requests.post("http://10.0.0.171:8080/message", headers=headers, json=data)
response.raise_for_status()
except:
pass
msg_with_sendr: str = "<{}> {}".format(sender, message) if sender != "somebody" else message
try:
requests.put("http://10.0.0.10/api/mailbox.json", json={"topic": "morsemessage", "message": msg_with_sendr})
except:
pass
messages.append(Message(datetime.now(), sender, sendertype, message))
return ""
else:
return ""
# make sure only messages from the last hour are sent
# this command also only sends messages the user doesn't have yet.
@ -153,4 +153,4 @@ def api(last_index):
if __name__ == "__main__":
socketio.run(app,port=3000,host='0.0.0.0')
socketio.run(app)

View file

@ -1,10 +0,0 @@
import serial
import requests
ser = serial.Serial('/dev/ttyUSB0')
while True:
line = ser.readline()
out = requests.post("http://localhost:3000/reply",data=line.decode()[:-1])
ser.close()

View file

@ -1,3 +0,0 @@
flask
requests
flask_socketio

View file

@ -2,4 +2,13 @@
killall gunicorn
./run.sh & disown
sleep 1
DISPLAY=:0 xdotool key ctrl+F5
sleep 5
DISPLAY=:0 xdotool key ctrl+F5
sleep 10
DISPLAY=:0 xdotool key ctrl+F5
sleep 10
DISPLAY=:0 xdotool key ctrl+F5
sleep 10
DISPLAY=:0 xdotool key ctrl+F5

6
run.py
View file

@ -1,6 +0,0 @@
#!/usr/bin/env python3
from chat import app
from chat import socketio
socketio.run(app,port=3000,host='0.0.0.0',allow_unsafe_werkzeug=True)

7
run.sh Executable file
View file

@ -0,0 +1,7 @@
#!/bin/bash
cd "$(dirname "$0")"
poetry install
export FLASK_APP=chat.py
exec poetry run gunicorn --worker-class eventlet -w 1 -b0.0.0.0:5000 chat:app

View file

@ -37,17 +37,31 @@
.msg .sender.name:before { content: "<"; } .msg .sender.name:after { content: ">"; }
.msg .sender.ip:before { content: "["; } .msg .sender.ip:after { content: "]"; }
.mpd-status { margin-bottom: 0.2em; }
.mpd-status:before { content: " ▶ "; }
</style>
<title>Messages from the world to kelder</title>
<meta http-equiv="refresh" content="5" />
</head>
<body>
{% if mpd_status["state"] == "play" %}
{% if mpd_song["artist"] and mpd_song["title"] %}
<div class="mpd-status"><span class="artist">{{ mpd_song["artist"] }}</span><span class="between artist-title"> </span><span class="title">{{ mpd_song["title"] }}</span></div>
{% elif mpd_song["title"] %}
<div class="mpd-status"><span class="title">{{ mpd_song["title"] }}</span></div>
{% elif mpd_song["artist"] %}
<div class="mpd-status"><span class="artist">{{ mpd_song["artist"] }}</span></div>
{% else %}
<div class="mpd-status">Unknown music, fix your metadata!</div>
{% endif %}
{% endif %}
<h1>Messages</h1>
{% for m in messages %}
<div class="msg_wrapper">
<div class="msg"><!--
--><span class="meta"><!--
--><time datetime="{{ m.time }}">{{ "{:%d/%m %H:%M:%S}".format(m.time) }}</time><!--
--><time datetime="{{ m.time }}">{{ "{:%d/%m %H:%M:%S}".format(m.time) }}</time><span class="between time-sender"> - </span><!--
--><span class="sender {{ m.sendertype }}">{{ m.sender }}</span><span class="between sender-msg">: </span><!--
--></span><!--
--><span class="msg">{{ m.msg }}</span><!--
--></div>