Compare commits

...

4 commits

Author SHA1 Message Date
739295e865 Limit sender username 2024-10-23 14:10:35 +02:00
19c4cb71f6 Merge pull request 'updates from korner' (#7) from axdzitte/cammiechat:master into master
Reviewed-on: #7
2024-10-10 13:11:41 +02:00
c17fa92ec1 Added cammiewatcher 2024-09-29 17:31:19 +02:00
unknown
12c261b0b1 updates 2024-09-26 20:52:45 +02:00
8 changed files with 106 additions and 107 deletions

8
cammiewatcher.py Normal file
View file

@ -0,0 +1,8 @@
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)

152
chat.py
View file

@ -1,77 +1,73 @@
#!/bin/false #!/bin/false
# Don't run directly, use gunicorn # Don't run directly, use gunicorn
from flask import Flask, request, escape, render_template from flask import Flask, request, render_template
from flask_socketio import SocketIO, emit, send from flask_socketio import SocketIO, emit, send
import subprocess import subprocess
import json import json
from datetime import datetime from datetime import datetime
from collections import defaultdict from collections import defaultdict
import mpd
from urllib.parse import urlencode from urllib.parse import urlencode
import urllib.request import urllib.request
import base64 import base64
import requests import requests
import socket
mpc = mpd.MPDClient()
mpc.timeout = 0.2
app = Flask(__name__) app = Flask(__name__)
# This is fine # This is fine
socketio = SocketIO(app, cors_allowed_origins='*') socketio = SocketIO(app, cors_allowed_origins='*')
messages = [] messages = []
last_sent = defaultdict(lambda: datetime(1970,1,1))
timeout = 1 timeout = 1
class Message: class Message:
def __init__(self, time, sender, sendertype, msg): def __init__(self, time, sender, sendertype, msg, sid = None):
self.time = time self.time = time
self.sid = sid
self.sender = sender self.sender = sender
self.sendertype = sendertype self.sendertype = sendertype
self.msg = msg self.msg = msg
def send_message(message) -> tuple:
@app.route("/messages/") if not message.msg:
def messages_get(): 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()
try: try:
mpc.connect("localhost", 6600) requests.put("http://10.0.0.10/api/mailbox.json", json={"topic": "morsemessage", "message": msg_with_sendr})
song = mpc.currentsong()
status = mpc.status()
except:
status = {"state": "not connected"}
song = {}
try:
mpc.disconnect()
except: except:
pass pass
return render_template("chat.html", messages=messages[::-1], mpd_song=song, mpd_status=status) return (True,"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"]) @app.route("/reply/", methods = ["POST"])
def reply_post(): def reply_post():
if request.data: 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() message = request.data.decode()
@ -80,66 +76,72 @@ def reply_post():
if not message: if not message:
return "No message found" return "No message found"
socketio.emit('replymessage', {'message': message}, broadcast=True) if len(messages) > 0 and messages[-1].sid:
return "Message sent\n" socketio.emit('replymessage', {'message': message},to=messages[-1].sid)
return "Message sent\n"
else:
return "Could not reply"
return "Failed\n" 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"]) @app.route("/messages/", methods = ["POST"])
def messages_post(): def messages_post():
if request.data: if request.data:
if "X-Username" in request.headers: if "X-Username" in request.headers and len(request.headers["X-Username"]) > 0:
sender = request.headers["X-Username"] sender = request.headers["X-Username"]
sendertype = "name" sendertype = "name"
if len(sender) > 50:
return "Username too long"
elif "X-Real-IP" in request.headers: elif "X-Real-IP" in request.headers:
sender = request.headers["X-Real-IP"] sender = reverse_lookup(request.headers["X-Real-IP"])
sendertype = "ip" sendertype = "ip"
else: else:
sender = "somebody" sender = "-"
sendertype = "unknown" 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() message = request.data.decode()
if len(message) > 200:
return "Message too long, maximum 200"
if not message: if not message:
return "No message found" return "No message found"
if "spam" in message.lower(): headers = {
messages.append(Message(time, "1.3.3.7", "ip", "Nee")) 'X-Username': sender,
return "OK" }
data = {
'message': message
}
try:
response = requests.post("http://10.0.0.171:8080/message", headers=headers, json=data)
response.raise_for_status()
except:
pass
# 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_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: try:
requests.put("http://10.0.0.10/api/mailbox.json", json={"topic": "morsemessage", "message": msg_with_sendr}) requests.put("http://10.0.0.10/api/mailbox.json", json={"topic": "morsemessage", "message": msg_with_sendr})
except: except:
pass pass
return "OK" messages.append(Message(datetime.now(), sender, sendertype, message))
return ""
else:
return ""
# make sure only messages from the last hour are sent # make sure only messages from the last hour are sent
# this command also only sends messages the user doesn't have yet. # this command also only sends messages the user doesn't have yet.
@ -153,4 +155,4 @@ def api(last_index):
if __name__ == "__main__": if __name__ == "__main__":
socketio.run(app) socketio.run(app,port=3000,host='0.0.0.0')

10
pyserial.py Normal file
View file

@ -0,0 +1,10 @@
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()

3
requirements.txt Normal file
View file

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

View file

@ -2,13 +2,4 @@
killall gunicorn killall gunicorn
./run.sh & disown ./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 Executable file
View file

@ -0,0 +1,6 @@
#!/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
View file

@ -1,7 +0,0 @@
#!/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,31 +37,17 @@
.msg .sender.name:before { content: "<"; } .msg .sender.name:after { content: ">"; } .msg .sender.name:before { content: "<"; } .msg .sender.name:after { content: ">"; }
.msg .sender.ip:before { content: "["; } .msg .sender.ip:after { content: "]"; } .msg .sender.ip:before { content: "["; } .msg .sender.ip:after { content: "]"; }
.mpd-status { margin-bottom: 0.2em; }
.mpd-status:before { content: " ▶ "; }
</style> </style>
<title>Messages from the world to kelder</title> <title>Messages from the world to kelder</title>
<meta http-equiv="refresh" content="5" /> <meta http-equiv="refresh" content="5" />
</head> </head>
<body> <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> <h1>Messages</h1>
{% for m in messages %} {% for m in messages %}
<div class="msg_wrapper"> <div class="msg_wrapper">
<div class="msg"><!-- <div class="msg"><!--
--><span class="meta"><!-- --><span class="meta"><!--
--><time datetime="{{ m.time }}">{{ "{:%d/%m %H:%M:%S}".format(m.time) }}</time><span class="between time-sender"> - </span><!-- --><time datetime="{{ m.time }}">{{ "{:%d/%m %H:%M:%S}".format(m.time) }}</time><!--
--><span class="sender {{ m.sendertype }}">{{ m.sender }}</span><span class="between sender-msg">: </span><!--
--></span><!-- --></span><!--
--><span class="msg">{{ m.msg }}</span><!-- --><span class="msg">{{ m.msg }}</span><!--
--></div> --></div>