Initial commit
This commit is contained in:
commit
63ef8de457
5 changed files with 185 additions and 0 deletions
13
.editorconfig
Normal file
13
.editorconfig
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
# https://editorconfig.org
|
||||||
|
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
charset = utf-8
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
indent_style = tab
|
||||||
|
|
||||||
|
[*.py]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 4
|
90
chat.py
Normal file
90
chat.py
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
#!/bin/false
|
||||||
|
# Don't run directly, use gunicorn
|
||||||
|
|
||||||
|
from flask import Flask, request, escape, render_template
|
||||||
|
import subprocess
|
||||||
|
import json
|
||||||
|
from datetime import datetime
|
||||||
|
from collections import defaultdict
|
||||||
|
import mpd
|
||||||
|
|
||||||
|
|
||||||
|
mpc = mpd.MPDClient()
|
||||||
|
mpc.timeout = 0.2
|
||||||
|
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
messages = []
|
||||||
|
last_sent = defaultdict(lambda: datetime(1970,1,1))
|
||||||
|
|
||||||
|
timeout = 1
|
||||||
|
|
||||||
|
|
||||||
|
class Message:
|
||||||
|
def __init__(self, time, sender, sendertype, msg):
|
||||||
|
self.time = time
|
||||||
|
self.sender = sender
|
||||||
|
self.sendertype = sendertype
|
||||||
|
self.msg = msg
|
||||||
|
|
||||||
|
|
||||||
|
@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("chat.html", messages=messages[::-1], mpd_song=song, mpd_status=status)
|
||||||
|
|
||||||
|
|
||||||
|
@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
|
||||||
|
|
||||||
|
if len(message) > 200:
|
||||||
|
return "Message too long, maximum 200"
|
||||||
|
|
||||||
|
if len(message) == 0:
|
||||||
|
return "No message found"
|
||||||
|
|
||||||
|
if "spam" in str(message, "UTF-8").lower():
|
||||||
|
messages.append(Message(time, "1.3.3.7", "ip", "Nee"))
|
||||||
|
else:
|
||||||
|
messages.append(Message(time, sender, sendertype, str(message, "UTF-8")))
|
||||||
|
|
||||||
|
subprocess.Popen(("espeak", "-vnl"), input=message, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||||
|
return "OK"
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
app.run()
|
6
restart.sh
Executable file
6
restart.sh
Executable file
|
@ -0,0 +1,6 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
killall gunicorn
|
||||||
|
./runChat & disown
|
||||||
|
sleep 1
|
||||||
|
DISPLAY=:0 xdotool key F5
|
5
run.sh
Executable file
5
run.sh
Executable file
|
@ -0,0 +1,5 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
cd "$(dirname "$0")"
|
||||||
|
export FLASK_APP=chat.py
|
||||||
|
exec gunicorn -w 1 -b127.0.0.1:5000 chat:app
|
71
templates/chat.html
Normal file
71
templates/chat.html
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: monospace;
|
||||||
|
background: black;
|
||||||
|
color: #00ff00;
|
||||||
|
font-size: 300%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
margin: -2em 0 1em;
|
||||||
|
color: transparent;
|
||||||
|
text-align: left;
|
||||||
|
font-size: 75%;
|
||||||
|
white-space: pre;
|
||||||
|
text-indent: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
h1:after {
|
||||||
|
text-indent: 0;
|
||||||
|
display: block;
|
||||||
|
color: #00cc00;
|
||||||
|
content: " _ _ ____ ____ ____ __ ___ ____ ____\a( \\/ )( __)/ ___)/ ___) / _\\ / __)( __)/ ___)\a/ \\/ \\ ) _) \\___ \\\\___ \\/ \\( (_ \\ ) _) \\___ \\\a\\_)(_/(____)(____/(____/\\_/\\_/ \\___/(____)(____/";
|
||||||
|
}
|
||||||
|
.msg_wrapper { margin-bottom: 0.3em; }
|
||||||
|
.msg .meta { background-color: #00ff00; margin-right: 0.6em; }
|
||||||
|
.msg .meta:before { content: " "; }
|
||||||
|
.msg .meta .between { display: inline-block; width: 0px; height: 1px; overflow: hidden; }
|
||||||
|
.msg time { color: #000; margin-right: 0.7em; }
|
||||||
|
.msg .sender { color: #000; }
|
||||||
|
.msg .sender:before { content: "!{"; } .msg .sender:after { content: "}!"; margin-right: 0.5em; }
|
||||||
|
.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 }}">{{ "{:0=2d}".format(m.time.hour) }}:{{ "{:0=2d}".format(m.time.minute) }}:{{ "{:0=2d}".format(m.time.second) }}</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>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Reference in a new issue