Commit df8173a9 authored by Michael Aschauer's avatar Michael Aschauer
Browse files

initial full but unpolished version

parents
tmp
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
FROM node:16-alpine AS builder
WORKDIR /usr/src/frontend
COPY ./frontend/package*json ./
RUN npm install
COPY ./frontend/ ./
RUN npm run build
FROM node:16-alpine
WORKDIR /usr/src/server
COPY --from=builder /usr/src/frontend/dist/ /usr/src/server/public/
COPY ./backend/package*json .
RUN npm install
COPY ./backend/ .
EXPOSE 3000
CMD [ "npm", "run", "start"]
This diff is collapsed.
# a.space
An experimental, spatialized multi audio stream interface for [AMRO22 - Art Meets Radical Openness](https://radical-openness.org/en)
Frontend in [Vue.js](https://vuejs.org/),
with a Nodes.js/express/socket.io server backend for realtime chat and audience position sharing
written by [Michael Aschauer](https://m.ash.to/)
## License
Copyright (c) 2022, Michael Aschauer
a.space is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along with this program. If not, see https://www.gnu.org/licenses/.
## Project setup
see reference build and deployment via docker/podman
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
aspace.backface.io {
reverse_proxy backend:3000
}
{
"name": "server",
"version": "1.0.0",
"description": "a.space socket server",
"main": "server.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node server.js",
"startdev": "nodemon --inspect server.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"autolinker": "^3.15.0",
"body-parser": "^1.20.0",
"cors": "^2.8.5",
"dotenv": "^16.0.0",
"express": "^4.18.1",
"express-session": "^1.17.2",
"http": "^0.0.1-security",
"locutus": "^2.0.16",
"morgan": "^1.10.0",
"nodemon": "^2.0.16",
"path": "^0.12.7",
"randomcolor": "^0.6.2",
"socket.io": "^4.5.0",
"uuid-random": "^1.3.2"
}
}
This diff is collapsed.
const http = require("http");
const express = require("express");
const morgan = require("morgan");
const bodyParser = require("body-parser");
const cors = require("cors");
const path = require("path");
const env = require("dotenv").config();
const randomColor = require('randomcolor');
const strip_tags = require('locutus/php/strings/strip_tags')
const uuid = require("uuid-random");
// purge messages older than (in milliseconds)
const forget_time = 60 * 60 * 1000
// frontend location for debugging
const frontEndLoc = path.join(__dirname, "..", "frontend", "dist");
let users = {}
let messages = []
const deleteOldMessages = function(messages) {
while (messages.length > 0 && new Date() - messages[0].date > forget_time) {
messages.shift()
}
}
// setup express app
const app = express()
app.use(cors());
app.use(morgan("dev"));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static("./public"));
app.use(express.static(frontEndLoc));
// start server
const server = http.createServer(app)
server.listen(process.env.PORT || 3000);
// setup sockets
const io = require("socket.io")(server, {
cors: {
origin: "*",
},
path: "/ws/"
});
io.on("connection", socket => {
console.log('connect #' + socket.id + " from " + socket.client.conn.remoteAddress);
deleteOldMessages(messages)
io.to(socket.id).emit("your-id", { id: socket.id })
io.to(socket.id).emit("history", { users, messages })
socket.on("join", function(user_data) {
users[socket.id] = user_data
users[socket.id].id = socket.id
users[socket.id].color = randomColor({ luminosity: 'bright' })
users[socket.id].datetime = new Date()
socket.broadcast.emit("joined", users[socket.id])
});
socket.on("message", function(msg_data) {
msg_data.user_id = socket.id
msg_data.id = uuid()
msg_data.msg = strip_tags(msg_data.msg)
msg_data.color = users[socket.id].color
msg_data.date = new Date()
messages.push(msg_data)
io.emit("message", msg_data)
deleteOldMessages(messages)
});
socket.on("moved", function(user_data) {
users[socket.id] = user_data
socket.broadcast.emit("moved", user_data);
});
socket.on("disconnect", function(user_data) {
console.log("disconnect #" + socket.id);
socket.broadcast.emit("left", users[socket.id]);
delete users[socket.id]
});
});
version: "3.7"
services:
backend:
image: backface/aspace
build:
context: ./
dockerfile: Dockerfile
command:
npm run start
caddy:
image: caddy:latest
ports:
- 80:80
- 443:443
volumes:
- ./backend/Caddyfile:/etc/caddy/Caddyfile:ro
node_modules
npm-debug.log
tmp
*.mp3
*local.json
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
{
"recommendations": ["johnsoncodehk.volar"]
}
# Vue 3 + Vite
This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
## Recommended IDE Setup
- [VS Code](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=johnsoncodehk.volar)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>a.space</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>
{
"name": "a.space",
"private": true,
"version": "0.0.0",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview",
"deploy": "vite build; rsync -avzL dist/* man:www/aspace.backface.io"
},
"dependencies": {
"autolinker": "^3.15.0",
"custom-vue-scrollbar": "^0.0.7",
"d3": "^7.4.4",
"d3-force": "^3.0.0",
"fit-svg-text": "^0.1.2",
"locutus": "^2.0.16",
"randomcolor": "^0.6.2",
"resonance-audio": "^1.0.0",
"socket.io-client": "^4.5.0",
"tone": "^14.7.77",
"vue": "^3.2.25",
"vue-feather-icons": "^5.1.0"
},
"devDependencies": {
"@vitejs/plugin-vue": "^2.3.1",
"autoprefixer": "^10.4.7",
"postcss": "^8.4.13",
"tailwindcss": "^3.0.24",
"vite": "^2.9.5",
"web-audio-peak-meter": "^2.1.0"
}
}
This diff is collapsed.
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
{
"streams": [
{
"id": 1,
"src": "https://cba.fro.at/wp-content/uploads/lachansonfreequenns/siegbert-schwab-la-chanson-2020.11.14_preview.mp3",
"title":"La Choix est le dilemme",
"color": "red"
},
{
"id": 2,
"src": "https://cba.fro.at/wp-content/uploads/kulturbildungspezial/kundbpezial-20200717_preview.mp3",
"title": "Greenwashing & Extinction Rebellion",
"color": "green"
},
{
"id": 3,
"src": "http://amp1.cesnet.cz:8000/cro-jazz-256.ogg",
"title": "CRo Jazz",
"color": "blue"
}
]
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment