Skip to content

Instantly share code, notes, and snippets.

@sneha-belkhale
Last active November 25, 2023 19:54
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sneha-belkhale/e7a1fe52e33b5c98f1ea2081a3b4ed8a to your computer and use it in GitHub Desktop.
Save sneha-belkhale/e7a1fe52e33b5c98f1ea2081a3b4ed8a to your computer and use it in GitHub Desktop.
Local Network Chat -- (python server + frontend + linux daemon Init Script for the server )
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
body {
display: flex;
justify-content: center;
align-items: center;
margin: 0px;
background-color: black;
width: 100%;
height: 100vh;
color: white;
font-family: monospace
}
.center {
display: flex;
flex-direction: column;
margin: auto;
width: 60%;
height: 100%;
position: relative;
margin: 20px 0 20px 0;
}
.input-container {
display: flex;
flex-direction: row;
justify-content: space-between;
width: 100%;
height: 30px;
z-index: 10;
margin-bottom: 20px;
}
.message-input {
width: 100%;
border: 2px solid white;
background-color: #ff00b1;
color: white;
font-family: monospace
}
.name-input {
width: 120px;
border: 2px solid white;
background-color: #ff00b1;
color: white;
font-family: monospace;
}
::placeholder {
color: white;
font-family: monospace;
}
.message-area {
position: relative;
display: flex;
height: 100%;
flex-direction: column;
justify-content: flex-end;
margin-bottom: 30px;
}
.date {
background-color: blue;
}
.message {
display: grid;
grid-template-columns: 100px 120px auto;
gap: 15px;
margin-bottom: 5px;
}
.name {
width: 80px;
width: 100%;
text-align: right;
overflow: hidden;
word-wrap: break-word;
}
#green {
color: #00ff5c;
}
#blue {
color: blue;
}
#magenta {
color: magenta;
}
#teal {
color: #00dcff;
}
#yellow {
color: #f0ff00;
}
#sendButton {
cursor: pointer;
height: 100%;
border: 2px solid white;
background-color: blueviolet;
color: white;
font-family: monospace;
}
@media only screen and (max-width: 600px) {
.center {
width: 100%;
}
}
</style>
</head>
<body>
<div class="center">
<div class="message-area">
</div>
<div class="input-container">
<input class="name-input" placeholder="Alias" />
<input class="message-input" placeholder="Symbols" />
<button id="sendButton">Send</button>
</div>
</div>
<script>;
const apiUrl = 'http://192.168.8.1:8989';
// const apiUrl = '/';
const messageArea = document.querySelector(".message-area");
const nameColorList = ["yellow", "magenta", "green", "teal", "yellow", "blue"]
let sentSecretKey = false;
const newMessageEl = (message) => {
const messageEl = document.createElement("div");
const d = new Date(message.date);
let [month, date, year] = d.toLocaleDateString().split("/")
let [hour, minute, second] = d.toLocaleTimeString().split(/:| /)
let charSum = 0;
for (let i = 0; i < message.name.length; i++) {
let c = message.name.charCodeAt(i);
charSum += c;
}
let color = nameColorList[charSum % nameColorList.length];
messageEl.innerHTML = `
<div class="message">
<div class="date">[${hour}:${minute}:${second}]</div>
<div id=${color} class="name">${message.name}:</div>
<div class="text">${message.text}</div>
</div>
`;
return messageEl;
}
const fetchMessages = async () => {
try {
const res = await fetch(apiUrl)
const messages = await res.json();
messageArea.innerHTML = '';
messages.forEach(message => {
const msgEl = newMessageEl(message)
messageArea.appendChild(msgEl);
});
} catch (error) {
console.log('Error fetching messages', error)
}
}
fetchMessages();
setInterval(() => {
fetchMessages()
}, 3000)
const sendBtn = document.querySelector('#sendButton');
sendBtn.addEventListener('click', async () => {
const nameEl = document.querySelector('.name-input')
const msgEl = document.querySelector('.message-input')
if (nameEl.value.length < 1 || msgEl.value.length < 1) {
return
}
const payload = {
name: nameEl.value,
text: msgEl.value
};
try {
const res = await fetch(apiUrl, {
method: 'post',
body: JSON.stringify(payload)
});
const body = await res.json();
if (res.ok) {
// Add message to UI
const msgEl = newMessageEl(body)
messageArea.appendChild(msgEl);
if (!sentSecretKey) {
const secretMsgEl = newMessageEl({ "name": "YOUR KEY", "text": "fvxyaZ9ix95ZaLuWn7XqcbRW5", "date": "2012-01-26T00:00:00.417-07:00" })
messageArea.appendChild(secretMsgEl);
sentSecretKey = true;
}
} else {
// TODO: Display that error in the UI
console.log(body.message)
}
} catch (error) {
console.log('Error posting message.', error)
}
})
</script>
</body>
</html>
#!/usr/bin/env python2
from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
import SocketServer
import logging
import json
import datetime
PORT = 8989
db = '/root/data.json'
class GetHandler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header('Content-type', 'application/json')
self.send_header('Access-Control-Allow-Origin', '*')
self.send_header('Access-Control-Allow-Methods', 'GET')
self.end_headers()
with open(db) as json_file:
data = json.load(json_file)
self.wfile.write(json.dumps(data))
def do_POST(self):
self.send_response(200)
self.send_header('Content-type', 'application/json')
self.send_header('Access-Control-Allow-Origin', '*')
self.send_header('Access-Control-Allow-Methods', 'POST')
self.end_headers()
content_len = int(self.headers.getheader('content-length', 0))
post_body = self.rfile.read(content_len)
post_data = json.loads(post_body)
try:
name = post_data["name"]
text = post_data["text"]
except:
return
data = 0
with open(db) as json_file:
data = json.load(json_file)
entry = {'name': name, 'text': text, 'date': datetime.datetime.now().strftime("%m/%d/%Y, %H:%M:%S")}
data.append(entry)
with open(db, 'w') as outfile:
json.dump(data, outfile, indent=4)
self.wfile.write(json.dumps(entry))
# override the log message function, because it crashes headless OpenWRT since there is no output stream?
def log_message(self, format, *args):
return
Handler = GetHandler
httpd = SocketServer.TCPServer(("", PORT), Handler)
httpd.serve_forever()
#!/bin/sh /etc/rc.common
START=98
STOP=98
start() {
# commands to launch application
echo "starting chat server"
# run in the background because init.d scripts seem to be blocking
# sleep 20 seconds, because it seems whatever python servers need to initialize is not ready on boot
(sleep 20; python /root/server.py)&
}
stop() {
# commands to kill application
echo stop
killall python
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment