Compare commits
No commits in common. "master" and "name_on_message" have entirely different histories.
master
...
name_on_me
12 changed files with 207 additions and 465 deletions
14
Pipfile
Normal file
14
Pipfile
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
[[source]]
|
||||||
|
url = "https://pypi.org/simple"
|
||||||
|
verify_ssl = true
|
||||||
|
name = "pypi"
|
||||||
|
|
||||||
|
[packages]
|
||||||
|
gunicorn = "*"
|
||||||
|
flask = "*"
|
||||||
|
"python-mpd2" = "*"
|
||||||
|
|
||||||
|
[dev-packages]
|
||||||
|
|
||||||
|
[requires]
|
||||||
|
python_version = "3.6"
|
106
Pipfile.lock
generated
Normal file
106
Pipfile.lock
generated
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
{
|
||||||
|
"_meta": {
|
||||||
|
"hash": {
|
||||||
|
"sha256": "804aaad19da42dd0078edca3a25a05492b4832c1a3b2f75601730dc4c7a43a3e"
|
||||||
|
},
|
||||||
|
"pipfile-spec": 6,
|
||||||
|
"requires": {
|
||||||
|
"python_version": "3.7"
|
||||||
|
},
|
||||||
|
"sources": [
|
||||||
|
{
|
||||||
|
"name": "pypi",
|
||||||
|
"url": "https://pypi.org/simple",
|
||||||
|
"verify_ssl": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"default": {
|
||||||
|
"click": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13",
|
||||||
|
"sha256:5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7"
|
||||||
|
],
|
||||||
|
"version": "==7.0"
|
||||||
|
},
|
||||||
|
"flask": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:2271c0070dbcb5275fad4a82e29f23ab92682dc45f9dfbc22c02ba9b9322ce48",
|
||||||
|
"sha256:a080b744b7e345ccfcbc77954861cb05b3c63786e93f2b3875e0913d44b43f05"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==1.0.2"
|
||||||
|
},
|
||||||
|
"gunicorn": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:aa8e0b40b4157b36a5df5e599f45c9c76d6af43845ba3b3b0efe2c70473c2471",
|
||||||
|
"sha256:fa2662097c66f920f53f70621c6c58ca4a3c4d3434205e608e121b5b3b71f4f3"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==19.9.0"
|
||||||
|
},
|
||||||
|
"itsdangerous": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19",
|
||||||
|
"sha256:b12271b2047cb23eeb98c8b5622e2e5c5e9abd9784a153e9d8ef9cb4dd09d749"
|
||||||
|
],
|
||||||
|
"version": "==1.1.0"
|
||||||
|
},
|
||||||
|
"jinja2": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:74c935a1b8bb9a3947c50a54766a969d4846290e1e788ea44c1392163723c3bd",
|
||||||
|
"sha256:f84be1bb0040caca4cea721fcbbbbd61f9be9464ca236387158b0feea01914a4"
|
||||||
|
],
|
||||||
|
"version": "==2.10"
|
||||||
|
},
|
||||||
|
"markupsafe": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:048ef924c1623740e70204aa7143ec592504045ae4429b59c30054cb31e3c432",
|
||||||
|
"sha256:130f844e7f5bdd8e9f3f42e7102ef1d49b2e6fdf0d7526df3f87281a532d8c8b",
|
||||||
|
"sha256:19f637c2ac5ae9da8bfd98cef74d64b7e1bb8a63038a3505cd182c3fac5eb4d9",
|
||||||
|
"sha256:1b8a7a87ad1b92bd887568ce54b23565f3fd7018c4180136e1cf412b405a47af",
|
||||||
|
"sha256:1c25694ca680b6919de53a4bb3bdd0602beafc63ff001fea2f2fc16ec3a11834",
|
||||||
|
"sha256:1f19ef5d3908110e1e891deefb5586aae1b49a7440db952454b4e281b41620cd",
|
||||||
|
"sha256:1fa6058938190ebe8290e5cae6c351e14e7bb44505c4a7624555ce57fbbeba0d",
|
||||||
|
"sha256:31cbb1359e8c25f9f48e156e59e2eaad51cd5242c05ed18a8de6dbe85184e4b7",
|
||||||
|
"sha256:3e835d8841ae7863f64e40e19477f7eb398674da6a47f09871673742531e6f4b",
|
||||||
|
"sha256:4e97332c9ce444b0c2c38dd22ddc61c743eb208d916e4265a2a3b575bdccb1d3",
|
||||||
|
"sha256:525396ee324ee2da82919f2ee9c9e73b012f23e7640131dd1b53a90206a0f09c",
|
||||||
|
"sha256:52b07fbc32032c21ad4ab060fec137b76eb804c4b9a1c7c7dc562549306afad2",
|
||||||
|
"sha256:52ccb45e77a1085ec5461cde794e1aa037df79f473cbc69b974e73940655c8d7",
|
||||||
|
"sha256:5c3fbebd7de20ce93103cb3183b47671f2885307df4a17a0ad56a1dd51273d36",
|
||||||
|
"sha256:5e5851969aea17660e55f6a3be00037a25b96a9b44d2083651812c99d53b14d1",
|
||||||
|
"sha256:5edfa27b2d3eefa2210fb2f5d539fbed81722b49f083b2c6566455eb7422fd7e",
|
||||||
|
"sha256:7d263e5770efddf465a9e31b78362d84d015cc894ca2c131901a4445eaa61ee1",
|
||||||
|
"sha256:83381342bfc22b3c8c06f2dd93a505413888694302de25add756254beee8449c",
|
||||||
|
"sha256:857eebb2c1dc60e4219ec8e98dfa19553dae33608237e107db9c6078b1167856",
|
||||||
|
"sha256:98e439297f78fca3a6169fd330fbe88d78b3bb72f967ad9961bcac0d7fdd1550",
|
||||||
|
"sha256:bf54103892a83c64db58125b3f2a43df6d2cb2d28889f14c78519394feb41492",
|
||||||
|
"sha256:d9ac82be533394d341b41d78aca7ed0e0f4ba5a2231602e2f05aa87f25c51672",
|
||||||
|
"sha256:e982fe07ede9fada6ff6705af70514a52beb1b2c3d25d4e873e82114cf3c5401",
|
||||||
|
"sha256:edce2ea7f3dfc981c4ddc97add8a61381d9642dc3273737e756517cc03e84dd6",
|
||||||
|
"sha256:efdc45ef1afc238db84cb4963aa689c0408912a0239b0721cb172b4016eb31d6",
|
||||||
|
"sha256:f137c02498f8b935892d5c0172560d7ab54bc45039de8805075e19079c639a9c",
|
||||||
|
"sha256:f82e347a72f955b7017a39708a3667f106e6ad4d10b25f237396a7115d8ed5fd",
|
||||||
|
"sha256:fb7c206e01ad85ce57feeaaa0bf784b97fa3cad0d4a5737bc5295785f5c613a1"
|
||||||
|
],
|
||||||
|
"version": "==1.1.0"
|
||||||
|
},
|
||||||
|
"python-mpd2": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:29119e3a88ef4a6f15acb1b83bab9344fba8eefc370e0144ffb77f5138e65dd7",
|
||||||
|
"sha256:772fa6861273bb9f363a97987c2c45ca3965eb770570f1f02566efec9c89fc5f"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==1.0.0"
|
||||||
|
},
|
||||||
|
"werkzeug": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:c3fd7a7d41976d9f44db327260e263132466836cef6f91512889ed60ad26557c",
|
||||||
|
"sha256:d5da73735293558eb1651ee2fddc4d0dedcfa06538b8813a2e20011583c9e49b"
|
||||||
|
],
|
||||||
|
"version": "==0.14.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"develop": {}
|
||||||
|
}
|
|
@ -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)
|
|
174
chat.py
174
chat.py
|
@ -1,158 +1,108 @@
|
||||||
#!/bin/false
|
#!/bin/false
|
||||||
# Don't run directly, use gunicorn
|
# 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 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 socket
|
mpc = mpd.MPDClient()
|
||||||
|
mpc.timeout = 0.2
|
||||||
|
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
# This is fine
|
|
||||||
socketio = SocketIO(app, cors_allowed_origins='*')
|
|
||||||
messages = []
|
messages = []
|
||||||
|
last_sent = defaultdict(lambda: datetime(1970,1,1))
|
||||||
|
|
||||||
timeout = 1
|
timeout = 1
|
||||||
|
|
||||||
|
|
||||||
|
def speak(text):
|
||||||
|
espk_proc = subprocess.Popen(("espeak", "-vnl"), stdin=subprocess.PIPE, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||||
|
espk_proc.stdin.write(text)
|
||||||
|
espk_proc.stdin.close()
|
||||||
|
|
||||||
|
|
||||||
class Message:
|
class Message:
|
||||||
def __init__(self, time, sender, sendertype, msg, sid = None):
|
def __init__(self, time, sender, sendertype, msg):
|
||||||
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:
|
|
||||||
|
|
||||||
if not message.msg:
|
|
||||||
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:
|
|
||||||
requests.put("http://10.0.0.10/api/mailbox.json", json={"topic": "morsemessage", "message": msg_with_sendr})
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
return (True,"OK")
|
|
||||||
|
|
||||||
def reverse_lookup(ip):
|
|
||||||
rdns = socket.getnameinfo((ip, 0), 0)
|
|
||||||
if rdns:
|
|
||||||
ip = rdns[0]
|
|
||||||
return ip
|
|
||||||
|
|
||||||
|
|
||||||
@app.route("/messages/")
|
@app.route("/messages/")
|
||||||
def messages_get():
|
def messages_get():
|
||||||
return render_template("chat.html", messages=messages[::-1])
|
try:
|
||||||
|
mpc.connect("localhost", 6600)
|
||||||
|
song = mpc.currentsong()
|
||||||
|
status = mpc.status()
|
||||||
|
except:
|
||||||
|
status = {"state": "not connected"}
|
||||||
|
song = {}
|
||||||
|
try:
|
||||||
|
mpc.disconnect()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
@app.route("/reply/", methods = ["POST"])
|
return render_template("chat.html", messages=messages[::-1], mpd_song=song, mpd_status=status)
|
||||||
def reply_post():
|
|
||||||
|
|
||||||
|
@app.route("/messages/", methods = ["POST"])
|
||||||
|
def messages_post():
|
||||||
if request.data:
|
if request.data:
|
||||||
|
if "X-Username" in request.headers:
|
||||||
message = request.data.decode()
|
sender = request.headers["X-Username"]
|
||||||
|
|
||||||
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"
|
sendertype = "name"
|
||||||
elif "X-Real-IP" in request.headers:
|
elif "X-Real-IP" in request.headers:
|
||||||
sender = reverse_lookup(request.headers["X-Real-IP"])
|
sender = request.headers["X-Real-IP"]
|
||||||
sendertype = "ip"
|
sendertype = "ip"
|
||||||
else:
|
else:
|
||||||
sender = "somebody"
|
sender = "somebody"
|
||||||
sendertype = "unknown"
|
sendertype = "unknown"
|
||||||
|
|
||||||
ok, return_message = send_message(Message(datetime.now(), sender, sendertype, data.get("message"), sid = request.sid))
|
if sender[:6] == "abefor":
|
||||||
|
sender = "abeforkelder"
|
||||||
|
|
||||||
return return_message
|
time = datetime.now()
|
||||||
|
last_sent_from_ip = last_sent[sendertype + sender]
|
||||||
|
|
||||||
@app.route("/messages/", methods = ["POST"])
|
last_sent[sendertype + sender] = time
|
||||||
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"
|
|
||||||
if len(sender) > 50:
|
|
||||||
return "Username too long"
|
|
||||||
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 (time-last_sent_from_ip).total_seconds() < timeout:
|
||||||
if not message:
|
return "OK Felix"
|
||||||
|
|
||||||
|
message = request.data
|
||||||
|
|
||||||
|
if len(message) > 200:
|
||||||
|
return "Message too long, maximum 200"
|
||||||
|
|
||||||
|
if len(message) == 0:
|
||||||
return "No message found"
|
return "No message found"
|
||||||
|
|
||||||
headers = {
|
if "spam" in str(message, "UTF-8").lower():
|
||||||
'X-Username': sender,
|
messages.append(Message(time, "1.3.3.7", "ip", "Nee"))
|
||||||
}
|
return "OK"
|
||||||
data = {
|
|
||||||
'message': message
|
|
||||||
}
|
|
||||||
|
|
||||||
try:
|
if sender != "somebody":
|
||||||
response = requests.post("http://10.0.0.171:8080/message", headers=headers, json=data)
|
message = "<" + sender + "> " + message.decode()
|
||||||
response.raise_for_status()
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
msg_with_sendr: str = "<{}> {}".format(sender, message) if sender != "somebody" else message
|
messages.append(Message(time, sender, sendertype, message))
|
||||||
try:
|
url = 'http://10.0.5.42:8000/' # Set destination URL here
|
||||||
requests.put("http://10.0.0.10/api/mailbox.json", json={"topic": "morsemessage", "message": msg_with_sendr})
|
post_fields = {'X-Messages': base64.b64encode(message)}
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
messages.append(Message(datetime.now(), sender, sendertype, message))
|
assembly_request = urllib.request.Request(url, urlencode(post_fields).encode())
|
||||||
|
assembly_request.add_header('X-Messages', base64.b64encode(message))
|
||||||
|
urllib.request.urlopen(assembly_request).read().decode()
|
||||||
|
speak(message)
|
||||||
|
|
||||||
return ""
|
return "OK"
|
||||||
else:
|
|
||||||
return ""
|
|
||||||
|
|
||||||
# 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__":
|
if __name__ == "__main__":
|
||||||
socketio.run(app,port=3000,host='0.0.0.0')
|
app.run()
|
||||||
|
|
303
poetry.lock
generated
303
poetry.lock
generated
|
@ -1,303 +0,0 @@
|
||||||
[[package]]
|
|
||||||
category = "main"
|
|
||||||
description = "Composable command line interface toolkit"
|
|
||||||
name = "click"
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
|
||||||
version = "7.0"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "main"
|
|
||||||
description = "DNS toolkit"
|
|
||||||
name = "dnspython"
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
|
||||||
version = "1.16.0"
|
|
||||||
|
|
||||||
[package.extras]
|
|
||||||
DNSSEC = ["pycryptodome", "ecdsa (>=0.13)"]
|
|
||||||
IDNA = ["idna (>=2.1)"]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "main"
|
|
||||||
description = "Highly concurrent networking library"
|
|
||||||
name = "eventlet"
|
|
||||||
optional = false
|
|
||||||
python-versions = "*"
|
|
||||||
version = "0.25.1"
|
|
||||||
|
|
||||||
[package.dependencies]
|
|
||||||
dnspython = ">=1.15.0"
|
|
||||||
greenlet = ">=0.3"
|
|
||||||
monotonic = ">=1.4"
|
|
||||||
six = ">=1.10.0"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "main"
|
|
||||||
description = "A simple framework for building complex web applications."
|
|
||||||
name = "flask"
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
|
||||||
version = "1.1.1"
|
|
||||||
|
|
||||||
[package.dependencies]
|
|
||||||
Jinja2 = ">=2.10.1"
|
|
||||||
Werkzeug = ">=0.15"
|
|
||||||
click = ">=5.1"
|
|
||||||
itsdangerous = ">=0.24"
|
|
||||||
|
|
||||||
[package.extras]
|
|
||||||
dev = ["pytest", "coverage", "tox", "sphinx", "pallets-sphinx-themes", "sphinxcontrib-log-cabinet", "sphinx-issues"]
|
|
||||||
docs = ["sphinx", "pallets-sphinx-themes", "sphinxcontrib-log-cabinet", "sphinx-issues"]
|
|
||||||
dotenv = ["python-dotenv"]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "main"
|
|
||||||
description = "Socket.IO integration for Flask applications"
|
|
||||||
name = "flask-socketio"
|
|
||||||
optional = false
|
|
||||||
python-versions = "*"
|
|
||||||
version = "4.2.1"
|
|
||||||
|
|
||||||
[package.dependencies]
|
|
||||||
Flask = ">=0.9"
|
|
||||||
python-socketio = ">=4.3.0"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "main"
|
|
||||||
description = "Lightweight in-process concurrent programming"
|
|
||||||
name = "greenlet"
|
|
||||||
optional = false
|
|
||||||
python-versions = "*"
|
|
||||||
version = "0.4.15"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "main"
|
|
||||||
description = "WSGI HTTP Server for UNIX"
|
|
||||||
name = "gunicorn"
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=3.4"
|
|
||||||
version = "20.0.4"
|
|
||||||
|
|
||||||
[package.dependencies]
|
|
||||||
setuptools = ">=3.0"
|
|
||||||
|
|
||||||
[package.extras]
|
|
||||||
eventlet = ["eventlet (>=0.9.7)"]
|
|
||||||
gevent = ["gevent (>=0.13)"]
|
|
||||||
setproctitle = ["setproctitle"]
|
|
||||||
tornado = ["tornado (>=0.2)"]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "main"
|
|
||||||
description = "Various helpers to pass data to untrusted environments and back."
|
|
||||||
name = "itsdangerous"
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
|
||||||
version = "1.1.0"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "main"
|
|
||||||
description = "A very fast and expressive template engine."
|
|
||||||
name = "jinja2"
|
|
||||||
optional = false
|
|
||||||
python-versions = "*"
|
|
||||||
version = "2.10.3"
|
|
||||||
|
|
||||||
[package.dependencies]
|
|
||||||
MarkupSafe = ">=0.23"
|
|
||||||
|
|
||||||
[package.extras]
|
|
||||||
i18n = ["Babel (>=0.8)"]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "main"
|
|
||||||
description = "Safely add untrusted strings to HTML/XML markup."
|
|
||||||
name = "markupsafe"
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*"
|
|
||||||
version = "1.1.1"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "main"
|
|
||||||
description = "An implementation of time.monotonic() for Python 2 & < 3.3"
|
|
||||||
name = "monotonic"
|
|
||||||
optional = false
|
|
||||||
python-versions = "*"
|
|
||||||
version = "1.5"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "main"
|
|
||||||
description = "Engine.IO server"
|
|
||||||
name = "python-engineio"
|
|
||||||
optional = false
|
|
||||||
python-versions = "*"
|
|
||||||
version = "3.11.2"
|
|
||||||
|
|
||||||
[package.dependencies]
|
|
||||||
six = ">=1.9.0"
|
|
||||||
|
|
||||||
[package.extras]
|
|
||||||
asyncio_client = ["aiohttp (>=3.4)"]
|
|
||||||
client = ["requests (>=2.21.0)", "websocket-client (>=0.54.0)"]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "main"
|
|
||||||
description = "A Python MPD client library"
|
|
||||||
name = "python-mpd2"
|
|
||||||
optional = false
|
|
||||||
python-versions = "*"
|
|
||||||
version = "1.0.0"
|
|
||||||
|
|
||||||
[package.extras]
|
|
||||||
twisted = ["twisted"]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "main"
|
|
||||||
description = "Socket.IO server"
|
|
||||||
name = "python-socketio"
|
|
||||||
optional = false
|
|
||||||
python-versions = "*"
|
|
||||||
version = "4.4.0"
|
|
||||||
|
|
||||||
[package.dependencies]
|
|
||||||
python-engineio = ">=3.9.0"
|
|
||||||
six = ">=1.9.0"
|
|
||||||
|
|
||||||
[package.extras]
|
|
||||||
asyncio_client = ["aiohttp (>=3.4)", "websockets (>=7.0)"]
|
|
||||||
client = ["requests (>=2.21.0)", "websocket-client (>=0.54.0)"]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "main"
|
|
||||||
description = "Python 2 and 3 compatibility utilities"
|
|
||||||
name = "six"
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=2.6, !=3.0.*, !=3.1.*"
|
|
||||||
version = "1.13.0"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "main"
|
|
||||||
description = "The comprehensive WSGI web application library."
|
|
||||||
name = "werkzeug"
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
|
||||||
version = "0.16.0"
|
|
||||||
|
|
||||||
[package.extras]
|
|
||||||
dev = ["pytest", "coverage", "tox", "sphinx", "pallets-sphinx-themes", "sphinx-issues"]
|
|
||||||
termcolor = ["termcolor"]
|
|
||||||
watchdog = ["watchdog"]
|
|
||||||
|
|
||||||
[metadata]
|
|
||||||
content-hash = "37516445f8e0fb70eead3e64133d40d41ba04634c586c2020232d5eaebe6f075"
|
|
||||||
python-versions = "^3.6"
|
|
||||||
|
|
||||||
[metadata.files]
|
|
||||||
click = [
|
|
||||||
{file = "Click-7.0-py2.py3-none-any.whl", hash = "sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13"},
|
|
||||||
{file = "Click-7.0.tar.gz", hash = "sha256:5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7"},
|
|
||||||
]
|
|
||||||
dnspython = [
|
|
||||||
{file = "dnspython-1.16.0-py2.py3-none-any.whl", hash = "sha256:f69c21288a962f4da86e56c4905b49d11aba7938d3d740e80d9e366ee4f1632d"},
|
|
||||||
{file = "dnspython-1.16.0.zip", hash = "sha256:36c5e8e38d4369a08b6780b7f27d790a292b2b08eea01607865bf0936c558e01"},
|
|
||||||
]
|
|
||||||
eventlet = [
|
|
||||||
{file = "eventlet-0.25.1-py2.py3-none-any.whl", hash = "sha256:658b1cd80937adc1a4860de2841e0528f64e2ca672885c4e00fc0e2217bde6b1"},
|
|
||||||
{file = "eventlet-0.25.1.tar.gz", hash = "sha256:6c9c625af48424c4680d89314dbe45a76cc990cf002489f9469ff214b044ffc1"},
|
|
||||||
]
|
|
||||||
flask = [
|
|
||||||
{file = "Flask-1.1.1-py2.py3-none-any.whl", hash = "sha256:45eb5a6fd193d6cf7e0cf5d8a5b31f83d5faae0293695626f539a823e93b13f6"},
|
|
||||||
{file = "Flask-1.1.1.tar.gz", hash = "sha256:13f9f196f330c7c2c5d7a5cf91af894110ca0215ac051b5844701f2bfd934d52"},
|
|
||||||
]
|
|
||||||
flask-socketio = [
|
|
||||||
{file = "Flask-SocketIO-4.2.1.tar.gz", hash = "sha256:2172dff1e42415ba480cee02c30c2fc833671ff326f1598ee3d69aa02cf768ec"},
|
|
||||||
{file = "Flask_SocketIO-4.2.1-py2.py3-none-any.whl", hash = "sha256:7ff5b2f5edde23e875a8b0abf868584e5706e11741557449bc5147df2cd78268"},
|
|
||||||
]
|
|
||||||
greenlet = [
|
|
||||||
{file = "greenlet-0.4.15-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:99a26afdb82ea83a265137a398f570402aa1f2b5dfb4ac3300c026931817b163"},
|
|
||||||
{file = "greenlet-0.4.15-cp27-cp27m-win32.whl", hash = "sha256:beeabe25c3b704f7d56b573f7d2ff88fc99f0138e43480cecdfcaa3b87fe4f87"},
|
|
||||||
{file = "greenlet-0.4.15-cp27-cp27m-win_amd64.whl", hash = "sha256:9854f612e1b59ec66804931df5add3b2d5ef0067748ea29dc60f0efdcda9a638"},
|
|
||||||
{file = "greenlet-0.4.15-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ac57fcdcfb0b73bb3203b58a14501abb7e5ff9ea5e2edfa06bb03035f0cff248"},
|
|
||||||
{file = "greenlet-0.4.15-cp33-cp33m-win32.whl", hash = "sha256:d634a7ea1fc3380ff96f9e44d8d22f38418c1c381d5fac680b272d7d90883720"},
|
|
||||||
{file = "greenlet-0.4.15-cp33-cp33m-win_amd64.whl", hash = "sha256:0d48200bc50cbf498716712129eef819b1729339e34c3ae71656964dac907c28"},
|
|
||||||
{file = "greenlet-0.4.15-cp34-cp34m-manylinux1_x86_64.whl", hash = "sha256:bcb530089ff24f6458a81ac3fa699e8c00194208a724b644ecc68422e1111939"},
|
|
||||||
{file = "greenlet-0.4.15-cp34-cp34m-win32.whl", hash = "sha256:8b4572c334593d449113f9dc8d19b93b7b271bdbe90ba7509eb178923327b625"},
|
|
||||||
{file = "greenlet-0.4.15-cp34-cp34m-win_amd64.whl", hash = "sha256:a9f145660588187ff835c55a7d2ddf6abfc570c2651c276d3d4be8a2766db490"},
|
|
||||||
{file = "greenlet-0.4.15-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:51503524dd6f152ab4ad1fbd168fc6c30b5795e8c70be4410a64940b3abb55c0"},
|
|
||||||
{file = "greenlet-0.4.15-cp35-cp35m-win32.whl", hash = "sha256:a19bf883b3384957e4a4a13e6bd1ae3d85ae87f4beb5957e35b0be287f12f4e4"},
|
|
||||||
{file = "greenlet-0.4.15-cp35-cp35m-win_amd64.whl", hash = "sha256:853da4f9563d982e4121fed8c92eea1a4594a2299037b3034c3c898cb8e933d6"},
|
|
||||||
{file = "greenlet-0.4.15-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:23d12eacffa9d0f290c0fe0c4e81ba6d5f3a5b7ac3c30a5eaf0126bf4deda5c8"},
|
|
||||||
{file = "greenlet-0.4.15-cp36-cp36m-win32.whl", hash = "sha256:000546ad01e6389e98626c1367be58efa613fa82a1be98b0c6fc24b563acc6d0"},
|
|
||||||
{file = "greenlet-0.4.15-cp36-cp36m-win_amd64.whl", hash = "sha256:d97b0661e1aead761f0ded3b769044bb00ed5d33e1ec865e891a8b128bf7c656"},
|
|
||||||
{file = "greenlet-0.4.15-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:8041e2de00e745c0e05a502d6e6db310db7faa7c979b3a5877123548a4c0b214"},
|
|
||||||
{file = "greenlet-0.4.15-cp37-cp37m-win32.whl", hash = "sha256:81fcd96a275209ef117e9ec91f75c731fa18dcfd9ffaa1c0adbdaa3616a86043"},
|
|
||||||
{file = "greenlet-0.4.15-cp37-cp37m-win_amd64.whl", hash = "sha256:37c9ba82bd82eb6a23c2e5acc03055c0e45697253b2393c9a50cef76a3985304"},
|
|
||||||
{file = "greenlet-0.4.15.tar.gz", hash = "sha256:9416443e219356e3c31f1f918a91badf2e37acf297e2fa13d24d1cc2380f8fbc"},
|
|
||||||
]
|
|
||||||
gunicorn = [
|
|
||||||
{file = "gunicorn-20.0.4-py2.py3-none-any.whl", hash = "sha256:cd4a810dd51bf497552cf3f863b575dabd73d6ad6a91075b65936b151cbf4f9c"},
|
|
||||||
{file = "gunicorn-20.0.4.tar.gz", hash = "sha256:1904bb2b8a43658807108d59c3f3d56c2b6121a701161de0ddf9ad140073c626"},
|
|
||||||
]
|
|
||||||
itsdangerous = [
|
|
||||||
{file = "itsdangerous-1.1.0-py2.py3-none-any.whl", hash = "sha256:b12271b2047cb23eeb98c8b5622e2e5c5e9abd9784a153e9d8ef9cb4dd09d749"},
|
|
||||||
{file = "itsdangerous-1.1.0.tar.gz", hash = "sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19"},
|
|
||||||
]
|
|
||||||
jinja2 = [
|
|
||||||
{file = "Jinja2-2.10.3-py2.py3-none-any.whl", hash = "sha256:74320bb91f31270f9551d46522e33af46a80c3d619f4a4bf42b3164d30b5911f"},
|
|
||||||
{file = "Jinja2-2.10.3.tar.gz", hash = "sha256:9fe95f19286cfefaa917656583d020be14e7859c6b0252588391e47db34527de"},
|
|
||||||
]
|
|
||||||
markupsafe = [
|
|
||||||
{file = "MarkupSafe-1.1.1-cp27-cp27m-macosx_10_6_intel.whl", hash = "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161"},
|
|
||||||
{file = "MarkupSafe-1.1.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7"},
|
|
||||||
{file = "MarkupSafe-1.1.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183"},
|
|
||||||
{file = "MarkupSafe-1.1.1-cp27-cp27m-win32.whl", hash = "sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b"},
|
|
||||||
{file = "MarkupSafe-1.1.1-cp27-cp27m-win_amd64.whl", hash = "sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e"},
|
|
||||||
{file = "MarkupSafe-1.1.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f"},
|
|
||||||
{file = "MarkupSafe-1.1.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1"},
|
|
||||||
{file = "MarkupSafe-1.1.1-cp34-cp34m-macosx_10_6_intel.whl", hash = "sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5"},
|
|
||||||
{file = "MarkupSafe-1.1.1-cp34-cp34m-manylinux1_i686.whl", hash = "sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1"},
|
|
||||||
{file = "MarkupSafe-1.1.1-cp34-cp34m-manylinux1_x86_64.whl", hash = "sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735"},
|
|
||||||
{file = "MarkupSafe-1.1.1-cp34-cp34m-win32.whl", hash = "sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21"},
|
|
||||||
{file = "MarkupSafe-1.1.1-cp34-cp34m-win_amd64.whl", hash = "sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235"},
|
|
||||||
{file = "MarkupSafe-1.1.1-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b"},
|
|
||||||
{file = "MarkupSafe-1.1.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f"},
|
|
||||||
{file = "MarkupSafe-1.1.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905"},
|
|
||||||
{file = "MarkupSafe-1.1.1-cp35-cp35m-win32.whl", hash = "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1"},
|
|
||||||
{file = "MarkupSafe-1.1.1-cp35-cp35m-win_amd64.whl", hash = "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d"},
|
|
||||||
{file = "MarkupSafe-1.1.1-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff"},
|
|
||||||
{file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473"},
|
|
||||||
{file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e"},
|
|
||||||
{file = "MarkupSafe-1.1.1-cp36-cp36m-win32.whl", hash = "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66"},
|
|
||||||
{file = "MarkupSafe-1.1.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5"},
|
|
||||||
{file = "MarkupSafe-1.1.1-cp37-cp37m-macosx_10_6_intel.whl", hash = "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d"},
|
|
||||||
{file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e"},
|
|
||||||
{file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6"},
|
|
||||||
{file = "MarkupSafe-1.1.1-cp37-cp37m-win32.whl", hash = "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2"},
|
|
||||||
{file = "MarkupSafe-1.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c"},
|
|
||||||
{file = "MarkupSafe-1.1.1.tar.gz", hash = "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b"},
|
|
||||||
]
|
|
||||||
monotonic = [
|
|
||||||
{file = "monotonic-1.5-py2.py3-none-any.whl", hash = "sha256:552a91f381532e33cbd07c6a2655a21908088962bb8fa7239ecbcc6ad1140cc7"},
|
|
||||||
{file = "monotonic-1.5.tar.gz", hash = "sha256:23953d55076df038541e648a53676fb24980f7a1be290cdda21300b3bc21dfb0"},
|
|
||||||
]
|
|
||||||
python-engineio = [
|
|
||||||
{file = "python-engineio-3.11.2.tar.gz", hash = "sha256:47ae4a9b3b4f2e8a68929f37a518338838e119f24c9a9121af92c49f8bea55c3"},
|
|
||||||
{file = "python_engineio-3.11.2-py2.py3-none-any.whl", hash = "sha256:c3a3822deb51fdf9c7fe4d78abf807c73b83ea538036a50862d3024450746253"},
|
|
||||||
]
|
|
||||||
python-mpd2 = [
|
|
||||||
{file = "python-mpd2-1.0.0.tar.bz2", hash = "sha256:772fa6861273bb9f363a97987c2c45ca3965eb770570f1f02566efec9c89fc5f"},
|
|
||||||
{file = "python_mpd2-1.0.0-py2.py3-none-any.whl", hash = "sha256:29119e3a88ef4a6f15acb1b83bab9344fba8eefc370e0144ffb77f5138e65dd7"},
|
|
||||||
]
|
|
||||||
python-socketio = [
|
|
||||||
{file = "python-socketio-4.4.0.tar.gz", hash = "sha256:48cba5b827ac665dbf923a4f5ec590812aed5299a831fc43576a9af346272534"},
|
|
||||||
{file = "python_socketio-4.4.0-py2.py3-none-any.whl", hash = "sha256:af6c23c35497960f82106e36688123ecb52ad5a77d0ca27954ff3811c4d9d562"},
|
|
||||||
]
|
|
||||||
six = [
|
|
||||||
{file = "six-1.13.0-py2.py3-none-any.whl", hash = "sha256:1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd"},
|
|
||||||
{file = "six-1.13.0.tar.gz", hash = "sha256:30f610279e8b2578cab6db20741130331735c781b56053c59c4076da27f06b66"},
|
|
||||||
]
|
|
||||||
werkzeug = [
|
|
||||||
{file = "Werkzeug-0.16.0-py2.py3-none-any.whl", hash = "sha256:e5f4a1f98b52b18a93da705a7458e55afb26f32bff83ff5d19189f92462d65c4"},
|
|
||||||
{file = "Werkzeug-0.16.0.tar.gz", hash = "sha256:7280924747b5733b246fe23972186c6b348f9ae29724135a6dfc1e53cea433e7"},
|
|
||||||
]
|
|
|
@ -1,19 +0,0 @@
|
||||||
[tool.poetry]
|
|
||||||
name = "cammiechat"
|
|
||||||
version = "0.1.0"
|
|
||||||
description = ""
|
|
||||||
authors = ["Midgard <midgard@zeus.ugent.be>", "Robbe <robbevanherck@zeus.ugent.be>"]
|
|
||||||
|
|
||||||
[tool.poetry.dependencies]
|
|
||||||
python = "^3.6"
|
|
||||||
gunicorn = "^20.0.4"
|
|
||||||
flask = "^1.1.1"
|
|
||||||
python-mpd2 = "^1.0.0"
|
|
||||||
flask-socketio = "^4.2.1"
|
|
||||||
eventlet = "^0.25.1"
|
|
||||||
|
|
||||||
[tool.poetry.dev-dependencies]
|
|
||||||
|
|
||||||
[build-system]
|
|
||||||
requires = ["poetry>=0.12"]
|
|
||||||
build-backend = "poetry.masonry.api"
|
|
10
pyserial.py
10
pyserial.py
|
@ -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()
|
|
|
@ -1,3 +0,0 @@
|
||||||
flask
|
|
||||||
requests
|
|
||||||
flask_socketio
|
|
|
@ -2,4 +2,5 @@
|
||||||
|
|
||||||
killall gunicorn
|
killall gunicorn
|
||||||
./run.sh & disown
|
./run.sh & disown
|
||||||
|
sleep 1
|
||||||
|
DISPLAY=:0 xdotool key F5
|
||||||
|
|
6
run.py
6
run.py
|
@ -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)
|
|
6
run.sh
Executable file
6
run.sh
Executable file
|
@ -0,0 +1,6 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
cd "$(dirname "$0")"
|
||||||
|
pipenv install
|
||||||
|
export FLASK_APP=chat.py
|
||||||
|
exec pipenv run gunicorn -w 1 -b0.0.0.0:5000 chat:app
|
|
@ -37,17 +37,31 @@
|
||||||
.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><!--
|
--><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><!--
|
||||||
--><span class="msg">{{ m.msg }}</span><!--
|
--><span class="msg">{{ m.msg }}</span><!--
|
||||||
--></div>
|
--></div>
|
||||||
|
|
Loading…
Reference in a new issue